[Tutor] Using popen

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Wed, 3 Apr 2002 12:25:28 -0800 (PST)


On Tue, 2 Apr 2002, Sheila King wrote:

> On Tue, 02 Apr 2002 22:53:07 -0800 (PST), Sean 'Shaleh' Perry wrote:
>
> > > Python 2.2 (#1, Feb 21 2002, 02:25:03)
> > > [GCC egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)] on linux2
> > > Type "help", "copyright", "credits" or "license" for more
> > > information.
> > > > > > import os p = os.popen('vauthenticate secret_test', 'w', 0)
> > > > > > p.write('secret')
> > > > > > p.close()
> > > 256
> > >
> > > Now, I don't really understand these pipes and popen as well as
> > > I'd like, so I may well be doing something really stupid here.
> > > But, I certainly did not expect to get an exit code of 256 with
> > > this particular ACCOUNTNAME/password pair, as it returns an exit
> > > code of zero at the command line (and I know these are correct

The reason for the wackiness is because the return value of os.popen()
actually contains more than the "errorcode" of the executed program.
os.popen() packs _two_ values into one integer, so here's a case where we
actually need to do some bit manipulation!


This bit packing is what the documentation is trying vaguely to imply when
they say something about "The exit status of the command (encoded in the
format specified for wait())".


Let's take a look at the wait() documentation:

"""
wait ()
Wait for completion of a child process, and return a tuple containing its
pid and exit status indication: a 16-bit number, whose low byte is the
signal number that killed the process, and whose high byte is the exit
status (if the signal number is zero); the high bit of the low byte is set
if a core file was produced. (Not on MS-DOS.)
"""



So the value that the close() returns is actually a combination of the
"exit status" that we're looking for, along with a "signal" number.  And
to get the true exit status, we'll want to grab the high byte.  One way to
do this is to just push the signal number part right off by using bitwise
right shifting:

###
>>> 256 >> 8
1
###

That is, just shift the number by 8 bits.  What's left is the return value
that we're looking for.  (By the way, this bit shift is equivalent to what
Sean was doing with the modulo 255 arithmetic.)


You're actually getting an exit code of 1, so your program may be
signalling an error of some sort.

Hope this helps!