X-Git-Url: https://git.phdru.name/?a=blobdiff_plain;f=subproc.py;h=502d5dd19190d6456128d89e40434386ea987713;hb=34b8d0278505311f33805a54bc758bc4b690c882;hp=a0099c290db088a168181802ee91153ac2b920c9;hpb=71900f3630cb51580964038b78100d60e3671981;p=bookmarks_db.git diff --git a/subproc.py b/subproc.py old mode 100644 new mode 100755 index a0099c2..502d5dd --- a/subproc.py +++ b/subproc.py @@ -1,3 +1,5 @@ +#! /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' @@ -16,7 +18,7 @@ Subprocess class features: __version__ = "Revision: 1.15 " -# Id: subproc.py,v 1.15 1998/12/14 20:53:16 klm Exp +# 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 @@ -40,13 +42,18 @@ __version__ = "Revision: 1.15 " # # ken.manheimer@nist.gov +# This is a modified version by Oleg Broytman . +# 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 @@ -115,7 +122,7 @@ class Subprocess: os.execvp(cmd[0], cmd) os._exit(1) # Shouldn't get here - except os.error, e: + except os.error as e: if self.control_stderr: os.dup2(parentErr, 2) # Reconnect to parent's stdout sys.stderr.write("**execvp failed, '%s'**\n" % @@ -133,7 +140,8 @@ class Subprocess: time.sleep(execvp_grace_seconds) try: pid, err = os.waitpid(self.pid, os.WNOHANG) - except os.error, (errno, msg): + except os.error as error: + errno, msg = error if errno == 10: raise SubprocessError("Subprocess '%s' failed." % self.cmd) raise SubprocessError("Subprocess failed[%d]: %s" % (errno, msg)) @@ -205,7 +213,7 @@ class Subprocess: got0 = self.readPendingChars(n) got = got + got0 n = n - len(got0) - return got + return got def readPendingChars(self, max=None): """Read all currently pending subprocess output as a single string.""" return self.readbuf.readPendingChars(max) @@ -324,7 +332,7 @@ class Subprocess: # 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))) def __del__(self): """Terminate the subprocess""" @@ -400,15 +408,15 @@ class ReadBuf: got = "" if self.buf: - 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 if self.eof: - return '' + return '' sel = select.select([self.fd], [], [self.fd], 0) if sel[2]: @@ -536,7 +544,7 @@ def record_trial(s): c.write(s) c.seek(0) r = c.read() - show = " start:\t %s\n end:\t %s\n" % (`s`, `r`) + show = " start:\t %s\n end:\t %s\n" % (repr(s), repr(r)) if r != s: raise IOError("String distorted:\n%s" % show) @@ -589,7 +597,7 @@ class Ph: line = string.splitfields(line, ':') it[string.strip(line[0])] = ( string.strip(string.join(line[1:]))) - + def getreply(self): """Consume next response from ph, returning list of lines or string err.""" @@ -642,23 +650,23 @@ class Ph: ############################################################################# 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(`p.readline()`) - print(`p.readline()`) + print(repr(p.readline())) + print(repr(p.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(`p.readline()`) + print(repr(p.readline())) print('\tRest via readPendingChars:') print(p.readPendingChars()) print("\tStopping then continuing subprocess (verbose):") @@ -680,3 +688,6 @@ def test(p=0): del p print("\tDone.") return None + +if __name__ == '__main__': + test()