diff options
author | Gregory P. Smith <greg@krypto.org> | 2012-10-10 10:34:47 (GMT) |
---|---|---|
committer | Gregory P. Smith <greg@krypto.org> | 2012-10-10 10:34:47 (GMT) |
commit | 5591b02a4c96c4b530ee024e6b1581f5ba72945d (patch) | |
tree | c8618089fe0ad50bbc2783517d5eb71bfca7e3d3 /Lib/subprocess.py | |
parent | a256841b4bd923c5ac149a97318cde23c1086e39 (diff) | |
download | cpython-5591b02a4c96c4b530ee024e6b1581f5ba72945d.zip cpython-5591b02a4c96c4b530ee024e6b1581f5ba72945d.tar.gz cpython-5591b02a4c96c4b530ee024e6b1581f5ba72945d.tar.bz2 |
Fixes Issue #16114: The subprocess module no longer provides a
misleading error message stating that args[0] did not exist when
either the cwd or executable keyword arguments specified a path that
did not exist.
It now keeps track of if the child got as far as preexec and reports it if
not back to the parent via a special "noexec" error message value in
the error pipe so that the cwd can be blamed for a failed chdir
instead of the exec of the executable being blamed instead.
The executable is also always reported accurately when exec fails.
Unittests enhanced to cover these cases.
Diffstat (limited to 'Lib/subprocess.py')
-rw-r--r-- | Lib/subprocess.py | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 93262df..83c79ef 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1169,6 +1169,7 @@ class Popen(object): if executable is None: executable = args[0] + orig_executable = executable # For transferring possible exec failure from child to parent. # Data format: "exception name:hex errno:description" @@ -1224,6 +1225,7 @@ class Popen(object): self._child_created = True if self.pid == 0: # Child + reached_preexec = False try: # Close parent's pipe ends if p2cwrite != -1: @@ -1288,6 +1290,7 @@ class Popen(object): if start_new_session and hasattr(os, 'setsid'): os.setsid() + reached_preexec = True if preexec_fn: preexec_fn() @@ -1303,6 +1306,8 @@ class Popen(object): errno_num = exc_value.errno else: errno_num = 0 + if not reached_preexec: + exc_value = "noexec" message = '%s:%x:%s' % (exc_type.__name__, errno_num, exc_value) message = message.encode(errors="surrogatepass") @@ -1364,10 +1369,17 @@ class Popen(object): err_msg = err_msg.decode(errors="surrogatepass") if issubclass(child_exception_type, OSError) and hex_errno: errno_num = int(hex_errno, 16) + child_exec_never_called = (err_msg == "noexec") + if child_exec_never_called: + err_msg = "" if errno_num != 0: err_msg = os.strerror(errno_num) if errno_num == errno.ENOENT: - err_msg += ': ' + repr(args[0]) + if child_exec_never_called: + # The error must be from chdir(cwd). + err_msg += ': ' + repr(cwd) + else: + err_msg += ': ' + repr(orig_executable) raise child_exception_type(errno_num, err_msg) raise child_exception_type(err_msg) |