# HG changeset patch # User Edouard Tisserant # Date 1700824579 -3600 # Node ID a1d7187b84023ba2412f2e3248ccf01f13dc2767 # Parent 098875cff39fbfff83216d587e50c9e9a2b26ff8 Runtime: Add stderr support to local posix spawn based subprocess replacement diff -r 098875cff39f -r a1d7187b8402 runtime/spawn_subprocess.py --- a/runtime/spawn_subprocess.py Wed Nov 22 11:24:16 2023 +0100 +++ b/runtime/spawn_subprocess.py Fri Nov 24 12:16:19 2023 +0100 @@ -14,17 +14,24 @@ class Popen(object): - def __init__(self, args, stdin=None, stdout=None): + def __init__(self, args, stdin=None, stdout=None, stderr=None): self.returncode = None self.stdout = None + self.stderr = None self.stdin = None - # TODO: stderr file_actions = posix_spawn.FileActions() if stdout is not None: # child's stdout, child 2 parent pipe + c1pread, c1pwrite = os.pipe() + # attach child's stdout to writing en of c1p pipe + file_actions.add_dup2(c1pwrite, 1) + # close other end + file_actions.add_close(c1pread) + if stderr is not None: + # child's stderr, child 2 parent pipe c2pread, c2pwrite = os.pipe() - # attach child's stdout to writing en of c2p pipe - file_actions.add_dup2(c2pwrite, 1) + # attach child's stderr to writing en of c2p pipe + file_actions.add_dup2(c2pwrite, 2) # close other end file_actions.add_close(c2pread) if stdin is not None: @@ -36,7 +43,10 @@ file_actions.add_close(p2cwrite) self.pid = posix_spawn.posix_spawnp(args[0], args, file_actions=file_actions) if stdout is not None: - self.stdout = os.fdopen(c2pread) + self.stdout = os.fdopen(c1pread) + os.close(c1pwrite) + if stderr is not None: + self.stderr = os.fdopen(c2pread) os.close(c2pwrite) if stdin is not None: self.stdin = os.fdopen(p2cwrite, 'w') @@ -50,29 +60,44 @@ if self.stdin is not None: self.stdin.close() self.stdin = None + if self.stdout is not None: stdoutdata = self.stdout.read() else: stdoutdata = "" - # TODO - stderrdata = "" + if self.stderr is not None: + stderrdata = self.stderr.read() + else: + stderrdata = "" self._wait() + if self.stdout is not None: self.stdout.close() self.stdout = None + if self.stderr is not None: + self.stderr.close() + self.stderr = None + return (stdoutdata, stderrdata) def wait(self): if self.stdin is not None: self.stdin.close() self.stdin = None + self._wait() + if self.stdout is not None: self.stdout.close() self.stdout = None + + if self.stderr is not None: + self.stderr.close() + self.stderr = None + return self.returncode def poll(self): @@ -84,10 +109,15 @@ if self.stdin is not None: self.stdin.close() self.stdin = None + if self.stdout is not None: self.stdout.close() self.stdout = None + if self.stderr is not None: + self.stderr.close() + self.stderr = None + return self.returncode def kill(self): @@ -96,10 +126,15 @@ if self.stdin is not None: self.stdin.close() self.stdin = None + if self.stdout is not None: self.stdout.close() self.stdout = None + if self.stderr is not None: + self.stderr.close() + self.stderr = None + def call(*args): cmd = []