Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/cpython
Path: blob/main/Modules/_posixsubprocess.c
12 views
1
/* Authors: Gregory P. Smith & Jeffrey Yasskin */
2
#ifndef Py_BUILD_CORE_BUILTIN
3
# define Py_BUILD_CORE_MODULE 1
4
#endif
5
6
#include "Python.h"
7
#include "pycore_fileutils.h"
8
#include "pycore_pystate.h"
9
#if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE)
10
# define _GNU_SOURCE
11
#endif
12
#include <unistd.h>
13
#include <fcntl.h>
14
#ifdef HAVE_SYS_TYPES_H
15
#include <sys/types.h>
16
#endif
17
#if defined(HAVE_SYS_STAT_H)
18
#include <sys/stat.h>
19
#endif
20
#ifdef HAVE_SYS_SYSCALL_H
21
#include <sys/syscall.h>
22
#endif
23
#if defined(HAVE_SYS_RESOURCE_H)
24
#include <sys/resource.h>
25
#endif
26
#ifdef HAVE_DIRENT_H
27
#include <dirent.h>
28
#endif
29
#ifdef HAVE_GRP_H
30
#include <grp.h>
31
#endif /* HAVE_GRP_H */
32
33
#include "posixmodule.h"
34
35
#ifdef _Py_MEMORY_SANITIZER
36
# include <sanitizer/msan_interface.h>
37
#endif
38
39
#if defined(__ANDROID__) && __ANDROID_API__ < 21 && !defined(SYS_getdents64)
40
# include <sys/linux-syscalls.h>
41
# define SYS_getdents64 __NR_getdents64
42
#endif
43
44
#if defined(__linux__) && defined(HAVE_VFORK) && defined(HAVE_SIGNAL_H) && \
45
defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
46
/* If this is ever expanded to non-Linux platforms, verify what calls are
47
* allowed after vfork(). Ex: setsid() may be disallowed on macOS? */
48
# include <signal.h>
49
# define VFORK_USABLE 1
50
#endif
51
52
#if defined(__sun) && defined(__SVR4)
53
/* readdir64 is used to work around Solaris 9 bug 6395699. */
54
# define readdir readdir64
55
# define dirent dirent64
56
# if !defined(HAVE_DIRFD)
57
/* Some versions of Solaris lack dirfd(). */
58
# define dirfd(dirp) ((dirp)->dd_fd)
59
# define HAVE_DIRFD
60
# endif
61
#endif
62
63
#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__DragonFly__)
64
# define FD_DIR "/dev/fd"
65
#else
66
# define FD_DIR "/proc/self/fd"
67
#endif
68
69
#ifdef NGROUPS_MAX
70
#define MAX_GROUPS NGROUPS_MAX
71
#else
72
#define MAX_GROUPS 64
73
#endif
74
75
#define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0)
76
77
static struct PyModuleDef _posixsubprocessmodule;
78
79
/*[clinic input]
80
module _posixsubprocess
81
[clinic start generated code]*/
82
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c62211df27cf7334]*/
83
84
/*[python input]
85
class pid_t_converter(CConverter):
86
type = 'pid_t'
87
format_unit = '" _Py_PARSE_PID "'
88
89
def parse_arg(self, argname, displayname):
90
return """
91
{paramname} = PyLong_AsPid({argname});
92
if ({paramname} == -1 && PyErr_Occurred()) {{{{
93
goto exit;
94
}}}}
95
""".format(argname=argname, paramname=self.parser_name)
96
[python start generated code]*/
97
/*[python end generated code: output=da39a3ee5e6b4b0d input=5af1c116d56cbb5a]*/
98
99
#include "clinic/_posixsubprocess.c.h"
100
101
/* Convert ASCII to a positive int, no libc call. no overflow. -1 on error. */
102
static int
103
_pos_int_from_ascii(const char *name)
104
{
105
int num = 0;
106
while (*name >= '0' && *name <= '9') {
107
num = num * 10 + (*name - '0');
108
++name;
109
}
110
if (*name)
111
return -1; /* Non digit found, not a number. */
112
return num;
113
}
114
115
116
#if defined(__FreeBSD__) || defined(__DragonFly__)
117
/* When /dev/fd isn't mounted it is often a static directory populated
118
* with 0 1 2 or entries for 0 .. 63 on FreeBSD, NetBSD, OpenBSD and DragonFlyBSD.
119
* NetBSD and OpenBSD have a /proc fs available (though not necessarily
120
* mounted) and do not have fdescfs for /dev/fd. MacOS X has a devfs
121
* that properly supports /dev/fd.
122
*/
123
static int
124
_is_fdescfs_mounted_on_dev_fd(void)
125
{
126
struct stat dev_stat;
127
struct stat dev_fd_stat;
128
if (stat("/dev", &dev_stat) != 0)
129
return 0;
130
if (stat(FD_DIR, &dev_fd_stat) != 0)
131
return 0;
132
if (dev_stat.st_dev == dev_fd_stat.st_dev)
133
return 0; /* / == /dev == /dev/fd means it is static. #fail */
134
return 1;
135
}
136
#endif
137
138
139
/* Returns 1 if there is a problem with fd_sequence, 0 otherwise. */
140
static int
141
_sanity_check_python_fd_sequence(PyObject *fd_sequence)
142
{
143
Py_ssize_t seq_idx;
144
long prev_fd = -1;
145
for (seq_idx = 0; seq_idx < PyTuple_GET_SIZE(fd_sequence); ++seq_idx) {
146
PyObject* py_fd = PyTuple_GET_ITEM(fd_sequence, seq_idx);
147
long iter_fd;
148
if (!PyLong_Check(py_fd)) {
149
return 1;
150
}
151
iter_fd = PyLong_AsLong(py_fd);
152
if (iter_fd < 0 || iter_fd <= prev_fd || iter_fd > INT_MAX) {
153
/* Negative, overflow, unsorted, too big for a fd. */
154
return 1;
155
}
156
prev_fd = iter_fd;
157
}
158
return 0;
159
}
160
161
162
/* Is fd found in the sorted Python Sequence? */
163
static int
164
_is_fd_in_sorted_fd_sequence(int fd, int *fd_sequence,
165
Py_ssize_t fd_sequence_len)
166
{
167
/* Binary search. */
168
Py_ssize_t search_min = 0;
169
Py_ssize_t search_max = fd_sequence_len - 1;
170
if (search_max < 0)
171
return 0;
172
do {
173
long middle = (search_min + search_max) / 2;
174
long middle_fd = fd_sequence[middle];
175
if (fd == middle_fd)
176
return 1;
177
if (fd > middle_fd)
178
search_min = middle + 1;
179
else
180
search_max = middle - 1;
181
} while (search_min <= search_max);
182
return 0;
183
}
184
185
186
// Forward declaration
187
static void _Py_FreeCharPArray(char *const array[]);
188
189
/*
190
* Flatten a sequence of bytes() objects into a C array of
191
* NULL terminated string pointers with a NULL char* terminating the array.
192
* (ie: an argv or env list)
193
*
194
* Memory allocated for the returned list is allocated using PyMem_Malloc()
195
* and MUST be freed by _Py_FreeCharPArray().
196
*/
197
static char *const *
198
_PySequence_BytesToCharpArray(PyObject* self)
199
{
200
char **array;
201
Py_ssize_t i, argc;
202
PyObject *item = NULL;
203
Py_ssize_t size;
204
205
argc = PySequence_Size(self);
206
if (argc == -1)
207
return NULL;
208
209
assert(argc >= 0);
210
211
if ((size_t)argc > (PY_SSIZE_T_MAX-sizeof(char *)) / sizeof(char *)) {
212
PyErr_NoMemory();
213
return NULL;
214
}
215
216
array = PyMem_Malloc((argc + 1) * sizeof(char *));
217
if (array == NULL) {
218
PyErr_NoMemory();
219
return NULL;
220
}
221
for (i = 0; i < argc; ++i) {
222
char *data;
223
item = PySequence_GetItem(self, i);
224
if (item == NULL) {
225
/* NULL terminate before freeing. */
226
array[i] = NULL;
227
goto fail;
228
}
229
/* check for embedded null bytes */
230
if (PyBytes_AsStringAndSize(item, &data, NULL) < 0) {
231
/* NULL terminate before freeing. */
232
array[i] = NULL;
233
goto fail;
234
}
235
size = PyBytes_GET_SIZE(item) + 1;
236
array[i] = PyMem_Malloc(size);
237
if (!array[i]) {
238
PyErr_NoMemory();
239
goto fail;
240
}
241
memcpy(array[i], data, size);
242
Py_DECREF(item);
243
}
244
array[argc] = NULL;
245
246
return array;
247
248
fail:
249
Py_XDECREF(item);
250
_Py_FreeCharPArray(array);
251
return NULL;
252
}
253
254
255
/* Free's a NULL terminated char** array of C strings. */
256
static void
257
_Py_FreeCharPArray(char *const array[])
258
{
259
Py_ssize_t i;
260
for (i = 0; array[i] != NULL; ++i) {
261
PyMem_Free(array[i]);
262
}
263
PyMem_Free((void*)array);
264
}
265
266
267
/*
268
* Do all the Python C API calls in the parent process to turn the pass_fds
269
* "py_fds_to_keep" tuple into a C array. The caller owns allocation and
270
* freeing of the array.
271
*
272
* On error an unknown number of array elements may have been filled in.
273
* A Python exception has been set when an error is returned.
274
*
275
* Returns: -1 on error, 0 on success.
276
*/
277
static int
278
convert_fds_to_keep_to_c(PyObject *py_fds_to_keep, int *c_fds_to_keep)
279
{
280
Py_ssize_t i, len;
281
282
len = PyTuple_GET_SIZE(py_fds_to_keep);
283
for (i = 0; i < len; ++i) {
284
PyObject* fdobj = PyTuple_GET_ITEM(py_fds_to_keep, i);
285
long fd = PyLong_AsLong(fdobj);
286
if (fd == -1 && PyErr_Occurred()) {
287
return -1;
288
}
289
if (fd < 0 || fd > INT_MAX) {
290
PyErr_SetString(PyExc_ValueError,
291
"fd out of range in fds_to_keep.");
292
return -1;
293
}
294
c_fds_to_keep[i] = (int)fd;
295
}
296
return 0;
297
}
298
299
300
/* This function must be async-signal-safe as it is called from child_exec()
301
* after fork() or vfork().
302
*/
303
static int
304
make_inheritable(int *c_fds_to_keep, Py_ssize_t len, int errpipe_write)
305
{
306
Py_ssize_t i;
307
308
for (i = 0; i < len; ++i) {
309
int fd = c_fds_to_keep[i];
310
if (fd == errpipe_write) {
311
/* errpipe_write is part of fds_to_keep. It must be closed at
312
exec(), but kept open in the child process until exec() is
313
called. */
314
continue;
315
}
316
if (_Py_set_inheritable_async_safe(fd, 1, NULL) < 0)
317
return -1;
318
}
319
return 0;
320
}
321
322
323
/* Get the maximum file descriptor that could be opened by this process.
324
* This function is async signal safe for use between fork() and exec().
325
*/
326
static long
327
safe_get_max_fd(void)
328
{
329
long local_max_fd;
330
#if defined(__NetBSD__)
331
local_max_fd = fcntl(0, F_MAXFD);
332
if (local_max_fd >= 0)
333
return local_max_fd;
334
#endif
335
#if defined(HAVE_SYS_RESOURCE_H) && defined(__OpenBSD__)
336
struct rlimit rl;
337
/* Not on the POSIX async signal safe functions list but likely
338
* safe. TODO - Someone should audit OpenBSD to make sure. */
339
if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
340
return (long) rl.rlim_max;
341
#endif
342
#ifdef _SC_OPEN_MAX
343
local_max_fd = sysconf(_SC_OPEN_MAX);
344
if (local_max_fd == -1)
345
#endif
346
local_max_fd = 256; /* Matches legacy Lib/subprocess.py behavior. */
347
return local_max_fd;
348
}
349
350
351
/* Close all file descriptors in the given range except for those in
352
* fds_to_keep by invoking closer on each subrange.
353
*
354
* If end_fd == -1, it's guessed via safe_get_max_fd(), but it isn't
355
* possible to know for sure what the max fd to go up to is for
356
* processes with the capability of raising their maximum, or in case
357
* a process opened a high fd and then lowered its maximum.
358
*/
359
static int
360
_close_range_except(int start_fd,
361
int end_fd,
362
int *fds_to_keep,
363
Py_ssize_t fds_to_keep_len,
364
int (*closer)(int, int))
365
{
366
if (end_fd == -1) {
367
end_fd = Py_MIN(safe_get_max_fd(), INT_MAX);
368
}
369
Py_ssize_t keep_seq_idx;
370
/* As fds_to_keep is sorted we can loop through the list closing
371
* fds in between any in the keep list falling within our range. */
372
for (keep_seq_idx = 0; keep_seq_idx < fds_to_keep_len; ++keep_seq_idx) {
373
int keep_fd = fds_to_keep[keep_seq_idx];
374
if (keep_fd < start_fd)
375
continue;
376
if (closer(start_fd, keep_fd - 1) != 0)
377
return -1;
378
start_fd = keep_fd + 1;
379
}
380
if (start_fd <= end_fd) {
381
if (closer(start_fd, end_fd) != 0)
382
return -1;
383
}
384
return 0;
385
}
386
387
#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
388
/* It doesn't matter if d_name has room for NAME_MAX chars; we're using this
389
* only to read a directory of short file descriptor number names. The kernel
390
* will return an error if we didn't give it enough space. Highly Unlikely.
391
* This structure is very old and stable: It will not change unless the kernel
392
* chooses to break compatibility with all existing binaries. Highly Unlikely.
393
*/
394
struct linux_dirent64 {
395
unsigned long long d_ino;
396
long long d_off;
397
unsigned short d_reclen; /* Length of this linux_dirent */
398
unsigned char d_type;
399
char d_name[256]; /* Filename (null-terminated) */
400
};
401
402
static int
403
_brute_force_closer(int first, int last)
404
{
405
for (int i = first; i <= last; i++) {
406
/* Ignore errors */
407
(void)close(i);
408
}
409
return 0;
410
}
411
412
/* Close all open file descriptors in the range from start_fd and higher
413
* Do not close any in the sorted fds_to_keep list.
414
*
415
* This version is async signal safe as it does not make any unsafe C library
416
* calls, malloc calls or handle any locks. It is _unfortunate_ to be forced
417
* to resort to making a kernel system call directly but this is the ONLY api
418
* available that does no harm. opendir/readdir/closedir perform memory
419
* allocation and locking so while they usually work they are not guaranteed
420
* to (especially if you have replaced your malloc implementation). A version
421
* of this function that uses those can be found in the _maybe_unsafe variant.
422
*
423
* This is Linux specific because that is all I am ready to test it on. It
424
* should be easy to add OS specific dirent or dirent64 structures and modify
425
* it with some cpp #define magic to work on other OSes as well if you want.
426
*/
427
static void
428
_close_open_fds_safe(int start_fd, int *fds_to_keep, Py_ssize_t fds_to_keep_len)
429
{
430
int fd_dir_fd;
431
432
fd_dir_fd = _Py_open_noraise(FD_DIR, O_RDONLY);
433
if (fd_dir_fd == -1) {
434
/* No way to get a list of open fds. */
435
_close_range_except(start_fd, -1,
436
fds_to_keep, fds_to_keep_len,
437
_brute_force_closer);
438
return;
439
} else {
440
char buffer[sizeof(struct linux_dirent64)];
441
int bytes;
442
while ((bytes = syscall(SYS_getdents64, fd_dir_fd,
443
(struct linux_dirent64 *)buffer,
444
sizeof(buffer))) > 0) {
445
struct linux_dirent64 *entry;
446
int offset;
447
#ifdef _Py_MEMORY_SANITIZER
448
__msan_unpoison(buffer, bytes);
449
#endif
450
for (offset = 0; offset < bytes; offset += entry->d_reclen) {
451
int fd;
452
entry = (struct linux_dirent64 *)(buffer + offset);
453
if ((fd = _pos_int_from_ascii(entry->d_name)) < 0)
454
continue; /* Not a number. */
455
if (fd != fd_dir_fd && fd >= start_fd &&
456
!_is_fd_in_sorted_fd_sequence(fd, fds_to_keep,
457
fds_to_keep_len)) {
458
close(fd);
459
}
460
}
461
}
462
close(fd_dir_fd);
463
}
464
}
465
466
#define _close_open_fds_fallback _close_open_fds_safe
467
468
#else /* NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */
469
470
static int
471
_unsafe_closer(int first, int last)
472
{
473
_Py_closerange(first, last);
474
return 0;
475
}
476
477
/* Close all open file descriptors from start_fd and higher.
478
* Do not close any in the sorted fds_to_keep tuple.
479
*
480
* This function violates the strict use of async signal safe functions. :(
481
* It calls opendir(), readdir() and closedir(). Of these, the one most
482
* likely to ever cause a problem is opendir() as it performs an internal
483
* malloc(). Practically this should not be a problem. The Java VM makes the
484
* same calls between fork and exec in its own UNIXProcess_md.c implementation.
485
*
486
* readdir_r() is not used because it provides no benefit. It is typically
487
* implemented as readdir() followed by memcpy(). See also:
488
* http://womble.decadent.org.uk/readdir_r-advisory.html
489
*/
490
static void
491
_close_open_fds_maybe_unsafe(int start_fd, int *fds_to_keep,
492
Py_ssize_t fds_to_keep_len)
493
{
494
DIR *proc_fd_dir;
495
#ifndef HAVE_DIRFD
496
while (_is_fd_in_sorted_fd_sequence(start_fd, fds_to_keep,
497
fds_to_keep_len)) {
498
++start_fd;
499
}
500
/* Close our lowest fd before we call opendir so that it is likely to
501
* reuse that fd otherwise we might close opendir's file descriptor in
502
* our loop. This trick assumes that fd's are allocated on a lowest
503
* available basis. */
504
close(start_fd);
505
++start_fd;
506
#endif
507
508
#if defined(__FreeBSD__) || defined(__DragonFly__)
509
if (!_is_fdescfs_mounted_on_dev_fd())
510
proc_fd_dir = NULL;
511
else
512
#endif
513
proc_fd_dir = opendir(FD_DIR);
514
if (!proc_fd_dir) {
515
/* No way to get a list of open fds. */
516
_close_range_except(start_fd, -1, fds_to_keep, fds_to_keep_len,
517
_unsafe_closer);
518
} else {
519
struct dirent *dir_entry;
520
#ifdef HAVE_DIRFD
521
int fd_used_by_opendir = dirfd(proc_fd_dir);
522
#else
523
int fd_used_by_opendir = start_fd - 1;
524
#endif
525
errno = 0;
526
while ((dir_entry = readdir(proc_fd_dir))) {
527
int fd;
528
if ((fd = _pos_int_from_ascii(dir_entry->d_name)) < 0)
529
continue; /* Not a number. */
530
if (fd != fd_used_by_opendir && fd >= start_fd &&
531
!_is_fd_in_sorted_fd_sequence(fd, fds_to_keep,
532
fds_to_keep_len)) {
533
close(fd);
534
}
535
errno = 0;
536
}
537
if (errno) {
538
/* readdir error, revert behavior. Highly Unlikely. */
539
_close_range_except(start_fd, -1, fds_to_keep, fds_to_keep_len,
540
_unsafe_closer);
541
}
542
closedir(proc_fd_dir);
543
}
544
}
545
546
#define _close_open_fds_fallback _close_open_fds_maybe_unsafe
547
548
#endif /* else NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */
549
550
/* We can use close_range() library function only if it's known to be
551
* async-signal-safe.
552
*
553
* On Linux, glibc explicitly documents it to be a thin wrapper over
554
* the system call, and other C libraries are likely to follow glibc.
555
*/
556
#if defined(HAVE_CLOSE_RANGE) && \
557
(defined(__linux__) || defined(__FreeBSD__))
558
#define HAVE_ASYNC_SAFE_CLOSE_RANGE
559
560
static int
561
_close_range_closer(int first, int last)
562
{
563
return close_range(first, last, 0);
564
}
565
#endif
566
567
static void
568
_close_open_fds(int start_fd, int *fds_to_keep, Py_ssize_t fds_to_keep_len)
569
{
570
#ifdef HAVE_ASYNC_SAFE_CLOSE_RANGE
571
if (_close_range_except(
572
start_fd, INT_MAX, fds_to_keep, fds_to_keep_len,
573
_close_range_closer) == 0) {
574
return;
575
}
576
#endif
577
_close_open_fds_fallback(start_fd, fds_to_keep, fds_to_keep_len);
578
}
579
580
#ifdef VFORK_USABLE
581
/* Reset dispositions for all signals to SIG_DFL except for ignored
582
* signals. This way we ensure that no signal handlers can run
583
* after we unblock signals in a child created by vfork().
584
*/
585
static void
586
reset_signal_handlers(const sigset_t *child_sigmask)
587
{
588
struct sigaction sa_dfl = {.sa_handler = SIG_DFL};
589
for (int sig = 1; sig < _NSIG; sig++) {
590
/* Dispositions for SIGKILL and SIGSTOP can't be changed. */
591
if (sig == SIGKILL || sig == SIGSTOP) {
592
continue;
593
}
594
595
/* There is no need to reset the disposition of signals that will
596
* remain blocked across execve() since the kernel will do it. */
597
if (sigismember(child_sigmask, sig) == 1) {
598
continue;
599
}
600
601
struct sigaction sa;
602
/* C libraries usually return EINVAL for signals used
603
* internally (e.g. for thread cancellation), so simply
604
* skip errors here. */
605
if (sigaction(sig, NULL, &sa) == -1) {
606
continue;
607
}
608
609
/* void *h works as these fields are both pointer types already. */
610
void *h = (sa.sa_flags & SA_SIGINFO ? (void *)sa.sa_sigaction :
611
(void *)sa.sa_handler);
612
if (h == SIG_IGN || h == SIG_DFL) {
613
continue;
614
}
615
616
/* This call can't reasonably fail, but if it does, terminating
617
* the child seems to be too harsh, so ignore errors. */
618
(void) sigaction(sig, &sa_dfl, NULL);
619
}
620
}
621
#endif /* VFORK_USABLE */
622
623
624
/*
625
* This function is code executed in the child process immediately after
626
* (v)fork to set things up and call exec().
627
*
628
* All of the code in this function must only use async-signal-safe functions,
629
* listed at `man 7 signal` or
630
* http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
631
*
632
* This restriction is documented at
633
* http://www.opengroup.org/onlinepubs/009695399/functions/fork.html.
634
*
635
* If this function is called after vfork(), even more care must be taken.
636
* The lack of preparations that C libraries normally take on fork(),
637
* as well as sharing the address space with the parent, might make even
638
* async-signal-safe functions vfork-unsafe. In particular, on Linux,
639
* set*id() and setgroups() library functions must not be called, since
640
* they have to interact with the library-level thread list and send
641
* library-internal signals to implement per-process credentials semantics
642
* required by POSIX but not supported natively on Linux. Another reason to
643
* avoid this family of functions is that sharing an address space between
644
* processes running with different privileges is inherently insecure.
645
* See https://bugs.python.org/issue35823 for discussion and references.
646
*
647
* In some C libraries, setrlimit() has the same thread list/signalling
648
* behavior since resource limits were per-thread attributes before
649
* Linux 2.6.10. Musl, as of 1.2.1, is known to have this issue
650
* (https://www.openwall.com/lists/musl/2020/10/15/6).
651
*
652
* If vfork-unsafe functionality is desired after vfork(), consider using
653
* syscall() to obtain it.
654
*/
655
Py_NO_INLINE static void
656
child_exec(char *const exec_array[],
657
char *const argv[],
658
char *const envp[],
659
const char *cwd,
660
int p2cread, int p2cwrite,
661
int c2pread, int c2pwrite,
662
int errread, int errwrite,
663
int errpipe_read, int errpipe_write,
664
int close_fds, int restore_signals,
665
int call_setsid, pid_t pgid_to_set,
666
gid_t gid,
667
Py_ssize_t extra_group_size, const gid_t *extra_groups,
668
uid_t uid, int child_umask,
669
const void *child_sigmask,
670
int *fds_to_keep, Py_ssize_t fds_to_keep_len,
671
PyObject *preexec_fn,
672
PyObject *preexec_fn_args_tuple)
673
{
674
int i, saved_errno, reached_preexec = 0;
675
PyObject *result;
676
const char* err_msg = "";
677
/* Buffer large enough to hold a hex integer. We can't malloc. */
678
char hex_errno[sizeof(saved_errno)*2+1];
679
680
if (make_inheritable(fds_to_keep, fds_to_keep_len, errpipe_write) < 0)
681
goto error;
682
683
/* Close parent's pipe ends. */
684
if (p2cwrite != -1)
685
POSIX_CALL(close(p2cwrite));
686
if (c2pread != -1)
687
POSIX_CALL(close(c2pread));
688
if (errread != -1)
689
POSIX_CALL(close(errread));
690
POSIX_CALL(close(errpipe_read));
691
692
/* When duping fds, if there arises a situation where one of the fds is
693
either 0, 1 or 2, it is possible that it is overwritten (#12607). */
694
if (c2pwrite == 0) {
695
POSIX_CALL(c2pwrite = dup(c2pwrite));
696
/* issue32270 */
697
if (_Py_set_inheritable_async_safe(c2pwrite, 0, NULL) < 0) {
698
goto error;
699
}
700
}
701
while (errwrite == 0 || errwrite == 1) {
702
POSIX_CALL(errwrite = dup(errwrite));
703
/* issue32270 */
704
if (_Py_set_inheritable_async_safe(errwrite, 0, NULL) < 0) {
705
goto error;
706
}
707
}
708
709
/* Dup fds for child.
710
dup2() removes the CLOEXEC flag but we must do it ourselves if dup2()
711
would be a no-op (issue #10806). */
712
if (p2cread == 0) {
713
if (_Py_set_inheritable_async_safe(p2cread, 1, NULL) < 0)
714
goto error;
715
}
716
else if (p2cread != -1)
717
POSIX_CALL(dup2(p2cread, 0)); /* stdin */
718
719
if (c2pwrite == 1) {
720
if (_Py_set_inheritable_async_safe(c2pwrite, 1, NULL) < 0)
721
goto error;
722
}
723
else if (c2pwrite != -1)
724
POSIX_CALL(dup2(c2pwrite, 1)); /* stdout */
725
726
if (errwrite == 2) {
727
if (_Py_set_inheritable_async_safe(errwrite, 1, NULL) < 0)
728
goto error;
729
}
730
else if (errwrite != -1)
731
POSIX_CALL(dup2(errwrite, 2)); /* stderr */
732
733
/* We no longer manually close p2cread, c2pwrite, and errwrite here as
734
* _close_open_fds takes care when it is not already non-inheritable. */
735
736
if (cwd)
737
POSIX_CALL(chdir(cwd));
738
739
if (child_umask >= 0)
740
umask(child_umask); /* umask() always succeeds. */
741
742
if (restore_signals)
743
_Py_RestoreSignals();
744
745
#ifdef VFORK_USABLE
746
if (child_sigmask) {
747
reset_signal_handlers(child_sigmask);
748
if ((errno = pthread_sigmask(SIG_SETMASK, child_sigmask, NULL))) {
749
goto error;
750
}
751
}
752
#endif
753
754
#ifdef HAVE_SETSID
755
if (call_setsid)
756
POSIX_CALL(setsid());
757
#endif
758
759
#ifdef HAVE_SETPGID
760
static_assert(_Py_IS_TYPE_SIGNED(pid_t), "pid_t is unsigned");
761
if (pgid_to_set >= 0) {
762
POSIX_CALL(setpgid(0, pgid_to_set));
763
}
764
#endif
765
766
#ifdef HAVE_SETGROUPS
767
if (extra_group_size > 0)
768
POSIX_CALL(setgroups(extra_group_size, extra_groups));
769
#endif /* HAVE_SETGROUPS */
770
771
#ifdef HAVE_SETREGID
772
if (gid != (gid_t)-1)
773
POSIX_CALL(setregid(gid, gid));
774
#endif /* HAVE_SETREGID */
775
776
#ifdef HAVE_SETREUID
777
if (uid != (uid_t)-1)
778
POSIX_CALL(setreuid(uid, uid));
779
#endif /* HAVE_SETREUID */
780
781
782
reached_preexec = 1;
783
if (preexec_fn != Py_None && preexec_fn_args_tuple) {
784
/* This is where the user has asked us to deadlock their program. */
785
result = PyObject_Call(preexec_fn, preexec_fn_args_tuple, NULL);
786
if (result == NULL) {
787
/* Stringifying the exception or traceback would involve
788
* memory allocation and thus potential for deadlock.
789
* We've already faced potential deadlock by calling back
790
* into Python in the first place, so it probably doesn't
791
* matter but we avoid it to minimize the possibility. */
792
err_msg = "Exception occurred in preexec_fn.";
793
errno = 0; /* We don't want to report an OSError. */
794
goto error;
795
}
796
/* Py_DECREF(result); - We're about to exec so why bother? */
797
}
798
799
/* close FDs after executing preexec_fn, which might open FDs */
800
if (close_fds) {
801
/* TODO HP-UX could use pstat_getproc() if anyone cares about it. */
802
_close_open_fds(3, fds_to_keep, fds_to_keep_len);
803
}
804
805
/* This loop matches the Lib/os.py _execvpe()'s PATH search when */
806
/* given the executable_list generated by Lib/subprocess.py. */
807
saved_errno = 0;
808
for (i = 0; exec_array[i] != NULL; ++i) {
809
const char *executable = exec_array[i];
810
if (envp) {
811
execve(executable, argv, envp);
812
} else {
813
execv(executable, argv);
814
}
815
if (errno != ENOENT && errno != ENOTDIR && saved_errno == 0) {
816
saved_errno = errno;
817
}
818
}
819
/* Report the first exec error, not the last. */
820
if (saved_errno)
821
errno = saved_errno;
822
823
error:
824
saved_errno = errno;
825
/* Report the posix error to our parent process. */
826
/* We ignore all write() return values as the total size of our writes is
827
less than PIPEBUF and we cannot do anything about an error anyways.
828
Use _Py_write_noraise() to retry write() if it is interrupted by a
829
signal (fails with EINTR). */
830
if (saved_errno) {
831
char *cur;
832
_Py_write_noraise(errpipe_write, "OSError:", 8);
833
cur = hex_errno + sizeof(hex_errno);
834
while (saved_errno != 0 && cur != hex_errno) {
835
*--cur = Py_hexdigits[saved_errno % 16];
836
saved_errno /= 16;
837
}
838
_Py_write_noraise(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur);
839
_Py_write_noraise(errpipe_write, ":", 1);
840
if (!reached_preexec) {
841
/* Indicate to the parent that the error happened before exec(). */
842
_Py_write_noraise(errpipe_write, "noexec", 6);
843
}
844
/* We can't call strerror(saved_errno). It is not async signal safe.
845
* The parent process will look the error message up. */
846
} else {
847
_Py_write_noraise(errpipe_write, "SubprocessError:0:", 18);
848
_Py_write_noraise(errpipe_write, err_msg, strlen(err_msg));
849
}
850
}
851
852
853
/* The main purpose of this wrapper function is to isolate vfork() from both
854
* subprocess_fork_exec() and child_exec(). A child process created via
855
* vfork() executes on the same stack as the parent process while the latter is
856
* suspended, so this function should not be inlined to avoid compiler bugs
857
* that might clobber data needed by the parent later. Additionally,
858
* child_exec() should not be inlined to avoid spurious -Wclobber warnings from
859
* GCC (see bpo-35823).
860
*/
861
Py_NO_INLINE static pid_t
862
do_fork_exec(char *const exec_array[],
863
char *const argv[],
864
char *const envp[],
865
const char *cwd,
866
int p2cread, int p2cwrite,
867
int c2pread, int c2pwrite,
868
int errread, int errwrite,
869
int errpipe_read, int errpipe_write,
870
int close_fds, int restore_signals,
871
int call_setsid, pid_t pgid_to_set,
872
gid_t gid,
873
Py_ssize_t extra_group_size, const gid_t *extra_groups,
874
uid_t uid, int child_umask,
875
const void *child_sigmask,
876
int *fds_to_keep, Py_ssize_t fds_to_keep_len,
877
PyObject *preexec_fn,
878
PyObject *preexec_fn_args_tuple)
879
{
880
881
pid_t pid;
882
883
#ifdef VFORK_USABLE
884
PyThreadState *vfork_tstate_save;
885
if (child_sigmask) {
886
/* These are checked by our caller; verify them in debug builds. */
887
assert(uid == (uid_t)-1);
888
assert(gid == (gid_t)-1);
889
assert(extra_group_size < 0);
890
assert(preexec_fn == Py_None);
891
892
/* Drop the GIL so that other threads can continue execution while this
893
* thread in the parent remains blocked per vfork-semantics on the
894
* child's exec syscall outcome. Exec does filesystem access which
895
* can take an arbitrarily long time. This addresses GH-104372.
896
*
897
* The vfork'ed child still runs in our address space. Per POSIX it
898
* must be limited to nothing but exec, but the Linux implementation
899
* is a little more usable. See the child_exec() comment - The child
900
* MUST NOT re-acquire the GIL.
901
*/
902
vfork_tstate_save = PyEval_SaveThread();
903
pid = vfork();
904
if (pid != 0) {
905
// Not in the child process, reacquire the GIL.
906
PyEval_RestoreThread(vfork_tstate_save);
907
}
908
if (pid == (pid_t)-1) {
909
/* If vfork() fails, fall back to using fork(). When it isn't
910
* allowed in a process by the kernel, vfork can return -1
911
* with errno EINVAL. https://bugs.python.org/issue47151. */
912
pid = fork();
913
}
914
} else
915
#endif
916
{
917
pid = fork();
918
}
919
920
if (pid != 0) {
921
// Parent process.
922
return pid;
923
}
924
925
/* Child process.
926
* See the comment above child_exec() for restrictions imposed on
927
* the code below.
928
*/
929
930
if (preexec_fn != Py_None) {
931
/* We'll be calling back into Python later so we need to do this.
932
* This call may not be async-signal-safe but neither is calling
933
* back into Python. The user asked us to use hope as a strategy
934
* to avoid deadlock... */
935
PyOS_AfterFork_Child();
936
}
937
938
child_exec(exec_array, argv, envp, cwd,
939
p2cread, p2cwrite, c2pread, c2pwrite,
940
errread, errwrite, errpipe_read, errpipe_write,
941
close_fds, restore_signals, call_setsid, pgid_to_set,
942
gid, extra_group_size, extra_groups,
943
uid, child_umask, child_sigmask,
944
fds_to_keep, fds_to_keep_len,
945
preexec_fn, preexec_fn_args_tuple);
946
_exit(255);
947
return 0; /* Dead code to avoid a potential compiler warning. */
948
}
949
950
/*[clinic input]
951
_posixsubprocess.fork_exec as subprocess_fork_exec
952
args as process_args: object
953
executable_list: object
954
close_fds: bool
955
pass_fds as py_fds_to_keep: object(subclass_of='&PyTuple_Type')
956
cwd as cwd_obj: object
957
env as env_list: object
958
p2cread: int
959
p2cwrite: int
960
c2pread: int
961
c2pwrite: int
962
errread: int
963
errwrite: int
964
errpipe_read: int
965
errpipe_write: int
966
restore_signals: bool
967
call_setsid: bool
968
pgid_to_set: pid_t
969
gid as gid_object: object
970
extra_groups as extra_groups_packed: object
971
uid as uid_object: object
972
child_umask: int
973
preexec_fn: object
974
allow_vfork: bool
975
/
976
977
Spawn a fresh new child process.
978
979
Fork a child process, close parent file descriptors as appropriate in the
980
child and duplicate the few that are needed before calling exec() in the
981
child process.
982
983
If close_fds is True, close file descriptors 3 and higher, except those listed
984
in the sorted tuple pass_fds.
985
986
The preexec_fn, if supplied, will be called immediately before closing file
987
descriptors and exec.
988
989
WARNING: preexec_fn is NOT SAFE if your application uses threads.
990
It may trigger infrequent, difficult to debug deadlocks.
991
992
If an error occurs in the child process before the exec, it is
993
serialized and written to the errpipe_write fd per subprocess.py.
994
995
Returns: the child process's PID.
996
997
Raises: Only on an error in the parent process.
998
[clinic start generated code]*/
999
1000
static PyObject *
1001
subprocess_fork_exec_impl(PyObject *module, PyObject *process_args,
1002
PyObject *executable_list, int close_fds,
1003
PyObject *py_fds_to_keep, PyObject *cwd_obj,
1004
PyObject *env_list, int p2cread, int p2cwrite,
1005
int c2pread, int c2pwrite, int errread,
1006
int errwrite, int errpipe_read, int errpipe_write,
1007
int restore_signals, int call_setsid,
1008
pid_t pgid_to_set, PyObject *gid_object,
1009
PyObject *extra_groups_packed,
1010
PyObject *uid_object, int child_umask,
1011
PyObject *preexec_fn, int allow_vfork)
1012
/*[clinic end generated code: output=7ee4f6ee5cf22b5b input=51757287ef266ffa]*/
1013
{
1014
PyObject *converted_args = NULL, *fast_args = NULL;
1015
PyObject *preexec_fn_args_tuple = NULL;
1016
gid_t *extra_groups = NULL;
1017
PyObject *cwd_obj2 = NULL;
1018
const char *cwd = NULL;
1019
pid_t pid = -1;
1020
int need_to_reenable_gc = 0;
1021
char *const *argv = NULL, *const *envp = NULL;
1022
Py_ssize_t extra_group_size = 0;
1023
int need_after_fork = 0;
1024
int saved_errno = 0;
1025
int *c_fds_to_keep = NULL;
1026
Py_ssize_t fds_to_keep_len = PyTuple_GET_SIZE(py_fds_to_keep);
1027
1028
PyInterpreterState *interp = PyInterpreterState_Get();
1029
if ((preexec_fn != Py_None) && interp->finalizing) {
1030
PyErr_SetString(PyExc_RuntimeError,
1031
"preexec_fn not supported at interpreter shutdown");
1032
return NULL;
1033
}
1034
if ((preexec_fn != Py_None) && (interp != PyInterpreterState_Main())) {
1035
PyErr_SetString(PyExc_RuntimeError,
1036
"preexec_fn not supported within subinterpreters");
1037
return NULL;
1038
}
1039
1040
if (close_fds && errpipe_write < 3) { /* precondition */
1041
PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3");
1042
return NULL;
1043
}
1044
if (_sanity_check_python_fd_sequence(py_fds_to_keep)) {
1045
PyErr_SetString(PyExc_ValueError, "bad value(s) in fds_to_keep");
1046
return NULL;
1047
}
1048
1049
/* We need to call gc.disable() when we'll be calling preexec_fn */
1050
if (preexec_fn != Py_None) {
1051
need_to_reenable_gc = PyGC_Disable();
1052
}
1053
1054
char *const *exec_array = _PySequence_BytesToCharpArray(executable_list);
1055
if (!exec_array)
1056
goto cleanup;
1057
1058
/* Convert args and env into appropriate arguments for exec() */
1059
/* These conversions are done in the parent process to avoid allocating
1060
or freeing memory in the child process. */
1061
if (process_args != Py_None) {
1062
Py_ssize_t num_args;
1063
/* Equivalent to: */
1064
/* tuple(PyUnicode_FSConverter(arg) for arg in process_args) */
1065
fast_args = PySequence_Fast(process_args, "argv must be a tuple");
1066
if (fast_args == NULL)
1067
goto cleanup;
1068
num_args = PySequence_Fast_GET_SIZE(fast_args);
1069
converted_args = PyTuple_New(num_args);
1070
if (converted_args == NULL)
1071
goto cleanup;
1072
for (Py_ssize_t arg_num = 0; arg_num < num_args; ++arg_num) {
1073
PyObject *borrowed_arg, *converted_arg;
1074
if (PySequence_Fast_GET_SIZE(fast_args) != num_args) {
1075
PyErr_SetString(PyExc_RuntimeError, "args changed during iteration");
1076
goto cleanup;
1077
}
1078
borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num);
1079
if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0)
1080
goto cleanup;
1081
PyTuple_SET_ITEM(converted_args, arg_num, converted_arg);
1082
}
1083
1084
argv = _PySequence_BytesToCharpArray(converted_args);
1085
Py_CLEAR(converted_args);
1086
Py_CLEAR(fast_args);
1087
if (!argv)
1088
goto cleanup;
1089
}
1090
1091
if (env_list != Py_None) {
1092
envp = _PySequence_BytesToCharpArray(env_list);
1093
if (!envp)
1094
goto cleanup;
1095
}
1096
1097
if (cwd_obj != Py_None) {
1098
if (PyUnicode_FSConverter(cwd_obj, &cwd_obj2) == 0)
1099
goto cleanup;
1100
cwd = PyBytes_AsString(cwd_obj2);
1101
}
1102
1103
if (extra_groups_packed != Py_None) {
1104
#ifdef HAVE_SETGROUPS
1105
if (!PyList_Check(extra_groups_packed)) {
1106
PyErr_SetString(PyExc_TypeError,
1107
"setgroups argument must be a list");
1108
goto cleanup;
1109
}
1110
extra_group_size = PySequence_Size(extra_groups_packed);
1111
1112
if (extra_group_size < 0)
1113
goto cleanup;
1114
1115
if (extra_group_size > MAX_GROUPS) {
1116
PyErr_SetString(PyExc_ValueError, "too many extra_groups");
1117
goto cleanup;
1118
}
1119
1120
/* Deliberately keep extra_groups == NULL for extra_group_size == 0 */
1121
if (extra_group_size > 0) {
1122
extra_groups = PyMem_RawMalloc(extra_group_size * sizeof(gid_t));
1123
if (extra_groups == NULL) {
1124
PyErr_SetString(PyExc_MemoryError,
1125
"failed to allocate memory for group list");
1126
goto cleanup;
1127
}
1128
}
1129
1130
for (Py_ssize_t i = 0; i < extra_group_size; i++) {
1131
PyObject *elem;
1132
elem = PySequence_GetItem(extra_groups_packed, i);
1133
if (!elem)
1134
goto cleanup;
1135
if (!PyLong_Check(elem)) {
1136
PyErr_SetString(PyExc_TypeError,
1137
"extra_groups must be integers");
1138
Py_DECREF(elem);
1139
goto cleanup;
1140
} else {
1141
gid_t gid;
1142
if (!_Py_Gid_Converter(elem, &gid)) {
1143
Py_DECREF(elem);
1144
PyErr_SetString(PyExc_ValueError, "invalid group id");
1145
goto cleanup;
1146
}
1147
extra_groups[i] = gid;
1148
}
1149
Py_DECREF(elem);
1150
}
1151
1152
#else /* HAVE_SETGROUPS */
1153
PyErr_BadInternalCall();
1154
goto cleanup;
1155
#endif /* HAVE_SETGROUPS */
1156
}
1157
1158
gid_t gid = (gid_t)-1;
1159
if (gid_object != Py_None) {
1160
#ifdef HAVE_SETREGID
1161
if (!_Py_Gid_Converter(gid_object, &gid))
1162
goto cleanup;
1163
1164
#else /* HAVE_SETREGID */
1165
PyErr_BadInternalCall();
1166
goto cleanup;
1167
#endif /* HAVE_SETREUID */
1168
}
1169
1170
uid_t uid = (uid_t)-1;
1171
if (uid_object != Py_None) {
1172
#ifdef HAVE_SETREUID
1173
if (!_Py_Uid_Converter(uid_object, &uid))
1174
goto cleanup;
1175
1176
#else /* HAVE_SETREUID */
1177
PyErr_BadInternalCall();
1178
goto cleanup;
1179
#endif /* HAVE_SETREUID */
1180
}
1181
1182
c_fds_to_keep = PyMem_Malloc(fds_to_keep_len * sizeof(int));
1183
if (c_fds_to_keep == NULL) {
1184
PyErr_SetString(PyExc_MemoryError, "failed to malloc c_fds_to_keep");
1185
goto cleanup;
1186
}
1187
if (convert_fds_to_keep_to_c(py_fds_to_keep, c_fds_to_keep) < 0) {
1188
goto cleanup;
1189
}
1190
1191
/* This must be the last thing done before fork() because we do not
1192
* want to call PyOS_BeforeFork() if there is any chance of another
1193
* error leading to the cleanup: code without calling fork(). */
1194
if (preexec_fn != Py_None) {
1195
preexec_fn_args_tuple = PyTuple_New(0);
1196
if (!preexec_fn_args_tuple)
1197
goto cleanup;
1198
PyOS_BeforeFork();
1199
need_after_fork = 1;
1200
}
1201
1202
/* NOTE: When old_sigmask is non-NULL, do_fork_exec() may use vfork(). */
1203
const void *old_sigmask = NULL;
1204
#ifdef VFORK_USABLE
1205
/* Use vfork() only if it's safe. See the comment above child_exec(). */
1206
sigset_t old_sigs;
1207
if (preexec_fn == Py_None && allow_vfork &&
1208
uid == (uid_t)-1 && gid == (gid_t)-1 && extra_group_size < 0) {
1209
/* Block all signals to ensure that no signal handlers are run in the
1210
* child process while it shares memory with us. Note that signals
1211
* used internally by C libraries won't be blocked by
1212
* pthread_sigmask(), but signal handlers installed by C libraries
1213
* normally service only signals originating from *within the process*,
1214
* so it should be sufficient to consider any library function that
1215
* might send such a signal to be vfork-unsafe and do not call it in
1216
* the child.
1217
*/
1218
sigset_t all_sigs;
1219
sigfillset(&all_sigs);
1220
if ((saved_errno = pthread_sigmask(SIG_BLOCK, &all_sigs, &old_sigs))) {
1221
goto cleanup;
1222
}
1223
old_sigmask = &old_sigs;
1224
}
1225
#endif
1226
1227
pid = do_fork_exec(exec_array, argv, envp, cwd,
1228
p2cread, p2cwrite, c2pread, c2pwrite,
1229
errread, errwrite, errpipe_read, errpipe_write,
1230
close_fds, restore_signals, call_setsid, pgid_to_set,
1231
gid, extra_group_size, extra_groups,
1232
uid, child_umask, old_sigmask,
1233
c_fds_to_keep, fds_to_keep_len,
1234
preexec_fn, preexec_fn_args_tuple);
1235
1236
/* Parent (original) process */
1237
if (pid == (pid_t)-1) {
1238
/* Capture errno for the exception. */
1239
saved_errno = errno;
1240
}
1241
1242
#ifdef VFORK_USABLE
1243
if (old_sigmask) {
1244
/* vfork() semantics guarantees that the parent is blocked
1245
* until the child performs _exit() or execve(), so it is safe
1246
* to unblock signals once we're here.
1247
* Note that in environments where vfork() is implemented as fork(),
1248
* such as QEMU user-mode emulation, the parent won't be blocked,
1249
* but it won't share the address space with the child,
1250
* so it's still safe to unblock the signals.
1251
*
1252
* We don't handle errors here because this call can't fail
1253
* if valid arguments are given, and because there is no good
1254
* way for the caller to deal with a failure to restore
1255
* the thread signal mask. */
1256
(void) pthread_sigmask(SIG_SETMASK, old_sigmask, NULL);
1257
}
1258
#endif
1259
1260
if (need_after_fork)
1261
PyOS_AfterFork_Parent();
1262
1263
cleanup:
1264
if (c_fds_to_keep != NULL) {
1265
PyMem_Free(c_fds_to_keep);
1266
}
1267
1268
if (saved_errno != 0) {
1269
errno = saved_errno;
1270
/* We can't call this above as PyOS_AfterFork_Parent() calls back
1271
* into Python code which would see the unreturned error. */
1272
PyErr_SetFromErrno(PyExc_OSError);
1273
}
1274
1275
Py_XDECREF(preexec_fn_args_tuple);
1276
PyMem_RawFree(extra_groups);
1277
Py_XDECREF(cwd_obj2);
1278
if (envp)
1279
_Py_FreeCharPArray(envp);
1280
Py_XDECREF(converted_args);
1281
Py_XDECREF(fast_args);
1282
if (argv)
1283
_Py_FreeCharPArray(argv);
1284
if (exec_array)
1285
_Py_FreeCharPArray(exec_array);
1286
1287
if (need_to_reenable_gc) {
1288
PyGC_Enable();
1289
}
1290
1291
return pid == -1 ? NULL : PyLong_FromPid(pid);
1292
}
1293
1294
/* module level code ********************************************************/
1295
1296
PyDoc_STRVAR(module_doc,
1297
"A POSIX helper for the subprocess module.");
1298
1299
static PyMethodDef module_methods[] = {
1300
SUBPROCESS_FORK_EXEC_METHODDEF
1301
{NULL, NULL} /* sentinel */
1302
};
1303
1304
static PyModuleDef_Slot _posixsubprocess_slots[] = {
1305
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
1306
{0, NULL}
1307
};
1308
1309
static struct PyModuleDef _posixsubprocessmodule = {
1310
PyModuleDef_HEAD_INIT,
1311
.m_name = "_posixsubprocess",
1312
.m_doc = module_doc,
1313
.m_size = 0,
1314
.m_methods = module_methods,
1315
.m_slots = _posixsubprocess_slots,
1316
};
1317
1318
PyMODINIT_FUNC
1319
PyInit__posixsubprocess(void)
1320
{
1321
return PyModuleDef_Init(&_posixsubprocessmodule);
1322
}
1323
1324