mirror of
https://github.com/ARM-software/devlib.git
synced 2025-01-31 02:00:45 +00:00
utils/misc: Cleanup check_output()
* Remove check_output_lock as the issue has been fixed in Python 3.4 * Use Popen process as a context manager. Technically, Popen.communicate() already achieves those but the context manager will ensure this is done even if an exception happens at any point.
This commit is contained in:
parent
be734140b3
commit
678822f9e4
@ -151,22 +151,16 @@ def preexec_function():
|
|||||||
|
|
||||||
|
|
||||||
check_output_logger = logging.getLogger('check_output')
|
check_output_logger = logging.getLogger('check_output')
|
||||||
# Popen is not thread safe. If two threads attempt to call it at the same time,
|
|
||||||
# one may lock up. See https://bugs.python.org/issue12739.
|
|
||||||
check_output_lock = threading.RLock()
|
|
||||||
|
|
||||||
|
|
||||||
def get_subprocess(command, **kwargs):
|
def get_subprocess(command, **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.')
|
||||||
with check_output_lock:
|
return subprocess.Popen(command,
|
||||||
process = subprocess.Popen(command,
|
stdout=subprocess.PIPE,
|
||||||
stdout=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stdin=subprocess.PIPE,
|
||||||
stdin=subprocess.PIPE,
|
preexec_fn=preexec_function,
|
||||||
preexec_fn=preexec_function,
|
**kwargs)
|
||||||
**kwargs)
|
|
||||||
return process
|
|
||||||
|
|
||||||
|
|
||||||
def check_subprocess_output(process, timeout=None, ignore=None, inputtext=None):
|
def check_subprocess_output(process, timeout=None, ignore=None, inputtext=None):
|
||||||
@ -181,21 +175,22 @@ def check_subprocess_output(process, timeout=None, ignore=None, inputtext=None):
|
|||||||
message = 'Invalid value for ignore parameter: "{}"; must be an int or a list'
|
message = 'Invalid value for ignore parameter: "{}"; must be an int or a list'
|
||||||
raise ValueError(message.format(ignore))
|
raise ValueError(message.format(ignore))
|
||||||
|
|
||||||
try:
|
with process:
|
||||||
output, error = process.communicate(inputtext, timeout=timeout)
|
try:
|
||||||
except subprocess.TimeoutExpired as e:
|
output, error = process.communicate(inputtext, timeout=timeout)
|
||||||
timeout_expired = e
|
except subprocess.TimeoutExpired as e:
|
||||||
else:
|
timeout_expired = e
|
||||||
timeout_expired = None
|
else:
|
||||||
|
timeout_expired = None
|
||||||
|
|
||||||
# Currently errors=replace is needed as 0x8c throws an error
|
# Currently errors=replace is needed as 0x8c throws an error
|
||||||
output = output.decode(sys.stdout.encoding or 'utf-8', "replace") if output else ''
|
output = output.decode(sys.stdout.encoding or 'utf-8', "replace") if output else ''
|
||||||
error = error.decode(sys.stderr.encoding or 'utf-8', "replace") if error else ''
|
error = error.decode(sys.stderr.encoding or 'utf-8', "replace") if error else ''
|
||||||
|
|
||||||
if timeout_expired:
|
if timeout_expired:
|
||||||
raise TimeoutError(process.args, output='\n'.join([output, error]))
|
raise TimeoutError(process.args, output='\n'.join([output, error]))
|
||||||
|
|
||||||
retcode = process.poll()
|
retcode = process.returncode
|
||||||
if retcode and ignore != 'all' and retcode not in ignore:
|
if retcode and ignore != 'all' and retcode not in ignore:
|
||||||
raise subprocess.CalledProcessError(retcode, process.args, output, error)
|
raise subprocess.CalledProcessError(retcode, process.args, output, error)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user