Subject: python exiting w/curses and w/o a terminal; failure of try/except
To: None <netbsd-help@netbsd.org>
From: Greg Troxel <gdt@ir.bbn.com>
List: netbsd-help
Date: 01/18/2005 15:24:06
On NetBSD/i386 2.0ish, I have python23-pth and bittorrent installed:
Information for bittorrent-3.4.2nb1:
Requires:
py23pth-cursespanel-[0-9]*
python23-pth>=2.3.3nb2
I am using btdownloadheadless.py, which writes status to stdout, and
running it with '< /dev/null > LOGFILE 2.&1 &'.
My intent is to push new binary software distributions (./build.sh
release, plus packages and a tarball for non-pkgsrc stuff under
/usr/foo) around to a 20-node ad hoc wireless testbed, after doing a
build on the (wired) build machine.
If I start the downloader while logged in, it starts, and continues to
run in the background.
If I start the downloader by
ssh host23 /usr/foo/bin/torrent downloader
which then invokes btdownloadheadless.py as above, I get a failure
during initscr in curses. Note that running '/usr/foo/bin/torrent
downloader' as the same uid works fine from login window.
The failure output is:
Error opening terminal: unknown.
Here is the snippet of code that seems to be at fault:
----------------------------------------
def run(params):
try:
import curses
curses.initscr()
cols = curses.COLS
curses.endwin()
except:
cols = 80
h = HeadlessDisplayer()
----------------------------------------
I believe this should leave the try block on an error, and run the
except block. I put print statements before/after each statement, and
found that it was the initscr that failed:
13219 python2p3 CALL read(3,0x813bb90,8)
13219 python2p3 GIO fd 3 read 8 bytes
"\a\0\r\0
\0
\0"
13219 python2p3 RET read 8
13219 python2p3 CALL read(3,0xbfbfdb90,0xa)
13219 python2p3 RET read 0
13219 python2p3 CALL close(3)
13219 python2p3 RET close 0
13219 python2p3 CALL ioctl(2,TIOCGETA,0xbfbff470)
13219 python2p3 RET ioctl -1 errno 25 Inappropriate ioctl for device
13219 python2p3 CALL ioctl(2,TIOCGETA,0xbfbff430)
13219 python2p3 RET ioctl -1 errno 25 Inappropriate ioctl for device
13219 python2p3 CALL write(2,0xbfbfec40,0x21)
13219 python2p3 GIO fd 2 wrote 33 bytes
"Error opening terminal: unknown.
"
13219 python2p3 RET write 33/0x21
13219 python2p3 CALL write(1,0x8283000,0x2e)
13219 python2p3 GIO fd 1 wrote 46 bytes
"before try block
before import
before initscr
"
13219 python2p3 RET write 46/0x2e
13219 python2p3 CALL exit(1)
After commenting out the initscr call, I got this:
before try block
before import
before initscr
before assignment
before 80
after 80
after try block
and the download started. This indicates that cols = curses.COLS
failed and the except block was run.
Here is my modified code:
def run(params):
print 'before try block'
try:
print 'before import'
import curses
print 'before initscr'
#curses.initscr()
print 'before assignment'
cols = curses.COLS
print 'before endwin'
curses.endwin()
print 'after endwin'
except:
print 'before 80'
cols = 80
print 'after 80'
print 'after try block'
h = HeadlessDisplayer()
So, it seems that curses.initscr fails in a way that causes an exit,
rather than running the except block. Clearly something is buggy, but
the question is whether this is a bug in the bittorrent code, the
python interpreter, the python curses glue code, or libcurses. I
looked at python's curses code and libcurses, and didn't see anything
that would exit instead of just returning NULL, more or less.
I plan to patch my bt package to not try curses, but I'd be interested
to be enlightened.