Author: futatuki Date: Thu Nov 28 17:16:38 2019 New Revision: 1870561 URL: http://svn.apache.org/viewvc?rev=1870561&view=rev Log: Follow up to r1870204,r1870217,r1870266: Reduce work to communicate to child
* tools/server-side/svn-backup-dumps.py (SvnBackup.exec_cmd_unix): - Use Popen.communicate if output is None. - Pass stdout of the parent to the child process as stderr directly if printerr is True, to avoid extra encode/decode on py3 and buffering. Suggested by: Jun Omae <jun66j5_{AT}_gmail.com> Modified: subversion/trunk/tools/server-side/svn-backup-dumps.py Modified: subversion/trunk/tools/server-side/svn-backup-dumps.py URL: http://svn.apache.org/viewvc/subversion/trunk/tools/server-side/svn-backup-dumps.py?rev=1870561&r1=1870560&r2=1870561&view=diff ============================================================================== --- subversion/trunk/tools/server-side/svn-backup-dumps.py (original) +++ subversion/trunk/tools/server-side/svn-backup-dumps.py Thu Nov 28 17:16:38 2019 @@ -377,39 +377,51 @@ class SvnBackup: return self.exec_cmd_unix(cmd, output, printerr) def exec_cmd_unix(self, cmd, output=None, printerr=False): + if printerr: + if sys.hexversion >= 0x3000000: + sys.stdout.flush() + errout = sys.stdout.buffer + else: + errout = sys.stdout + else: + errout = PIPE try: - proc = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=False) + proc = Popen(cmd, stdout=PIPE, stderr=errout, shell=False) except: return (256, "", "Popen failed (%s ...):\n %s" % (cmd[0], str(sys.exc_info()[1]))) - stdout = proc.stdout - stderr = proc.stderr - self.set_nonblock(stdout) - self.set_nonblock(stderr) - readfds = [ stdout, stderr ] - selres = select.select(readfds, [], []) - bufout = b"" - buferr = b"" - while len(selres[0]) > 0: - for fd in selres[0]: - buf = fd.read(16384) - if len(buf) == 0: - readfds.remove(fd) - elif fd == stdout: - if output: - output.write(buf) - else: - bufout += buf - else: - if printerr: - sys.stdout.write(buf.decode(sys.stdout.encoding, - 'backslashreplace')) + if output is None: + bufout, buferr = proc.communicate() + rc = proc.returncode + if buferr is None: + buferr = b"" + else: + stdout = proc.stdout + self.set_nonblock(stdout) + readfds = [ stdout ] + if not printerr: + stderr = proc.stderr + self.set_nonblock(stderr) + readfds.append(stderr) + selres = select.select(readfds, [], []) + bufout = b"" + buferr = b"" + while len(selres[0]) > 0: + for fd in selres[0]: + buf = fd.read(16384) + if len(buf) == 0: + readfds.remove(fd) + elif fd == stdout: + if output: + output.write(buf) + else: + bufout += buf else: buferr += buf - if len(readfds) == 0: - break - selres = select.select(readfds, [], []) - rc = proc.wait() + if len(readfds) == 0: + break + selres = select.select(readfds, [], []) + rc = proc.wait() if printerr: print("") return (rc, bufout, buferr)