[Python-Dev] popen2.py strangeness

Sjoerd Mullender sjoerd@acm.org
Mon, 02 Jun 2003 17:18:57 +0200


I can't currently report this as a bug on SourceForge (down for
maintenance), so in the mean time we can discuss this here...

I just noticed the following behavior (current CVS):

+ python
Python 2.3b1+ (#37, Jun  2 2003, 11:34:36)
[GCC 3.2 20020903 (Red Hat Linux 8.0 3.2-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import popen2
>>> a = popen2.Popen3('sleep 1', 1, -1)
>>> # wait more than one second to give the process time to exit
...
>>> b = popen2.Popen3('sleep 1', 1, -1)
>>> a.wait()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/ufs/sjoerd/src/python/Lib/popen2.py", line 86, in wait
    pid, sts = os.waitpid(self.pid, 0)
OSError: [Errno 10] No child processes
>>>

I would expect the a.wait() to return the exit status (or None) of the
first "sleep 1" command, but instead I get a traceback.

The reason is clear: in popen2.Popen3.__init__ the very first thing that
happens is a call to _cleanup() which does a poll() call on all active
instances.  If the process has died, the os.waitpid() call that poll()
does removes it from the OS's process table, so that a next os.waitpid()
on the same process id will fail.

I understand why the call to _cleanup() happens: defunct processes need
to be cleaned up, and if you only ever use the popen[234] factory
functions, the library needs to call os.waitpid for the created
processes.

However, it seems to me the above sequence of events is legitimate and
should be supported.  The question is: how?

-- Sjoerd Mullender <sjoerd@acm.org>