summaryrefslogtreecommitdiffstats
path: root/Modules/_posixsubprocess.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_posixsubprocess.c')
-rw-r--r--Modules/_posixsubprocess.c38
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)