diff options
author | Victor Stinner <victor.stinner@haypocalc.com> | 2011-09-01 21:45:04 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@haypocalc.com> | 2011-09-01 21:45:04 (GMT) |
commit | c15c88c13dd67e320161760638778b17486100c1 (patch) | |
tree | ac307edc5d42ff52186369ed1d2d88fa9cabfc4c /Lib/subprocess.py | |
parent | 3391e64482fa55c06b073cc76668bf1bf3e5c149 (diff) | |
download | cpython-c15c88c13dd67e320161760638778b17486100c1.zip cpython-c15c88c13dd67e320161760638778b17486100c1.tar.gz cpython-c15c88c13dd67e320161760638778b17486100c1.tar.bz2 |
Issue #12494: Close pipes and kill process on error in subprocess functions
On error, call(), check_call(), check_output() and getstatusoutput() functions
of the subprocess module now kill the process, read its status (to avoid
zombis) and close pipes.
Diffstat (limited to 'Lib/subprocess.py')
-rw-r--r-- | Lib/subprocess.py | 56 |
1 files changed, 34 insertions, 22 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py index db64588..2c5c888 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -464,13 +464,13 @@ def call(*popenargs, timeout=None, **kwargs): retcode = call(["ls", "-l"]) """ - p = Popen(*popenargs, **kwargs) - try: - return p.wait(timeout=timeout) - except TimeoutExpired: - p.kill() - p.wait() - raise + with Popen(*popenargs, **kwargs) as p: + try: + return p.wait(timeout=timeout) + except: + p.kill() + p.wait() + raise def check_call(*popenargs, **kwargs): @@ -514,16 +514,20 @@ def check_output(*popenargs, timeout=None, **kwargs): """ if 'stdout' in kwargs: raise ValueError('stdout argument not allowed, it will be overridden.') - process = Popen(*popenargs, stdout=PIPE, **kwargs) - try: - output, unused_err = process.communicate(timeout=timeout) - except TimeoutExpired: - process.kill() - output, unused_err = process.communicate() - raise TimeoutExpired(process.args, timeout, output=output) - retcode = process.poll() - if retcode: - raise CalledProcessError(retcode, process.args, output=output) + with Popen(*popenargs, stdout=PIPE, **kwargs) as process: + try: + output, unused_err = process.communicate(timeout=timeout) + except TimeoutExpired: + process.kill() + output, unused_err = process.communicate() + raise TimeoutExpired(process.args, timeout, output=output) + except: + process.kill() + process.wait() + raise + retcode = process.poll() + if retcode: + raise CalledProcessError(retcode, process.args, output=output) return output @@ -618,11 +622,19 @@ def getstatusoutput(cmd): >>> subprocess.getstatusoutput('/bin/junk') (256, 'sh: /bin/junk: not found') """ - pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') - text = pipe.read() - sts = pipe.close() - if sts is None: sts = 0 - if text[-1:] == '\n': text = text[:-1] + with os.popen('{ ' + cmd + '; } 2>&1', 'r') as pipe: + try: + text = pipe.read() + sts = pipe.close() + except: + process = pipe._proc + process.kill() + process.wait() + raise + if sts is None: + sts = 0 + if text[-1:] == '\n': + text = text[:-1] return sts, text |