mirror of
https://github.com/python/cpython.git
synced 2025-12-11 11:31:05 +00:00
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.
This commit is contained in:
parent
3391e64482
commit
c15c88c13d
2 changed files with 38 additions and 22 deletions
|
|
@ -464,10 +464,10 @@ def call(*popenargs, timeout=None, **kwargs):
|
||||||
|
|
||||||
retcode = call(["ls", "-l"])
|
retcode = call(["ls", "-l"])
|
||||||
"""
|
"""
|
||||||
p = Popen(*popenargs, **kwargs)
|
with Popen(*popenargs, **kwargs) as p:
|
||||||
try:
|
try:
|
||||||
return p.wait(timeout=timeout)
|
return p.wait(timeout=timeout)
|
||||||
except TimeoutExpired:
|
except:
|
||||||
p.kill()
|
p.kill()
|
||||||
p.wait()
|
p.wait()
|
||||||
raise
|
raise
|
||||||
|
|
@ -514,13 +514,17 @@ def check_output(*popenargs, timeout=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
if 'stdout' in kwargs:
|
if 'stdout' in kwargs:
|
||||||
raise ValueError('stdout argument not allowed, it will be overridden.')
|
raise ValueError('stdout argument not allowed, it will be overridden.')
|
||||||
process = Popen(*popenargs, stdout=PIPE, **kwargs)
|
with Popen(*popenargs, stdout=PIPE, **kwargs) as process:
|
||||||
try:
|
try:
|
||||||
output, unused_err = process.communicate(timeout=timeout)
|
output, unused_err = process.communicate(timeout=timeout)
|
||||||
except TimeoutExpired:
|
except TimeoutExpired:
|
||||||
process.kill()
|
process.kill()
|
||||||
output, unused_err = process.communicate()
|
output, unused_err = process.communicate()
|
||||||
raise TimeoutExpired(process.args, timeout, output=output)
|
raise TimeoutExpired(process.args, timeout, output=output)
|
||||||
|
except:
|
||||||
|
process.kill()
|
||||||
|
process.wait()
|
||||||
|
raise
|
||||||
retcode = process.poll()
|
retcode = process.poll()
|
||||||
if retcode:
|
if retcode:
|
||||||
raise CalledProcessError(retcode, process.args, output=output)
|
raise CalledProcessError(retcode, process.args, output=output)
|
||||||
|
|
@ -618,11 +622,19 @@ def getstatusoutput(cmd):
|
||||||
>>> subprocess.getstatusoutput('/bin/junk')
|
>>> subprocess.getstatusoutput('/bin/junk')
|
||||||
(256, 'sh: /bin/junk: not found')
|
(256, 'sh: /bin/junk: not found')
|
||||||
"""
|
"""
|
||||||
pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r')
|
with os.popen('{ ' + cmd + '; } 2>&1', 'r') as pipe:
|
||||||
|
try:
|
||||||
text = pipe.read()
|
text = pipe.read()
|
||||||
sts = pipe.close()
|
sts = pipe.close()
|
||||||
if sts is None: sts = 0
|
except:
|
||||||
if text[-1:] == '\n': text = text[:-1]
|
process = pipe._proc
|
||||||
|
process.kill()
|
||||||
|
process.wait()
|
||||||
|
raise
|
||||||
|
if sts is None:
|
||||||
|
sts = 0
|
||||||
|
if text[-1:] == '\n':
|
||||||
|
text = text[:-1]
|
||||||
return sts, text
|
return sts, text
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,10 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #12494: 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.
|
||||||
|
|
||||||
- Issue #12720: Expose low-level Linux extended file attribute functions in os.
|
- Issue #12720: Expose low-level Linux extended file attribute functions in os.
|
||||||
|
|
||||||
- Issue #10946: The distutils commands bdist_dumb, bdist_wininst and bdist_msi
|
- Issue #10946: The distutils commands bdist_dumb, bdist_wininst and bdist_msi
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue