blob: 709ebaaf49513e4a985b35ea486d5f29171dd282 [file] [log] [blame]
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001/* Authors: Gregory P. Smith & Jeffrey Yasskin */
2#include "Python.h"
Ross Lagerwall667d75d2011-12-22 09:45:53 +02003#if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE)
4# define _GNU_SOURCE
Gregory P. Smith51ee2702010-12-13 07:59:39 +00005#endif
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00006#include <unistd.h>
Gregory P. Smith51ee2702010-12-13 07:59:39 +00007#include <fcntl.h>
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00008
9
10#define POSIX_CALL(call) if ((call) == -1) goto error
11
12
13/* Maximum file descriptor, initialized on module load. */
14static long max_fd;
15
16
17/* Given the gc module call gc.enable() and return 0 on success. */
18static int _enable_gc(PyObject *gc_module)
19{
20 PyObject *result;
21 result = PyObject_CallMethod(gc_module, "enable", NULL);
22 if (result == NULL)
23 return 1;
24 Py_DECREF(result);
25 return 0;
26}
27
28
29/*
30 * This function is code executed in the child process immediately after fork
31 * to set things up and call exec().
32 *
33 * All of the code in this function must only use async-signal-safe functions,
34 * listed at `man 7 signal` or
35 * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
36 *
37 * This restriction is documented at
38 * http://www.opengroup.org/onlinepubs/009695399/functions/fork.html.
39 */
40static void child_exec(char *const exec_array[],
41 char *const argv[],
42 char *const envp[],
43 const char *cwd,
44 int p2cread, int p2cwrite,
45 int c2pread, int c2pwrite,
46 int errread, int errwrite,
47 int errpipe_read, int errpipe_write,
48 int close_fds, int restore_signals,
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +000049 int call_setsid, Py_ssize_t num_fds_to_keep,
50 PyObject *py_fds_to_keep,
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000051 PyObject *preexec_fn,
52 PyObject *preexec_fn_args_tuple)
53{
Gregory P. Smith12fdca52012-01-21 12:31:25 -080054 int i, saved_errno, fd_num, unused;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000055 PyObject *result;
Gregory P. Smith14affb82010-12-22 05:22:17 +000056 const char* err_msg = "";
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000057 /* Buffer large enough to hold a hex integer. We can't malloc. */
58 char hex_errno[sizeof(saved_errno)*2+1];
59
60 /* Close parent's pipe ends. */
61 if (p2cwrite != -1) {
62 POSIX_CALL(close(p2cwrite));
63 }
64 if (c2pread != -1) {
65 POSIX_CALL(close(c2pread));
66 }
67 if (errread != -1) {
68 POSIX_CALL(close(errread));
69 }
70 POSIX_CALL(close(errpipe_read));
71
Ross Lagerwalld98646e2011-07-27 07:16:31 +020072 /* When duping fds, if there arises a situation where one of the fds is
73 either 0, 1 or 2, it is possible that it is overwritten (#12607). */
74 if (c2pwrite == 0)
75 POSIX_CALL(c2pwrite = dup(c2pwrite));
76 if (errwrite == 0 || errwrite == 1)
77 POSIX_CALL(errwrite = dup(errwrite));
78
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +000079 /* Dup fds for child.
80 dup2() removes the CLOEXEC flag but we must do it ourselves if dup2()
81 would be a no-op (issue #10806). */
82 if (p2cread == 0) {
83 int old = fcntl(p2cread, F_GETFD);
84 if (old != -1)
85 fcntl(p2cread, F_SETFD, old & ~FD_CLOEXEC);
86 } else if (p2cread != -1) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000087 POSIX_CALL(dup2(p2cread, 0)); /* stdin */
88 }
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +000089 if (c2pwrite == 1) {
90 int old = fcntl(c2pwrite, F_GETFD);
91 if (old != -1)
92 fcntl(c2pwrite, F_SETFD, old & ~FD_CLOEXEC);
93 } else if (c2pwrite != -1) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000094 POSIX_CALL(dup2(c2pwrite, 1)); /* stdout */
95 }
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +000096 if (errwrite == 2) {
97 int old = fcntl(errwrite, F_GETFD);
98 if (old != -1)
99 fcntl(errwrite, F_SETFD, old & ~FD_CLOEXEC);
100 } else if (errwrite != -1) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000101 POSIX_CALL(dup2(errwrite, 2)); /* stderr */
102 }
103
104 /* Close pipe fds. Make sure we don't close the same fd more than */
105 /* once, or standard fds. */
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +0000106 if (p2cread > 2) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000107 POSIX_CALL(close(p2cread));
108 }
Gregory P. Smith9c4f44f2011-03-15 14:56:39 -0400109 if (c2pwrite > 2 && c2pwrite != p2cread) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000110 POSIX_CALL(close(c2pwrite));
111 }
Gregory P. Smith9c4f44f2011-03-15 14:56:39 -0400112 if (errwrite != c2pwrite && errwrite != p2cread && errwrite > 2) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000113 POSIX_CALL(close(errwrite));
114 }
115
116 /* close() is intentionally not checked for errors here as we are closing */
117 /* a large range of fds, some of which may be invalid. */
118 if (close_fds) {
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000119 Py_ssize_t keep_seq_idx;
120 int start_fd = 3;
121 for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) {
122 PyObject* py_keep_fd = PySequence_Fast_GET_ITEM(py_fds_to_keep,
123 keep_seq_idx);
124 int keep_fd = PyLong_AsLong(py_keep_fd);
125 if (keep_fd < 0) { /* Negative number, overflow or not a Long. */
126 err_msg = "bad value in fds_to_keep.";
127 errno = 0; /* We don't want to report an OSError. */
128 goto error;
129 }
Gregory P. Smith8edd99d2010-12-14 13:43:30 +0000130 if (keep_fd < start_fd)
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000131 continue;
132 for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) {
133 close(fd_num);
134 }
135 start_fd = keep_fd + 1;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000136 }
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000137 if (start_fd <= max_fd) {
138 for (fd_num = start_fd; fd_num < max_fd; ++fd_num) {
139 close(fd_num);
140 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000141 }
142 }
143
144 if (cwd)
145 POSIX_CALL(chdir(cwd));
146
147 if (restore_signals)
148 _Py_RestoreSignals();
149
150#ifdef HAVE_SETSID
151 if (call_setsid)
152 POSIX_CALL(setsid());
153#endif
154
155 if (preexec_fn != Py_None && preexec_fn_args_tuple) {
156 /* This is where the user has asked us to deadlock their program. */
157 result = PyObject_Call(preexec_fn, preexec_fn_args_tuple, NULL);
158 if (result == NULL) {
159 /* Stringifying the exception or traceback would involve
160 * memory allocation and thus potential for deadlock.
161 * We've already faced potential deadlock by calling back
162 * into Python in the first place, so it probably doesn't
163 * matter but we avoid it to minimize the possibility. */
164 err_msg = "Exception occurred in preexec_fn.";
165 errno = 0; /* We don't want to report an OSError. */
166 goto error;
167 }
168 /* Py_DECREF(result); - We're about to exec so why bother? */
169 }
170
171 /* This loop matches the Lib/os.py _execvpe()'s PATH search when */
172 /* given the executable_list generated by Lib/subprocess.py. */
173 saved_errno = 0;
174 for (i = 0; exec_array[i] != NULL; ++i) {
175 const char *executable = exec_array[i];
176 if (envp) {
177 execve(executable, argv, envp);
178 } else {
179 execv(executable, argv);
180 }
181 if (errno != ENOENT && errno != ENOTDIR && saved_errno == 0) {
182 saved_errno = errno;
183 }
184 }
185 /* Report the first exec error, not the last. */
186 if (saved_errno)
187 errno = saved_errno;
188
189error:
190 saved_errno = errno;
191 /* Report the posix error to our parent process. */
Gregory P. Smith12fdca52012-01-21 12:31:25 -0800192 /* We ignore all write() return values as the total size of our writes is
193 * less than PIPEBUF and we cannot do anything about an error anyways. */
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000194 if (saved_errno) {
195 char *cur;
Gregory P. Smith12fdca52012-01-21 12:31:25 -0800196 unused = write(errpipe_write, "OSError:", 8);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000197 cur = hex_errno + sizeof(hex_errno);
198 while (saved_errno != 0 && cur > hex_errno) {
199 *--cur = "0123456789ABCDEF"[saved_errno % 16];
200 saved_errno /= 16;
201 }
Gregory P. Smith12fdca52012-01-21 12:31:25 -0800202 unused = write(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur);
203 unused = write(errpipe_write, ":", 1);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000204 /* We can't call strerror(saved_errno). It is not async signal safe.
205 * The parent process will look the error message up. */
206 } else {
Gregory P. Smith12fdca52012-01-21 12:31:25 -0800207 unused = write(errpipe_write, "RuntimeError:0:", 15);
208 unused = write(errpipe_write, err_msg, strlen(err_msg));
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000209 }
Gregory P. Smith12fdca52012-01-21 12:31:25 -0800210 if (unused) return; /* silly? yes! avoids gcc compiler warning. */
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000211}
212
213
214static PyObject *
215subprocess_fork_exec(PyObject* self, PyObject *args)
216{
217 PyObject *gc_module = NULL;
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000218 PyObject *executable_list, *py_close_fds, *py_fds_to_keep;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000219 PyObject *env_list, *preexec_fn;
Gregory P. Smith68f52172010-03-15 06:07:42 +0000220 PyObject *process_args, *converted_args = NULL, *fast_args = NULL;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000221 PyObject *preexec_fn_args_tuple = NULL;
222 int p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite;
223 int errpipe_read, errpipe_write, close_fds, restore_signals;
224 int call_setsid;
Victor Stinner0e59cc32010-04-16 23:49:32 +0000225 PyObject *cwd_obj, *cwd_obj2;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000226 const char *cwd;
227 pid_t pid;
228 int need_to_reenable_gc = 0;
229 char *const *exec_array, *const *argv = NULL, *const *envp = NULL;
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000230 Py_ssize_t arg_num, num_fds_to_keep;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000231
232 if (!PyArg_ParseTuple(
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000233 args, "OOOOOOiiiiiiiiiiO:fork_exec",
234 &process_args, &executable_list, &py_close_fds, &py_fds_to_keep,
Victor Stinner0e59cc32010-04-16 23:49:32 +0000235 &cwd_obj, &env_list,
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000236 &p2cread, &p2cwrite, &c2pread, &c2pwrite,
237 &errread, &errwrite, &errpipe_read, &errpipe_write,
238 &restore_signals, &call_setsid, &preexec_fn))
239 return NULL;
240
241 close_fds = PyObject_IsTrue(py_close_fds);
242 if (close_fds && errpipe_write < 3) { /* precondition */
243 PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3");
244 return NULL;
245 }
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000246 num_fds_to_keep = PySequence_Length(py_fds_to_keep);
247 if (num_fds_to_keep < 0) {
248 PyErr_SetString(PyExc_ValueError, "bad fds_to_keep");
249 return NULL;
250 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000251
252 /* We need to call gc.disable() when we'll be calling preexec_fn */
253 if (preexec_fn != Py_None) {
254 PyObject *result;
255 gc_module = PyImport_ImportModule("gc");
256 if (gc_module == NULL)
257 return NULL;
258 result = PyObject_CallMethod(gc_module, "isenabled", NULL);
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000259 if (result == NULL) {
260 Py_DECREF(gc_module);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000261 return NULL;
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000262 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000263 need_to_reenable_gc = PyObject_IsTrue(result);
264 Py_DECREF(result);
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000265 if (need_to_reenable_gc == -1) {
266 Py_DECREF(gc_module);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000267 return NULL;
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000268 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000269 result = PyObject_CallMethod(gc_module, "disable", NULL);
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000270 if (result == NULL) {
271 Py_DECREF(gc_module);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000272 return NULL;
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000273 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000274 Py_DECREF(result);
275 }
276
277 exec_array = _PySequence_BytesToCharpArray(executable_list);
278 if (!exec_array)
279 return NULL;
280
281 /* Convert args and env into appropriate arguments for exec() */
282 /* These conversions are done in the parent process to avoid allocating
283 or freeing memory in the child process. */
284 if (process_args != Py_None) {
Gregory P. Smith68f52172010-03-15 06:07:42 +0000285 Py_ssize_t num_args;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000286 /* Equivalent to: */
287 /* tuple(PyUnicode_FSConverter(arg) for arg in process_args) */
Gregory P. Smith68f52172010-03-15 06:07:42 +0000288 fast_args = PySequence_Fast(process_args, "argv must be a tuple");
289 num_args = PySequence_Fast_GET_SIZE(fast_args);
290 converted_args = PyTuple_New(num_args);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000291 if (converted_args == NULL)
292 goto cleanup;
Gregory P. Smith68f52172010-03-15 06:07:42 +0000293 for (arg_num = 0; arg_num < num_args; ++arg_num) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000294 PyObject *borrowed_arg, *converted_arg;
Gregory P. Smith68f52172010-03-15 06:07:42 +0000295 borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000296 if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0)
297 goto cleanup;
298 PyTuple_SET_ITEM(converted_args, arg_num, converted_arg);
299 }
300
301 argv = _PySequence_BytesToCharpArray(converted_args);
302 Py_CLEAR(converted_args);
Gregory P. Smith68f52172010-03-15 06:07:42 +0000303 Py_CLEAR(fast_args);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000304 if (!argv)
305 goto cleanup;
306 }
307
308 if (env_list != Py_None) {
309 envp = _PySequence_BytesToCharpArray(env_list);
310 if (!envp)
311 goto cleanup;
312 }
313
314 if (preexec_fn != Py_None) {
315 preexec_fn_args_tuple = PyTuple_New(0);
316 if (!preexec_fn_args_tuple)
317 goto cleanup;
Victor Stinner0e59cc32010-04-16 23:49:32 +0000318 _PyImport_AcquireLock();
319 }
320
321 if (cwd_obj != Py_None) {
322 if (PyUnicode_FSConverter(cwd_obj, &cwd_obj2) == 0)
323 goto cleanup;
Victor Stinnerdcb24032010-04-22 12:08:36 +0000324 cwd = PyBytes_AsString(cwd_obj2);
Victor Stinner0e59cc32010-04-16 23:49:32 +0000325 } else {
326 cwd = NULL;
327 cwd_obj2 = NULL;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000328 }
329
330 pid = fork();
331 if (pid == 0) {
332 /* Child process */
Victor Stinner0e59cc32010-04-16 23:49:32 +0000333 /*
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000334 * Code from here to _exit() must only use async-signal-safe functions,
335 * listed at `man 7 signal` or
336 * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
337 */
338
339 if (preexec_fn != Py_None) {
340 /* We'll be calling back into Python later so we need to do this.
341 * This call may not be async-signal-safe but neither is calling
342 * back into Python. The user asked us to use hope as a strategy
343 * to avoid deadlock... */
344 PyOS_AfterFork();
345 }
346
347 child_exec(exec_array, argv, envp, cwd,
348 p2cread, p2cwrite, c2pread, c2pwrite,
349 errread, errwrite, errpipe_read, errpipe_write,
350 close_fds, restore_signals, call_setsid,
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000351 num_fds_to_keep, py_fds_to_keep,
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000352 preexec_fn, preexec_fn_args_tuple);
353 _exit(255);
354 return NULL; /* Dead code to avoid a potential compiler warning. */
355 }
Victor Stinner0e59cc32010-04-16 23:49:32 +0000356 Py_XDECREF(cwd_obj2);
357
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000358 if (pid == -1) {
359 /* Capture the errno exception before errno can be clobbered. */
360 PyErr_SetFromErrno(PyExc_OSError);
361 }
362 if (preexec_fn != Py_None &&
363 _PyImport_ReleaseLock() < 0 && !PyErr_Occurred()) {
364 PyErr_SetString(PyExc_RuntimeError,
365 "not holding the import lock");
366 }
367
368 /* Parent process */
369 if (envp)
370 _Py_FreeCharPArray(envp);
371 if (argv)
372 _Py_FreeCharPArray(argv);
373 _Py_FreeCharPArray(exec_array);
374
375 /* Reenable gc in the parent process (or if fork failed). */
376 if (need_to_reenable_gc && _enable_gc(gc_module)) {
377 Py_XDECREF(gc_module);
378 return NULL;
379 }
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000380 Py_XDECREF(preexec_fn_args_tuple);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000381 Py_XDECREF(gc_module);
382
383 if (pid == -1)
384 return NULL; /* fork() failed. Exception set earlier. */
385
386 return PyLong_FromPid(pid);
387
388cleanup:
389 if (envp)
390 _Py_FreeCharPArray(envp);
391 if (argv)
392 _Py_FreeCharPArray(argv);
393 _Py_FreeCharPArray(exec_array);
394 Py_XDECREF(converted_args);
Gregory P. Smith68f52172010-03-15 06:07:42 +0000395 Py_XDECREF(fast_args);
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000396 Py_XDECREF(preexec_fn_args_tuple);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000397
398 /* Reenable gc if it was disabled. */
399 if (need_to_reenable_gc)
400 _enable_gc(gc_module);
401 Py_XDECREF(gc_module);
402 return NULL;
403}
404
405
406PyDoc_STRVAR(subprocess_fork_exec_doc,
407"fork_exec(args, executable_list, close_fds, cwd, env,\n\
408 p2cread, p2cwrite, c2pread, c2pwrite,\n\
409 errread, errwrite, errpipe_read, errpipe_write,\n\
410 restore_signals, call_setsid, preexec_fn)\n\
411\n\
412Forks a child process, closes parent file descriptors as appropriate in the\n\
413child and dups the few that are needed before calling exec() in the child\n\
414process.\n\
415\n\
416The preexec_fn, if supplied, will be called immediately before exec.\n\
417WARNING: preexec_fn is NOT SAFE if your application uses threads.\n\
418 It may trigger infrequent, difficult to debug deadlocks.\n\
419\n\
420If an error occurs in the child process before the exec, it is\n\
421serialized and written to the errpipe_write fd per subprocess.py.\n\
422\n\
423Returns: the child process's PID.\n\
424\n\
425Raises: Only on an error in the parent process.\n\
426");
427
Gregory P. Smith51ee2702010-12-13 07:59:39 +0000428PyDoc_STRVAR(subprocess_cloexec_pipe_doc,
429"cloexec_pipe() -> (read_end, write_end)\n\n\
430Create a pipe whose ends have the cloexec flag set.");
431
432static PyObject *
433subprocess_cloexec_pipe(PyObject *self, PyObject *noargs)
434{
435 int fds[2];
436 int res;
437#ifdef HAVE_PIPE2
438 Py_BEGIN_ALLOW_THREADS
439 res = pipe2(fds, O_CLOEXEC);
440 Py_END_ALLOW_THREADS
Gregory P. Smithabcfcba2011-01-02 20:52:48 +0000441 if (res != 0 && errno == ENOSYS)
442 {
Gregory P. Smithabcfcba2011-01-02 20:52:48 +0000443 {
444#endif
445 /* We hold the GIL which offers some protection from other code calling
446 * fork() before the CLOEXEC flags have been set but we can't guarantee
447 * anything without pipe2(). */
448 long oldflags;
Gregory P. Smith51ee2702010-12-13 07:59:39 +0000449
Gregory P. Smithabcfcba2011-01-02 20:52:48 +0000450 res = pipe(fds);
Gregory P. Smith51ee2702010-12-13 07:59:39 +0000451
Gregory P. Smithabcfcba2011-01-02 20:52:48 +0000452 if (res == 0) {
453 oldflags = fcntl(fds[0], F_GETFD, 0);
454 if (oldflags < 0) res = oldflags;
455 }
456 if (res == 0)
457 res = fcntl(fds[0], F_SETFD, oldflags | FD_CLOEXEC);
458
459 if (res == 0) {
460 oldflags = fcntl(fds[1], F_GETFD, 0);
461 if (oldflags < 0) res = oldflags;
462 }
463 if (res == 0)
464 res = fcntl(fds[1], F_SETFD, oldflags | FD_CLOEXEC);
465#ifdef HAVE_PIPE2
466 }
Gregory P. Smith51ee2702010-12-13 07:59:39 +0000467 }
Gregory P. Smith51ee2702010-12-13 07:59:39 +0000468#endif
469 if (res != 0)
470 return PyErr_SetFromErrno(PyExc_OSError);
471 return Py_BuildValue("(ii)", fds[0], fds[1]);
472}
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000473
474/* module level code ********************************************************/
475
476PyDoc_STRVAR(module_doc,
477"A POSIX helper for the subprocess module.");
478
479
480static PyMethodDef module_methods[] = {
481 {"fork_exec", subprocess_fork_exec, METH_VARARGS, subprocess_fork_exec_doc},
Gregory P. Smith51ee2702010-12-13 07:59:39 +0000482 {"cloexec_pipe", subprocess_cloexec_pipe, METH_NOARGS, subprocess_cloexec_pipe_doc},
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000483 {NULL, NULL} /* sentinel */
484};
485
486
487static struct PyModuleDef _posixsubprocessmodule = {
488 PyModuleDef_HEAD_INIT,
489 "_posixsubprocess",
490 module_doc,
491 -1, /* No memory is needed. */
492 module_methods,
493};
494
495PyMODINIT_FUNC
496PyInit__posixsubprocess(void)
497{
498#ifdef _SC_OPEN_MAX
499 max_fd = sysconf(_SC_OPEN_MAX);
500 if (max_fd == -1)
501#endif
502 max_fd = 256; /* Matches Lib/subprocess.py */
503
504 return PyModule_Create(&_posixsubprocessmodule);
505}