diff options
Diffstat (limited to 'Modules/_posixsubprocess.c')
| -rw-r--r-- | Modules/_posixsubprocess.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index 1490223..8bedab5 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -117,10 +117,11 @@ _sanity_check_python_fd_sequence(PyObject *fd_sequence) for (seq_idx = 0; seq_idx < seq_len; ++seq_idx) { PyObject* py_fd = PySequence_Fast_GET_ITEM(fd_sequence, seq_idx); long iter_fd = PyLong_AsLong(py_fd); - if (iter_fd < 0 || iter_fd < prev_fd || iter_fd > INT_MAX) { + if (iter_fd < 0 || iter_fd <= prev_fd || iter_fd > INT_MAX) { /* Negative, overflow, not a Long, unsorted, too big for a fd. */ return 1; } + prev_fd = iter_fd; } return 0; } @@ -272,7 +273,7 @@ _close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep) { int fd_dir_fd; - fd_dir_fd = _Py_open(FD_DIR, O_RDONLY); + fd_dir_fd = _Py_open_noraise(FD_DIR, O_RDONLY); if (fd_dir_fd == -1) { /* No way to get a list of open fds. */ _close_fds_by_brute_force(start_fd, py_fds_to_keep); @@ -400,7 +401,7 @@ child_exec(char *const exec_array[], PyObject *preexec_fn, PyObject *preexec_fn_args_tuple) { - int i, saved_errno, unused, reached_preexec = 0; + int i, saved_errno, reached_preexec = 0; PyObject *result; const char* err_msg = ""; /* Buffer large enough to hold a hex integer. We can't malloc. */ @@ -514,28 +515,29 @@ error: saved_errno = errno; /* Report the posix error to our parent process. */ /* We ignore all write() return values as the total size of our writes is - * less than PIPEBUF and we cannot do anything about an error anyways. */ + less than PIPEBUF and we cannot do anything about an error anyways. + Use _Py_write_noraise() to retry write() if it is interrupted by a + signal (fails with EINTR). */ if (saved_errno) { char *cur; - unused = write(errpipe_write, "OSError:", 8); + _Py_write_noraise(errpipe_write, "OSError:", 8); cur = hex_errno + sizeof(hex_errno); while (saved_errno != 0 && cur > hex_errno) { - *--cur = "0123456789ABCDEF"[saved_errno % 16]; + *--cur = Py_hexdigits[saved_errno % 16]; saved_errno /= 16; } - unused = write(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur); - unused = write(errpipe_write, ":", 1); + _Py_write_noraise(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur); + _Py_write_noraise(errpipe_write, ":", 1); if (!reached_preexec) { /* Indicate to the parent that the error happened before exec(). */ - unused = write(errpipe_write, "noexec", 6); + _Py_write_noraise(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 { - unused = write(errpipe_write, "SubprocessError:0:", 18); - unused = write(errpipe_write, err_msg, strlen(err_msg)); + _Py_write_noraise(errpipe_write, "SubprocessError:0:", 18); + _Py_write_noraise(errpipe_write, err_msg, strlen(err_msg)); } - if (unused) return; /* silly? yes! avoids gcc compiler warning. */ } @@ -556,7 +558,9 @@ subprocess_fork_exec(PyObject* self, PyObject *args) int need_to_reenable_gc = 0; char *const *exec_array, *const *argv = NULL, *const *envp = NULL; Py_ssize_t arg_num; +#ifdef WITH_THREAD int import_lock_held = 0; +#endif if (!PyArg_ParseTuple( args, "OOpOOOiiiiiiiiiiO:fork_exec", @@ -651,8 +655,10 @@ subprocess_fork_exec(PyObject* self, PyObject *args) preexec_fn_args_tuple = PyTuple_New(0); if (!preexec_fn_args_tuple) goto cleanup; +#ifdef WITH_THREAD _PyImport_AcquireLock(); import_lock_held = 1; +#endif } if (cwd_obj != Py_None) { @@ -695,13 +701,15 @@ subprocess_fork_exec(PyObject* self, PyObject *args) /* Capture the errno exception before errno can be clobbered. */ PyErr_SetFromErrno(PyExc_OSError); } - if (preexec_fn != Py_None && - _PyImport_ReleaseLock() < 0 && !PyErr_Occurred()) { +#ifdef WITH_THREAD + if (preexec_fn != Py_None + && _PyImport_ReleaseLock() < 0 && !PyErr_Occurred()) { PyErr_SetString(PyExc_RuntimeError, "not holding the import lock"); pid = -1; } import_lock_held = 0; +#endif /* Parent process */ if (envp) @@ -723,8 +731,10 @@ subprocess_fork_exec(PyObject* self, PyObject *args) return PyLong_FromPid(pid); cleanup: +#ifdef WITH_THREAD if (import_lock_held) _PyImport_ReleaseLock(); +#endif if (envp) _Py_FreeCharPArray(envp); if (argv) |
