summaryrefslogtreecommitdiff
path: root/Modules/_posixsubprocess.c
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2012-10-10 03:34:47 -0700
committerGregory P. Smith <greg@krypto.org>2012-10-10 03:34:47 -0700
commit5591b02a4c96c4b530ee024e6b1581f5ba72945d (patch)
treec8618089fe0ad50bbc2783517d5eb71bfca7e3d3 /Modules/_posixsubprocess.c
parenta256841b4bd923c5ac149a97318cde23c1086e39 (diff)
downloadcpython-git-5591b02a4c96c4b530ee024e6b1581f5ba72945d.tar.gz
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 'Modules/_posixsubprocess.c')
-rw-r--r--Modules/_posixsubprocess.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
index 59673f4969..19ca31f56d 100644
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -354,7 +354,7 @@ child_exec(char *const exec_array[],
PyObject *preexec_fn,
PyObject *preexec_fn_args_tuple)
{
- int i, saved_errno, unused;
+ int i, saved_errno, unused, reached_preexec = 0;
PyObject *result;
const char* err_msg = "";
/* Buffer large enough to hold a hex integer. We can't malloc. */
@@ -438,6 +438,7 @@ child_exec(char *const exec_array[],
POSIX_CALL(setsid());
#endif
+ reached_preexec = 1;
if (preexec_fn != Py_None && preexec_fn_args_tuple) {
/* This is where the user has asked us to deadlock their program. */
result = PyObject_Call(preexec_fn, preexec_fn_args_tuple, NULL);
@@ -487,6 +488,10 @@ error:
}
unused = write(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur);
unused = write(errpipe_write, ":", 1);
+ if (!reached_preexec) {
+ /* Indicate to the parent that the error happened before exec(). */
+ unused = write(errpipe_write, "noexec", 6);
+ }
/* We can't call strerror(saved_errno). It is not async signal safe.
* The parent process will look the error message up. */
} else {