"""Run a subprocess and communicate with it via stdin, stdout, and stderr.
Requires that platform supports, eg, posix-style 'os.pipe' and 'os.fork'
"""Run a subprocess and communicate with it via stdin, stdout, and stderr.
Requires that platform supports, eg, posix-style 'os.pipe' and 'os.fork'
# Originally by ken manheimer, ken.manheimer@nist.gov, jan 1995.
# Prior art: Initially based python code examples demonstrating usage of pipes
# Originally by ken manheimer, ken.manheimer@nist.gov, jan 1995.
# Prior art: Initially based python code examples demonstrating usage of pipes
import sys, os, string, time, types
import select
import signal
import sys, os, string, time, types
import select
import signal
# You may need to increase execvp_grace_seconds, if you have a large or slow
# path to search:
execvp_grace_seconds = 0.5
# You may need to increase execvp_grace_seconds, if you have a large or slow
# path to search:
execvp_grace_seconds = 0.5
if self.control_stderr:
os.dup2(parentErr, 2) # Reconnect to parent's stdout
sys.stderr.write("**execvp failed, '%s'**\n" %
if self.control_stderr:
os.dup2(parentErr, 2) # Reconnect to parent's stdout
sys.stderr.write("**execvp failed, '%s'**\n" %
time.sleep(execvp_grace_seconds)
try:
pid, err = os.waitpid(self.pid, os.WNOHANG)
time.sleep(execvp_grace_seconds)
try:
pid, err = os.waitpid(self.pid, os.WNOHANG)
raise SubprocessError(
"child exited with return code %d" % rc)
# Child may have exited, but not in error, so we won't say
raise SubprocessError(
"child exited with return code %d" % rc)
# Child may have exited, but not in error, so we won't say
def readPendingChars(self, max=None):
"""Read all currently pending subprocess output as a single string."""
return self.readbuf.readPendingChars(max)
def readPendingChars(self, max=None):
"""Read all currently pending subprocess output as a single string."""
return self.readbuf.readPendingChars(max)
(sig[0], self.pid, self.cmd,
hex(id(self))[2:])))
for i in self.pipefiles:
(sig[0], self.pid, self.cmd,
hex(id(self))[2:])))
for i in self.pipefiles:
self.pid = 0
return None # ===>
time.sleep(.1)
# Only got here if subprocess is not gone:
raise SubprocessError(
"Failed kill of subproc %d, '%s', with signals %s" %
self.pid = 0
return None # ===>
time.sleep(.1)
# Only got here if subprocess is not gone:
raise SubprocessError(
"Failed kill of subproc %d, '%s', with signals %s" %
- (self.pid, self.cmd, map(lambda(x): x[0], sigs)))
+ (self.pid, self.cmd, map(lambda x: x[0], sigs)))
- 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 (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
sel = select.select([self.fd], [], [self.fd], 0)
if sel[2]:
sel = select.select([self.fd], [], [self.fd], 0)
if sel[2]:
line = string.splitfields(line, ':')
it[string.strip(line[0])] = (
string.strip(string.join(line[1:])))
line = string.splitfields(line, ':')
it[string.strip(line[0])] = (
string.strip(string.join(line[1:])))
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 bogus subprocess, should fail:")
try:
b = Subprocess('/', 1)
print("\tOops! Null-named subprocess startup *succeeded*?!?")
except SubprocessError:
print("\t...yep, it failed.")
print('\tWrite, then read, two newline-teriminated lines, using readline:')
p.write('first full line written\n'); p.write('second.\n')
print('\tWrite, then read, two newline-teriminated lines, using readline:')
p.write('first full line written\n'); p.write('second.\n')
print('\tThree lines, last sans newline, read using combination:')
p.write('first\n'); p.write('second\n'); p.write('third, (no cr)')
print('\tFirst line via readline:')
print('\tThree lines, last sans newline, read using combination:')
p.write('first\n'); p.write('second\n'); p.write('third, (no cr)')
print('\tFirst line via readline:')
print('\tRest via readPendingChars:')
print(p.readPendingChars())
print("\tStopping then continuing subprocess (verbose):")
print('\tRest via readPendingChars:')
print(p.readPendingChars())
print("\tStopping then continuing subprocess (verbose):")