ยปCore Development>Code coverage>Modules/_posixsubprocess.c

Python code coverage for Modules/_posixsubprocess.c

#countcontent
1n/a/* Authors: Gregory P. Smith & Jeffrey Yasskin */
2n/a#include "Python.h"
3n/a#if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE)
4n/a# define _GNU_SOURCE
5n/a#endif
6n/a#include <unistd.h>
7n/a#include <fcntl.h>
8n/a#ifdef HAVE_SYS_TYPES_H
9n/a#include <sys/types.h>
10n/a#endif
11n/a#if defined(HAVE_SYS_STAT_H) && defined(__FreeBSD__)
12n/a#include <sys/stat.h>
13n/a#endif
14n/a#ifdef HAVE_SYS_SYSCALL_H
15n/a#include <sys/syscall.h>
16n/a#endif
17n/a#if defined(HAVE_SYS_RESOURCE_H)
18n/a#include <sys/resource.h>
19n/a#endif
20n/a#ifdef HAVE_DIRENT_H
21n/a#include <dirent.h>
22n/a#endif
23n/a
24n/a#if defined(__ANDROID__) && __ANDROID_API__ < 21 && !defined(SYS_getdents64)
25n/a# include <sys/linux-syscalls.h>
26n/a# define SYS_getdents64 __NR_getdents64
27n/a#endif
28n/a
29n/a#if defined(sun)
30n/a/* readdir64 is used to work around Solaris 9 bug 6395699. */
31n/a# define readdir readdir64
32n/a# define dirent dirent64
33n/a# if !defined(HAVE_DIRFD)
34n/a/* Some versions of Solaris lack dirfd(). */
35n/a# define dirfd(dirp) ((dirp)->dd_fd)
36n/a# define HAVE_DIRFD
37n/a# endif
38n/a#endif
39n/a
40n/a#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__))
41n/a# define FD_DIR "/dev/fd"
42n/a#else
43n/a# define FD_DIR "/proc/self/fd"
44n/a#endif
45n/a
46n/a#define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0)
47n/a
48n/a
49n/a/* If gc was disabled, call gc.enable(). Return 0 on success. */
50n/astatic int
51n/a_enable_gc(int need_to_reenable_gc, PyObject *gc_module)
52n/a{
53n/a PyObject *result;
54n/a _Py_IDENTIFIER(enable);
55n/a PyObject *exctype, *val, *tb;
56n/a
57n/a if (need_to_reenable_gc) {
58n/a PyErr_Fetch(&exctype, &val, &tb);
59n/a result = _PyObject_CallMethodId(gc_module, &PyId_enable, NULL);
60n/a if (exctype != NULL) {
61n/a PyErr_Restore(exctype, val, tb);
62n/a }
63n/a if (result == NULL) {
64n/a return 1;
65n/a }
66n/a Py_DECREF(result);
67n/a }
68n/a return 0;
69n/a}
70n/a
71n/a
72n/a/* Convert ASCII to a positive int, no libc call. no overflow. -1 on error. */
73n/astatic int
74n/a_pos_int_from_ascii(const char *name)
75n/a{
76n/a int num = 0;
77n/a while (*name >= '0' && *name <= '9') {
78n/a num = num * 10 + (*name - '0');
79n/a ++name;
80n/a }
81n/a if (*name)
82n/a return -1; /* Non digit found, not a number. */
83n/a return num;
84n/a}
85n/a
86n/a
87n/a#if defined(__FreeBSD__)
88n/a/* When /dev/fd isn't mounted it is often a static directory populated
89n/a * with 0 1 2 or entries for 0 .. 63 on FreeBSD, NetBSD and OpenBSD.
90n/a * NetBSD and OpenBSD have a /proc fs available (though not necessarily
91n/a * mounted) and do not have fdescfs for /dev/fd. MacOS X has a devfs
92n/a * that properly supports /dev/fd.
93n/a */
94n/astatic int
95n/a_is_fdescfs_mounted_on_dev_fd(void)
96n/a{
97n/a struct stat dev_stat;
98n/a struct stat dev_fd_stat;
99n/a if (stat("/dev", &dev_stat) != 0)
100n/a return 0;
101n/a if (stat(FD_DIR, &dev_fd_stat) != 0)
102n/a return 0;
103n/a if (dev_stat.st_dev == dev_fd_stat.st_dev)
104n/a return 0; /* / == /dev == /dev/fd means it is static. #fail */
105n/a return 1;
106n/a}
107n/a#endif
108n/a
109n/a
110n/a/* Returns 1 if there is a problem with fd_sequence, 0 otherwise. */
111n/astatic int
112n/a_sanity_check_python_fd_sequence(PyObject *fd_sequence)
113n/a{
114n/a Py_ssize_t seq_idx, seq_len = PySequence_Length(fd_sequence);
115n/a long prev_fd = -1;
116n/a for (seq_idx = 0; seq_idx < seq_len; ++seq_idx) {
117n/a PyObject* py_fd = PySequence_Fast_GET_ITEM(fd_sequence, seq_idx);
118n/a long iter_fd = PyLong_AsLong(py_fd);
119n/a if (iter_fd < 0 || iter_fd <= prev_fd || iter_fd > INT_MAX) {
120n/a /* Negative, overflow, not a Long, unsorted, too big for a fd. */
121n/a return 1;
122n/a }
123n/a prev_fd = iter_fd;
124n/a }
125n/a return 0;
126n/a}
127n/a
128n/a
129n/a/* Is fd found in the sorted Python Sequence? */
130n/astatic int
131n/a_is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence)
132n/a{
133n/a /* Binary search. */
134n/a Py_ssize_t search_min = 0;
135n/a Py_ssize_t search_max = PySequence_Length(fd_sequence) - 1;
136n/a if (search_max < 0)
137n/a return 0;
138n/a do {
139n/a long middle = (search_min + search_max) / 2;
140n/a long middle_fd = PyLong_AsLong(
141n/a PySequence_Fast_GET_ITEM(fd_sequence, middle));
142n/a if (fd == middle_fd)
143n/a return 1;
144n/a if (fd > middle_fd)
145n/a search_min = middle + 1;
146n/a else
147n/a search_max = middle - 1;
148n/a } while (search_min <= search_max);
149n/a return 0;
150n/a}
151n/a
152n/astatic int
153n/amake_inheritable(PyObject *py_fds_to_keep, int errpipe_write)
154n/a{
155n/a Py_ssize_t i, len;
156n/a
157n/a len = PySequence_Length(py_fds_to_keep);
158n/a for (i = 0; i < len; ++i) {
159n/a PyObject* fdobj = PySequence_Fast_GET_ITEM(py_fds_to_keep, i);
160n/a long fd = PyLong_AsLong(fdobj);
161n/a assert(!PyErr_Occurred());
162n/a assert(0 <= fd && fd <= INT_MAX);
163n/a if (fd == errpipe_write) {
164n/a /* errpipe_write is part of py_fds_to_keep. It must be closed at
165n/a exec(), but kept open in the child process until exec() is
166n/a called. */
167n/a continue;
168n/a }
169n/a if (_Py_set_inheritable((int)fd, 1, NULL) < 0)
170n/a return -1;
171n/a }
172n/a return 0;
173n/a}
174n/a
175n/a
176n/a/* Get the maximum file descriptor that could be opened by this process.
177n/a * This function is async signal safe for use between fork() and exec().
178n/a */
179n/astatic long
180n/asafe_get_max_fd(void)
181n/a{
182n/a long local_max_fd;
183n/a#if defined(__NetBSD__)
184n/a local_max_fd = fcntl(0, F_MAXFD);
185n/a if (local_max_fd >= 0)
186n/a return local_max_fd;
187n/a#endif
188n/a#if defined(HAVE_SYS_RESOURCE_H) && defined(__OpenBSD__)
189n/a struct rlimit rl;
190n/a /* Not on the POSIX async signal safe functions list but likely
191n/a * safe. TODO - Someone should audit OpenBSD to make sure. */
192n/a if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
193n/a return (long) rl.rlim_max;
194n/a#endif
195n/a#ifdef _SC_OPEN_MAX
196n/a local_max_fd = sysconf(_SC_OPEN_MAX);
197n/a if (local_max_fd == -1)
198n/a#endif
199n/a local_max_fd = 256; /* Matches legacy Lib/subprocess.py behavior. */
200n/a return local_max_fd;
201n/a}
202n/a
203n/a
204n/a/* Close all file descriptors in the range from start_fd and higher
205n/a * except for those in py_fds_to_keep. If the range defined by
206n/a * [start_fd, safe_get_max_fd()) is large this will take a long
207n/a * time as it calls close() on EVERY possible fd.
208n/a *
209n/a * It isn't possible to know for sure what the max fd to go up to
210n/a * is for processes with the capability of raising their maximum.
211n/a */
212n/astatic void
213n/a_close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep)
214n/a{
215n/a long end_fd = safe_get_max_fd();
216n/a Py_ssize_t num_fds_to_keep = PySequence_Length(py_fds_to_keep);
217n/a Py_ssize_t keep_seq_idx;
218n/a int fd_num;
219n/a /* As py_fds_to_keep is sorted we can loop through the list closing
220n/a * fds inbetween any in the keep list falling within our range. */
221n/a for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) {
222n/a PyObject* py_keep_fd = PySequence_Fast_GET_ITEM(py_fds_to_keep,
223n/a keep_seq_idx);
224n/a int keep_fd = PyLong_AsLong(py_keep_fd);
225n/a if (keep_fd < start_fd)
226n/a continue;
227n/a for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) {
228n/a close(fd_num);
229n/a }
230n/a start_fd = keep_fd + 1;
231n/a }
232n/a if (start_fd <= end_fd) {
233n/a for (fd_num = start_fd; fd_num < end_fd; ++fd_num) {
234n/a close(fd_num);
235n/a }
236n/a }
237n/a}
238n/a
239n/a
240n/a#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
241n/a/* It doesn't matter if d_name has room for NAME_MAX chars; we're using this
242n/a * only to read a directory of short file descriptor number names. The kernel
243n/a * will return an error if we didn't give it enough space. Highly Unlikely.
244n/a * This structure is very old and stable: It will not change unless the kernel
245n/a * chooses to break compatibility with all existing binaries. Highly Unlikely.
246n/a */
247n/astruct linux_dirent64 {
248n/a unsigned long long d_ino;
249n/a long long d_off;
250n/a unsigned short d_reclen; /* Length of this linux_dirent */
251n/a unsigned char d_type;
252n/a char d_name[256]; /* Filename (null-terminated) */
253n/a};
254n/a
255n/a/* Close all open file descriptors in the range from start_fd and higher
256n/a * Do not close any in the sorted py_fds_to_keep list.
257n/a *
258n/a * This version is async signal safe as it does not make any unsafe C library
259n/a * calls, malloc calls or handle any locks. It is _unfortunate_ to be forced
260n/a * to resort to making a kernel system call directly but this is the ONLY api
261n/a * available that does no harm. opendir/readdir/closedir perform memory
262n/a * allocation and locking so while they usually work they are not guaranteed
263n/a * to (especially if you have replaced your malloc implementation). A version
264n/a * of this function that uses those can be found in the _maybe_unsafe variant.
265n/a *
266n/a * This is Linux specific because that is all I am ready to test it on. It
267n/a * should be easy to add OS specific dirent or dirent64 structures and modify
268n/a * it with some cpp #define magic to work on other OSes as well if you want.
269n/a */
270n/astatic void
271n/a_close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep)
272n/a{
273n/a int fd_dir_fd;
274n/a
275n/a fd_dir_fd = _Py_open_noraise(FD_DIR, O_RDONLY);
276n/a if (fd_dir_fd == -1) {
277n/a /* No way to get a list of open fds. */
278n/a _close_fds_by_brute_force(start_fd, py_fds_to_keep);
279n/a return;
280n/a } else {
281n/a char buffer[sizeof(struct linux_dirent64)];
282n/a int bytes;
283n/a while ((bytes = syscall(SYS_getdents64, fd_dir_fd,
284n/a (struct linux_dirent64 *)buffer,
285n/a sizeof(buffer))) > 0) {
286n/a struct linux_dirent64 *entry;
287n/a int offset;
288n/a for (offset = 0; offset < bytes; offset += entry->d_reclen) {
289n/a int fd;
290n/a entry = (struct linux_dirent64 *)(buffer + offset);
291n/a if ((fd = _pos_int_from_ascii(entry->d_name)) < 0)
292n/a continue; /* Not a number. */
293n/a if (fd != fd_dir_fd && fd >= start_fd &&
294n/a !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) {
295n/a close(fd);
296n/a }
297n/a }
298n/a }
299n/a close(fd_dir_fd);
300n/a }
301n/a}
302n/a
303n/a#define _close_open_fds _close_open_fds_safe
304n/a
305n/a#else /* NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */
306n/a
307n/a
308n/a/* Close all open file descriptors from start_fd and higher.
309n/a * Do not close any in the sorted py_fds_to_keep list.
310n/a *
311n/a * This function violates the strict use of async signal safe functions. :(
312n/a * It calls opendir(), readdir() and closedir(). Of these, the one most
313n/a * likely to ever cause a problem is opendir() as it performs an internal
314n/a * malloc(). Practically this should not be a problem. The Java VM makes the
315n/a * same calls between fork and exec in its own UNIXProcess_md.c implementation.
316n/a *
317n/a * readdir_r() is not used because it provides no benefit. It is typically
318n/a * implemented as readdir() followed by memcpy(). See also:
319n/a * http://womble.decadent.org.uk/readdir_r-advisory.html
320n/a */
321n/astatic void
322n/a_close_open_fds_maybe_unsafe(long start_fd, PyObject* py_fds_to_keep)
323n/a{
324n/a DIR *proc_fd_dir;
325n/a#ifndef HAVE_DIRFD
326n/a while (_is_fd_in_sorted_fd_sequence(start_fd, py_fds_to_keep)) {
327n/a ++start_fd;
328n/a }
329n/a /* Close our lowest fd before we call opendir so that it is likely to
330n/a * reuse that fd otherwise we might close opendir's file descriptor in
331n/a * our loop. This trick assumes that fd's are allocated on a lowest
332n/a * available basis. */
333n/a close(start_fd);
334n/a ++start_fd;
335n/a#endif
336n/a
337n/a#if defined(__FreeBSD__)
338n/a if (!_is_fdescfs_mounted_on_dev_fd())
339n/a proc_fd_dir = NULL;
340n/a else
341n/a#endif
342n/a proc_fd_dir = opendir(FD_DIR);
343n/a if (!proc_fd_dir) {
344n/a /* No way to get a list of open fds. */
345n/a _close_fds_by_brute_force(start_fd, py_fds_to_keep);
346n/a } else {
347n/a struct dirent *dir_entry;
348n/a#ifdef HAVE_DIRFD
349n/a int fd_used_by_opendir = dirfd(proc_fd_dir);
350n/a#else
351n/a int fd_used_by_opendir = start_fd - 1;
352n/a#endif
353n/a errno = 0;
354n/a while ((dir_entry = readdir(proc_fd_dir))) {
355n/a int fd;
356n/a if ((fd = _pos_int_from_ascii(dir_entry->d_name)) < 0)
357n/a continue; /* Not a number. */
358n/a if (fd != fd_used_by_opendir && fd >= start_fd &&
359n/a !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) {
360n/a close(fd);
361n/a }
362n/a errno = 0;
363n/a }
364n/a if (errno) {
365n/a /* readdir error, revert behavior. Highly Unlikely. */
366n/a _close_fds_by_brute_force(start_fd, py_fds_to_keep);
367n/a }
368n/a closedir(proc_fd_dir);
369n/a }
370n/a}
371n/a
372n/a#define _close_open_fds _close_open_fds_maybe_unsafe
373n/a
374n/a#endif /* else NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */
375n/a
376n/a
377n/a/*
378n/a * This function is code executed in the child process immediately after fork
379n/a * to set things up and call exec().
380n/a *
381n/a * All of the code in this function must only use async-signal-safe functions,
382n/a * listed at `man 7 signal` or
383n/a * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
384n/a *
385n/a * This restriction is documented at
386n/a * http://www.opengroup.org/onlinepubs/009695399/functions/fork.html.
387n/a */
388n/astatic void
389n/achild_exec(char *const exec_array[],
390n/a char *const argv[],
391n/a char *const envp[],
392n/a const char *cwd,
393n/a int p2cread, int p2cwrite,
394n/a int c2pread, int c2pwrite,
395n/a int errread, int errwrite,
396n/a int errpipe_read, int errpipe_write,
397n/a int close_fds, int restore_signals,
398n/a int call_setsid,
399n/a PyObject *py_fds_to_keep,
400n/a PyObject *preexec_fn,
401n/a PyObject *preexec_fn_args_tuple)
402n/a{
403n/a int i, saved_errno, reached_preexec = 0;
404n/a PyObject *result;
405n/a const char* err_msg = "";
406n/a /* Buffer large enough to hold a hex integer. We can't malloc. */
407n/a char hex_errno[sizeof(saved_errno)*2+1];
408n/a
409n/a if (make_inheritable(py_fds_to_keep, errpipe_write) < 0)
410n/a goto error;
411n/a
412n/a /* Close parent's pipe ends. */
413n/a if (p2cwrite != -1)
414n/a POSIX_CALL(close(p2cwrite));
415n/a if (c2pread != -1)
416n/a POSIX_CALL(close(c2pread));
417n/a if (errread != -1)
418n/a POSIX_CALL(close(errread));
419n/a POSIX_CALL(close(errpipe_read));
420n/a
421n/a /* When duping fds, if there arises a situation where one of the fds is
422n/a either 0, 1 or 2, it is possible that it is overwritten (#12607). */
423n/a if (c2pwrite == 0)
424n/a POSIX_CALL(c2pwrite = dup(c2pwrite));
425n/a if (errwrite == 0 || errwrite == 1)
426n/a POSIX_CALL(errwrite = dup(errwrite));
427n/a
428n/a /* Dup fds for child.
429n/a dup2() removes the CLOEXEC flag but we must do it ourselves if dup2()
430n/a would be a no-op (issue #10806). */
431n/a if (p2cread == 0) {
432n/a if (_Py_set_inheritable(p2cread, 1, NULL) < 0)
433n/a goto error;
434n/a }
435n/a else if (p2cread != -1)
436n/a POSIX_CALL(dup2(p2cread, 0)); /* stdin */
437n/a
438n/a if (c2pwrite == 1) {
439n/a if (_Py_set_inheritable(c2pwrite, 1, NULL) < 0)
440n/a goto error;
441n/a }
442n/a else if (c2pwrite != -1)
443n/a POSIX_CALL(dup2(c2pwrite, 1)); /* stdout */
444n/a
445n/a if (errwrite == 2) {
446n/a if (_Py_set_inheritable(errwrite, 1, NULL) < 0)
447n/a goto error;
448n/a }
449n/a else if (errwrite != -1)
450n/a POSIX_CALL(dup2(errwrite, 2)); /* stderr */
451n/a
452n/a /* Close pipe fds. Make sure we don't close the same fd more than */
453n/a /* once, or standard fds. */
454n/a if (p2cread > 2)
455n/a POSIX_CALL(close(p2cread));
456n/a if (c2pwrite > 2 && c2pwrite != p2cread)
457n/a POSIX_CALL(close(c2pwrite));
458n/a if (errwrite != c2pwrite && errwrite != p2cread && errwrite > 2)
459n/a POSIX_CALL(close(errwrite));
460n/a
461n/a if (cwd)
462n/a POSIX_CALL(chdir(cwd));
463n/a
464n/a if (restore_signals)
465n/a _Py_RestoreSignals();
466n/a
467n/a#ifdef HAVE_SETSID
468n/a if (call_setsid)
469n/a POSIX_CALL(setsid());
470n/a#endif
471n/a
472n/a reached_preexec = 1;
473n/a if (preexec_fn != Py_None && preexec_fn_args_tuple) {
474n/a /* This is where the user has asked us to deadlock their program. */
475n/a result = PyObject_Call(preexec_fn, preexec_fn_args_tuple, NULL);
476n/a if (result == NULL) {
477n/a /* Stringifying the exception or traceback would involve
478n/a * memory allocation and thus potential for deadlock.
479n/a * We've already faced potential deadlock by calling back
480n/a * into Python in the first place, so it probably doesn't
481n/a * matter but we avoid it to minimize the possibility. */
482n/a err_msg = "Exception occurred in preexec_fn.";
483n/a errno = 0; /* We don't want to report an OSError. */
484n/a goto error;
485n/a }
486n/a /* Py_DECREF(result); - We're about to exec so why bother? */
487n/a }
488n/a
489n/a /* close FDs after executing preexec_fn, which might open FDs */
490n/a if (close_fds) {
491n/a /* TODO HP-UX could use pstat_getproc() if anyone cares about it. */
492n/a _close_open_fds(3, py_fds_to_keep);
493n/a }
494n/a
495n/a /* This loop matches the Lib/os.py _execvpe()'s PATH search when */
496n/a /* given the executable_list generated by Lib/subprocess.py. */
497n/a saved_errno = 0;
498n/a for (i = 0; exec_array[i] != NULL; ++i) {
499n/a const char *executable = exec_array[i];
500n/a if (envp) {
501n/a execve(executable, argv, envp);
502n/a } else {
503n/a execv(executable, argv);
504n/a }
505n/a if (errno != ENOENT && errno != ENOTDIR && saved_errno == 0) {
506n/a saved_errno = errno;
507n/a }
508n/a }
509n/a /* Report the first exec error, not the last. */
510n/a if (saved_errno)
511n/a errno = saved_errno;
512n/a
513n/aerror:
514n/a saved_errno = errno;
515n/a /* Report the posix error to our parent process. */
516n/a /* We ignore all write() return values as the total size of our writes is
517n/a less than PIPEBUF and we cannot do anything about an error anyways.
518n/a Use _Py_write_noraise() to retry write() if it is interrupted by a
519n/a signal (fails with EINTR). */
520n/a if (saved_errno) {
521n/a char *cur;
522n/a _Py_write_noraise(errpipe_write, "OSError:", 8);
523n/a cur = hex_errno + sizeof(hex_errno);
524n/a while (saved_errno != 0 && cur != hex_errno) {
525n/a *--cur = Py_hexdigits[saved_errno % 16];
526n/a saved_errno /= 16;
527n/a }
528n/a _Py_write_noraise(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur);
529n/a _Py_write_noraise(errpipe_write, ":", 1);
530n/a if (!reached_preexec) {
531n/a /* Indicate to the parent that the error happened before exec(). */
532n/a _Py_write_noraise(errpipe_write, "noexec", 6);
533n/a }
534n/a /* We can't call strerror(saved_errno). It is not async signal safe.
535n/a * The parent process will look the error message up. */
536n/a } else {
537n/a _Py_write_noraise(errpipe_write, "SubprocessError:0:", 18);
538n/a _Py_write_noraise(errpipe_write, err_msg, strlen(err_msg));
539n/a }
540n/a}
541n/a
542n/a
543n/astatic PyObject *
544n/asubprocess_fork_exec(PyObject* self, PyObject *args)
545n/a{
546n/a PyObject *gc_module = NULL;
547n/a PyObject *executable_list, *py_fds_to_keep;
548n/a PyObject *env_list, *preexec_fn;
549n/a PyObject *process_args, *converted_args = NULL, *fast_args = NULL;
550n/a PyObject *preexec_fn_args_tuple = NULL;
551n/a int p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite;
552n/a int errpipe_read, errpipe_write, close_fds, restore_signals;
553n/a int call_setsid;
554n/a PyObject *cwd_obj, *cwd_obj2;
555n/a const char *cwd;
556n/a pid_t pid;
557n/a int need_to_reenable_gc = 0;
558n/a char *const *exec_array, *const *argv = NULL, *const *envp = NULL;
559n/a Py_ssize_t arg_num;
560n/a#ifdef WITH_THREAD
561n/a int import_lock_held = 0;
562n/a#endif
563n/a
564n/a if (!PyArg_ParseTuple(
565n/a args, "OOpOOOiiiiiiiiiiO:fork_exec",
566n/a &process_args, &executable_list, &close_fds, &py_fds_to_keep,
567n/a &cwd_obj, &env_list,
568n/a &p2cread, &p2cwrite, &c2pread, &c2pwrite,
569n/a &errread, &errwrite, &errpipe_read, &errpipe_write,
570n/a &restore_signals, &call_setsid, &preexec_fn))
571n/a return NULL;
572n/a
573n/a if (close_fds && errpipe_write < 3) { /* precondition */
574n/a PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3");
575n/a return NULL;
576n/a }
577n/a if (PySequence_Length(py_fds_to_keep) < 0) {
578n/a PyErr_SetString(PyExc_ValueError, "cannot get length of fds_to_keep");
579n/a return NULL;
580n/a }
581n/a if (_sanity_check_python_fd_sequence(py_fds_to_keep)) {
582n/a PyErr_SetString(PyExc_ValueError, "bad value(s) in fds_to_keep");
583n/a return NULL;
584n/a }
585n/a
586n/a /* We need to call gc.disable() when we'll be calling preexec_fn */
587n/a if (preexec_fn != Py_None) {
588n/a PyObject *result;
589n/a _Py_IDENTIFIER(isenabled);
590n/a _Py_IDENTIFIER(disable);
591n/a
592n/a gc_module = PyImport_ImportModule("gc");
593n/a if (gc_module == NULL)
594n/a return NULL;
595n/a result = _PyObject_CallMethodId(gc_module, &PyId_isenabled, NULL);
596n/a if (result == NULL) {
597n/a Py_DECREF(gc_module);
598n/a return NULL;
599n/a }
600n/a need_to_reenable_gc = PyObject_IsTrue(result);
601n/a Py_DECREF(result);
602n/a if (need_to_reenable_gc == -1) {
603n/a Py_DECREF(gc_module);
604n/a return NULL;
605n/a }
606n/a result = _PyObject_CallMethodId(gc_module, &PyId_disable, NULL);
607n/a if (result == NULL) {
608n/a Py_DECREF(gc_module);
609n/a return NULL;
610n/a }
611n/a Py_DECREF(result);
612n/a }
613n/a
614n/a exec_array = _PySequence_BytesToCharpArray(executable_list);
615n/a if (!exec_array)
616n/a goto cleanup;
617n/a
618n/a /* Convert args and env into appropriate arguments for exec() */
619n/a /* These conversions are done in the parent process to avoid allocating
620n/a or freeing memory in the child process. */
621n/a if (process_args != Py_None) {
622n/a Py_ssize_t num_args;
623n/a /* Equivalent to: */
624n/a /* tuple(PyUnicode_FSConverter(arg) for arg in process_args) */
625n/a fast_args = PySequence_Fast(process_args, "argv must be a tuple");
626n/a if (fast_args == NULL)
627n/a goto cleanup;
628n/a num_args = PySequence_Fast_GET_SIZE(fast_args);
629n/a converted_args = PyTuple_New(num_args);
630n/a if (converted_args == NULL)
631n/a goto cleanup;
632n/a for (arg_num = 0; arg_num < num_args; ++arg_num) {
633n/a PyObject *borrowed_arg, *converted_arg;
634n/a borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num);
635n/a if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0)
636n/a goto cleanup;
637n/a PyTuple_SET_ITEM(converted_args, arg_num, converted_arg);
638n/a }
639n/a
640n/a argv = _PySequence_BytesToCharpArray(converted_args);
641n/a Py_CLEAR(converted_args);
642n/a Py_CLEAR(fast_args);
643n/a if (!argv)
644n/a goto cleanup;
645n/a }
646n/a
647n/a if (env_list != Py_None) {
648n/a envp = _PySequence_BytesToCharpArray(env_list);
649n/a if (!envp)
650n/a goto cleanup;
651n/a }
652n/a
653n/a if (preexec_fn != Py_None) {
654n/a preexec_fn_args_tuple = PyTuple_New(0);
655n/a if (!preexec_fn_args_tuple)
656n/a goto cleanup;
657n/a#ifdef WITH_THREAD
658n/a _PyImport_AcquireLock();
659n/a import_lock_held = 1;
660n/a#endif
661n/a }
662n/a
663n/a if (cwd_obj != Py_None) {
664n/a if (PyUnicode_FSConverter(cwd_obj, &cwd_obj2) == 0)
665n/a goto cleanup;
666n/a cwd = PyBytes_AsString(cwd_obj2);
667n/a } else {
668n/a cwd = NULL;
669n/a cwd_obj2 = NULL;
670n/a }
671n/a
672n/a pid = fork();
673n/a if (pid == 0) {
674n/a /* Child process */
675n/a /*
676n/a * Code from here to _exit() must only use async-signal-safe functions,
677n/a * listed at `man 7 signal` or
678n/a * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
679n/a */
680n/a
681n/a if (preexec_fn != Py_None) {
682n/a /* We'll be calling back into Python later so we need to do this.
683n/a * This call may not be async-signal-safe but neither is calling
684n/a * back into Python. The user asked us to use hope as a strategy
685n/a * to avoid deadlock... */
686n/a PyOS_AfterFork();
687n/a }
688n/a
689n/a child_exec(exec_array, argv, envp, cwd,
690n/a p2cread, p2cwrite, c2pread, c2pwrite,
691n/a errread, errwrite, errpipe_read, errpipe_write,
692n/a close_fds, restore_signals, call_setsid,
693n/a py_fds_to_keep, preexec_fn, preexec_fn_args_tuple);
694n/a _exit(255);
695n/a return NULL; /* Dead code to avoid a potential compiler warning. */
696n/a }
697n/a Py_XDECREF(cwd_obj2);
698n/a
699n/a if (pid == -1) {
700n/a /* Capture the errno exception before errno can be clobbered. */
701n/a PyErr_SetFromErrno(PyExc_OSError);
702n/a }
703n/a#ifdef WITH_THREAD
704n/a if (preexec_fn != Py_None
705n/a && _PyImport_ReleaseLock() < 0 && !PyErr_Occurred()) {
706n/a PyErr_SetString(PyExc_RuntimeError,
707n/a "not holding the import lock");
708n/a pid = -1;
709n/a }
710n/a import_lock_held = 0;
711n/a#endif
712n/a
713n/a /* Parent process */
714n/a if (envp)
715n/a _Py_FreeCharPArray(envp);
716n/a if (argv)
717n/a _Py_FreeCharPArray(argv);
718n/a _Py_FreeCharPArray(exec_array);
719n/a
720n/a /* Reenable gc in the parent process (or if fork failed). */
721n/a if (_enable_gc(need_to_reenable_gc, gc_module)) {
722n/a pid = -1;
723n/a }
724n/a Py_XDECREF(preexec_fn_args_tuple);
725n/a Py_XDECREF(gc_module);
726n/a
727n/a if (pid == -1)
728n/a return NULL; /* fork() failed. Exception set earlier. */
729n/a
730n/a return PyLong_FromPid(pid);
731n/a
732n/acleanup:
733n/a#ifdef WITH_THREAD
734n/a if (import_lock_held)
735n/a _PyImport_ReleaseLock();
736n/a#endif
737n/a if (envp)
738n/a _Py_FreeCharPArray(envp);
739n/a if (argv)
740n/a _Py_FreeCharPArray(argv);
741n/a if (exec_array)
742n/a _Py_FreeCharPArray(exec_array);
743n/a Py_XDECREF(converted_args);
744n/a Py_XDECREF(fast_args);
745n/a Py_XDECREF(preexec_fn_args_tuple);
746n/a _enable_gc(need_to_reenable_gc, gc_module);
747n/a Py_XDECREF(gc_module);
748n/a return NULL;
749n/a}
750n/a
751n/a
752n/aPyDoc_STRVAR(subprocess_fork_exec_doc,
753n/a"fork_exec(args, executable_list, close_fds, cwd, env,\n\
754n/a p2cread, p2cwrite, c2pread, c2pwrite,\n\
755n/a errread, errwrite, errpipe_read, errpipe_write,\n\
756n/a restore_signals, call_setsid, preexec_fn)\n\
757n/a\n\
758n/aForks a child process, closes parent file descriptors as appropriate in the\n\
759n/achild and dups the few that are needed before calling exec() in the child\n\
760n/aprocess.\n\
761n/a\n\
762n/aThe preexec_fn, if supplied, will be called immediately before exec.\n\
763n/aWARNING: preexec_fn is NOT SAFE if your application uses threads.\n\
764n/a It may trigger infrequent, difficult to debug deadlocks.\n\
765n/a\n\
766n/aIf an error occurs in the child process before the exec, it is\n\
767n/aserialized and written to the errpipe_write fd per subprocess.py.\n\
768n/a\n\
769n/aReturns: the child process's PID.\n\
770n/a\n\
771n/aRaises: Only on an error in the parent process.\n\
772n/a");
773n/a
774n/a/* module level code ********************************************************/
775n/a
776n/aPyDoc_STRVAR(module_doc,
777n/a"A POSIX helper for the subprocess module.");
778n/a
779n/a
780n/astatic PyMethodDef module_methods[] = {
781n/a {"fork_exec", subprocess_fork_exec, METH_VARARGS, subprocess_fork_exec_doc},
782n/a {NULL, NULL} /* sentinel */
783n/a};
784n/a
785n/a
786n/astatic struct PyModuleDef _posixsubprocessmodule = {
787n/a PyModuleDef_HEAD_INIT,
788n/a "_posixsubprocess",
789n/a module_doc,
790n/a -1, /* No memory is needed. */
791n/a module_methods,
792n/a};
793n/a
794n/aPyMODINIT_FUNC
795n/aPyInit__posixsubprocess(void)
796n/a{
797n/a return PyModule_Create(&_posixsubprocessmodule);
798n/a}