X-Git-Url: https://git.phdru.name/?a=blobdiff_plain;ds=sidebyside;f=subproc.py;h=f5e89c5ffc75c003e22b8335ea4bdb9d9d39d9c9;hb=3e7f48c2fc9e132806609f7811c62bf2a43ddf7c;hp=39f82a63243cb628afc177f69f325c11d99f3d7c;hpb=3f8cd2467fcee643fd4ece8dac9f5cdf70f905c5;p=bookmarks_db.git diff --git a/subproc.py b/subproc.py index 39f82a6..f5e89c5 100644 --- a/subproc.py +++ b/subproc.py @@ -1,6 +1,7 @@ """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: @@ -11,14 +12,11 @@ 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 @@ -91,6 +89,7 @@ class Subprocess: """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 @@ -112,7 +111,16 @@ class Subprocess: 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 ### @@ -146,21 +154,6 @@ class Subprocess: # 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): @@ -279,9 +272,9 @@ class Subprocess: os.kill(self.pid, signal.SIGSTOP) except os.error: if verbose: - print "Stop failed for '%s' - '%s'" % (self.cmd, sys.exc_value) + print("Stop failed for '%s' - '%s'" % (self.cmd, sys.exc_value)) return 0 - if verbose: print "Stopped '%s'" % self.cmd + if verbose: print("Stopped '%s'" % self.cmd) return 'stopped' def cont(self, verbose=0): @@ -291,10 +284,10 @@ class Subprocess: os.kill(self.pid, signal.SIGCONT) except os.error: if verbose: - print ("Continue failed for '%s' - '%s'" % - (self.cmd, sys.exc_value)) + print(("Continue failed for '%s' - '%s'" % + (self.cmd, sys.exc_value))) return 0 - if verbose: print "Continued '%s'" % self.cmd + if verbose: print("Continued '%s'" % self.cmd) return 'continued' def die(self): @@ -322,9 +315,9 @@ class Subprocess: # WNOHANG == 1 on sunos, presumably same elsewhere. if os.waitpid(self.pid, os.WNOHANG): if self.expire_noisily: - print ("\n(%s subproc %d '%s' / %s)" % + print(("\n(%s subproc %d '%s' / %s)" % (sig[0], self.pid, self.cmd, - hex(id(self))[2:])) + hex(id(self))[2:]))) for i in self.pipefiles: os.close(i) self.pid = 0 @@ -344,13 +337,6 @@ class Subprocess: status = self.status() return '' -# 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 ##### ############################################################################# @@ -416,11 +402,15 @@ class ReadBuf: 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]: @@ -654,41 +644,41 @@ class Ph: ############################################################################# def test(p=0): - print "\tOpening subprocess:" + print("\tOpening subprocess:") p = Subprocess('cat', 1) # set to expire noisily... - print p - print "\tOpening bogus subprocess, should fail:" + print(p) + print("\tOpening bogus subprocess, should fail:") try: b = Subprocess('/', 1) - print "\tOops! Null-named subprocess startup *succeeded*?!?" + print("\tOops! Null-named subprocess startup *succeeded*?!?") except SubprocessError: - print "\t...yep, it failed." - print '\tWrite, then read, two newline-teriminated lines, using readline:' + 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 `p.readline()` - print `p.readline()` - print '\tThree lines, last sans newline, read using combination:' + print(`p.readline()`) + print(`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 '\tRest via readPendingChars:' - print p.readPendingChars() - print "\tStopping then continuing subprocess (verbose):" + print('\tFirst line via readline:') + print(`p.readline()`) + print('\tRest via readPendingChars:') + print(p.readPendingChars()) + print("\tStopping then continuing subprocess (verbose):") if not p.stop(1): # verbose stop - print '\t** Stop seems to have failed!' + print('\t** Stop seems to have failed!') else: - print '\tWriting line while subprocess is paused...' + print('\tWriting line while subprocess is paused...') p.write('written while subprocess paused\n') - print '\tNonblocking read of paused subprocess (should be empty):' - print p.readPendingChars() - print '\tContinuing subprocess (verbose):' + print('\tNonblocking read of paused subprocess (should be empty):') + print(p.readPendingChars()) + print('\tContinuing subprocess (verbose):') if not p.cont(1): # verbose continue - print '\t** Continue seems to have failed! Probly lost subproc...' + print('\t** Continue seems to have failed! Probly lost subproc...') return p else: - print '\tReading accumulated line, blocking read:' - print p.readline() - print "\tDeleting subproc, which was set to die noisily:" + print('\tReading accumulated line, blocking read:') + print(p.readline()) + print("\tDeleting subproc, which was set to die noisily:") del p - print "\tDone." + print("\tDone.") return None