Re: curses suite of modules

Guido.van.Rossum@cwi.nl
Tue, 13 Sep 1994 19:47:02 +0200

> First of all, thanks much to lance for producing the packages...

I second that!

> In order to build the dynamic-load module on SunOS 4.1.3, i need to do
> a few things differently than the way that is prescribed in the
> Setup.curses delivered with the packages. I'm wondering whether other
> people have seen the same behaviors.
>
> I need to use the System V compatability packages to do compile and
> load it, and use the termcap library in addition to the curses
> library. Ie, i need to compile with "-I/usr/5include", and load with
> "-L/usr/5lib -lcurses -ltermcap". Have other people had the same
> experience? If so, it would probably make sense to somehow
> incorporate the information in the distribution.

Well, since SunOS 4.1.3 is still one of the most used systems, that's
probably a good idea, but in general I think you can't expect packages
like this to document how to build them on every type of system. For
Python as a whole, the configure script finds most of these system
dependencies, but arbitrary new modules can require arbitrary new
hoops you will have to jump through... I'm sure the SunOS curses
documents explains how to compile and link curses applications?

> I'm unable to build the "panel" module at all - i don't see any
> panel.h include files on my system, or a libpanel.* in the regular or
> System V compatability libraries. Is the panel feature specific to
> some other OS? Or might the routines for it be available in my OS,
> but in a library with a different name?

I can't find them on SGI IRIX either, but I do see them on Solaris
2.x. I suppose it's a SVR4-ism.

> I've encountered two problems with the way the curses package behaves.
>
> The first is fairly straightforward - the .initscr() module method
> will, as documented, exit the parent program if it is invoked on a
> terminal that is not curses capable. If i understand correctly, the
> curses solution is to use the newscr() routine, which does not do the
> _exit if it is not successful. The problem is that screens are not
> yet implemented in the curses module, and i can't see a way to test
> for curses-capability without risking the initscr() method. ?

A really gross work-around would fork a child and call initscr() in
the child, and then immediately call endwin() and sys.exit(0). The
parent can then check the exit status of the child...

> Finally, i see a weird and troublesome behavior of nodelay-reads
> within curses. If i invoke the win.nodelay(1) method and then a
> win.getch(), python exits *and* the tty session exits! It looks like
> the tty gets set overall to nodelay, and immediately sees an EOF
> condition (if there is no prior input pending), all the way up the
> line. Does anyone else see this behavior, and does anyone have
> suggestions for preventing it??

In general, setting a file descriptor in non-blocking mode sets the
*device* in that mode, not the particular process or file descriptor.
Unfortunately most programs, including stdio, GNU readline and the
shell, don't distinguish between the error raised by a read on a
non-blocking device and a persistent error -- and in fact what could
they do? Repeating the read would cause them to spin the cpu until a
character is typed.

The only safe solution this is to only use this feature only inside a
function that switches it on and in a try-finally clause switches it
off again before returning.

(In general I would be wary of experimenting with curses in an
interactive Python session -- as soon as it sets the tty in cbreak
nocr mode weird things will happen to your output anyway, and only
because GNU readline uses a similar mode can you get away with a
little bit of this.)

--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl>
<URL:http://www.cwi.nl/cwi/people/Guido.van.Rossum.html>