"""Run a subprocess and communicate with it via stdin, stdout, and stderr.
-Requires that platform supports, eg, posix-style os.pipe and os.fork.
+Requires that platform supports, eg, posix-style 'os.pipe' and 'os.fork'
+routines.
Subprocess class features:
- provides detection of subprocess startup failure
- Subprocess objects have nice, informative string rep (as every good object
- ought).
+ ought)."""
- - RecordFile class provides record-oriented IO for file-like stream objects.
-"""
+__version__ = "Revision: 1.15 "
-__version__ = "Revision: 1.7 "
-
-# Id: subproc.py,v 1.7 1998
+# Id: subproc.py,v 1.15 1998/12/14 20:53:16 klm Exp
# Originally by ken manheimer, ken.manheimer@nist.gov, jan 1995.
# Prior art: Initially based python code examples demonstrating usage of pipes
"""Fork a subprocess with designated COMMAND (default, self.cmd)."""
if cmd: self.cmd = cmd
else: cmd = self.cmd
+ cmd = string.split(self.cmd)
pRc, cWp = os.pipe() # parent-read-child, child-write-parent
cRp, pWc = os.pipe() # child-read-parent, parent-write-child
pRe, cWe = os.pipe() # parent-read-error, child-write-error
try: os.close(i)
except os.error: pass
- self.run_cmd(cmd)
+ try:
+ os.execvp(cmd[0], cmd)
+ os._exit(1) # Shouldn't get here
+
+ except os.error, e:
+ if self.control_stderr:
+ os.dup2(parentErr, 2) # Reconnect to parent's stdout
+ sys.stderr.write("**execvp failed, '%s'**\n" %
+ str(e))
+ os._exit(1)
os._exit(1) # Shouldn't get here.
else: ### PARENT ###
# Child may have exited, but not in error, so we won't say
# anything more at this point.
- def run_cmd(self, cmd):
- cmd = string.split(self.cmd)
-
- try:
- os.execvp(cmd[0], cmd)
- os._exit(1) # Shouldn't get here
-
- except os.error, e:
- if self.control_stderr:
- os.dup2(parentErr, 2) # Reconnect to parent's stdout
- sys.stderr.write("**execvp failed, '%s'**\n" %
- str(e))
- os._exit(1)
-
-
### Write input to subprocess ###
def write(self, str):
return self.readPendingChars()
got = ''
while n:
- got0 = self.readPendingChars(n)
- got = got + got0
- n = n - len(got0)
+ got = got + self.readPendingChars(n)
+ n = n - len(got)
return got
def readPendingChars(self, max=None):
"""Read all currently pending subprocess output as a single string."""
status = self.status()
return '<Subprocess ' + status + ', at ' + hex(id(self))[2:] + '>'
-# The name of the class is a pun; it is short for "Process", but it also appeals
-# to the word "Procedure"
-class Subproc(Subprocess):
- def run_cmd(self, cmd):
- apply(cmd[0], cmd[1:])
- os._exit(1)
-
#############################################################################
##### Non-blocking read operations #####
#############################################################################
got = ""
if self.buf:
- got, self.buf = self.buf, ''
- return got # ===>
+ if (max > 0) and (len(self.buf) > max):
+ got = self.buf[0:max]
+ self.buf = self.buf[max:]
+ else:
+ got, self.buf = self.buf, ''
+ return got
if self.eof:
- return ''
+ return ''
sel = select.select([self.fd], [], [self.fd], 0)
if sel[2]: