+#! /usr/bin/env python
+
"""Run a subprocess and communicate with it via stdin, stdout, and stderr.
Requires that platform supports, eg, posix-style 'os.pipe' and 'os.fork'
#
# ken.manheimer@nist.gov
+# This is a modified version by Oleg Broytman <phd@phdru.name>.
+# The original version is still preserved at
+# https://www.python.org/ftp/python/contrib-09-Dec-1999/System/subproc.tar.gz
import sys, os, string, time, types
import select
import signal
-SubprocessError = 'SubprocessError'
+class SubprocessError(Exception):
+ pass
+
# You may need to increase execvp_grace_seconds, if you have a large or slow
# path to search:
execvp_grace_seconds = 0.5
except os.error as error:
errno, msg = error
if errno == 10:
+ self.pid = None
raise SubprocessError("Subprocess '%s' failed." % self.cmd)
+ self.pid = None
raise SubprocessError("Subprocess failed[%d]: %s" % (errno, msg))
if pid == self.pid:
# child exited already
"child killed by signal %d with a return code of %d"
% (sig, rc))
if rc:
+ self.pid = None
raise SubprocessError(
"child exited with return code %d" % rc)
# Child may have exited, but not in error, so we won't say
(sig[0], self.pid, self.cmd,
hex(id(self))[2:])))
for i in self.pipefiles:
- os.close(i)
+ try:
+ fp = os.fdopen(i).close()
+ except OSError:
+ pass
+ del self.pipefiles[:]
self.pid = 0
return None # ===>
time.sleep(.1)
#############################################################################
def test(p=0):
- print("\tOpening subprocess:")
- p = Subprocess('cat', 1) # set to expire noisily...
- print(p)
print("\tOpening bogus subprocess, should fail:")
try:
b = Subprocess('/', 1)
print("\tOops! Null-named subprocess startup *succeeded*?!?")
except SubprocessError:
print("\t...yep, it failed.")
+ print("\tOpening cat subprocess:")
+ p = Subprocess('cat', 1) # set to expire noisily...
+ print(p)
print('\tWrite, then read, two newline-teriminated lines, using readline:')
p.write('first full line written\n'); p.write('second.\n')
print(repr(p.readline()))
del p
print("\tDone.")
return None
+
+if __name__ == '__main__':
+ test()