popen2.Popen3 process destruction

brianc at temple.edu brianc at temple.edu
Tue Jun 15 16:25:02 CEST 2004


This could possibly be a bug, but I don't understand it fully
so I'm posting here first. Searching the list told me other
people are having this problem too.

I have created a class which inherits popen2.Popen3. 

The problem is that popen2.Popen3 does not define a __del__
method to handle proper closing of the pipes or destruction of
the process. So I created one in my class:

   def __del__(self):
      self.tochild.close()
      self.fromchild.close()
      if self.childerr:
         self.childerr.close()
      try:
         os.kill(self.pid,15)#SIGTERM - ASK NICELY
      except OSError:
         os.kill(self.pid,9)#SIGKILL - BE RELENTLESS

However, since the popen2 module stores a reference to the
object in popen2._active this __del__ method is never called
to clean things up. _cleanup() called in Popen3.__init__()
fails to clean up the process in subsequent instantiations.
This eventually leads to an "OSError: [Errno 24] Too many open
files"

"_clean()" fails because the program being called is
interactive using stdin/stdout. Much in the way "cat" is. In
fact the unit test provided with the popen2 module _test()
uses "cat" and hangs for the very same reason. It hangs on
"for inst in _active[:]:inst.wait()" This is why I created my
own class, to handle this special interactive nature.

The only workaround I currently see is ripping all but the
"_active.append(self)" from the popen2.Popen3.__init__() code
and putting it in my __init__. Currently I just call it
directly as prescribed by the python reference manual. 

Perhaps I'm missing the epiphany of why _active and _cleanup()
are needed and not a __del__() method. 

Thanks,
-Brian

System info:
IRIX64 6.5
Python 2.2.3




More information about the Python-list mailing list