blob: e6a9283c0a4e348c2702360203188ae1a7689c47 [file] [log] [blame]
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001/* Authors: Gregory P. Smith & Jeffrey Yasskin */
2#include "Python.h"
Victor Stinner5572ba72011-05-26 14:10:08 +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;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020021 _Py_identifier(enable);
22
23 result = _PyObject_CallMethodId(gc_module, &PyId_enable, NULL);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000024 if (result == NULL)
25 return 1;
26 Py_DECREF(result);
27 return 0;
28}
29
30
31/*
32 * This function is code executed in the child process immediately after fork
33 * to set things up and call exec().
34 *
35 * All of the code in this function must only use async-signal-safe functions,
36 * listed at `man 7 signal` or
37 * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
38 *
39 * This restriction is documented at
40 * http://www.opengroup.org/onlinepubs/009695399/functions/fork.html.
41 */
42static void child_exec(char *const exec_array[],
43 char *const argv[],
44 char *const envp[],
45 const char *cwd,
46 int p2cread, int p2cwrite,
47 int c2pread, int c2pwrite,
48 int errread, int errwrite,
49 int errpipe_read, int errpipe_write,
50 int close_fds, int restore_signals,
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +000051 int call_setsid, Py_ssize_t num_fds_to_keep,
52 PyObject *py_fds_to_keep,
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000053 PyObject *preexec_fn,
54 PyObject *preexec_fn_args_tuple)
55{
56 int i, saved_errno, fd_num;
57 PyObject *result;
Gregory P. Smith14affb82010-12-22 05:22:17 +000058 const char* err_msg = "";
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000059 /* Buffer large enough to hold a hex integer. We can't malloc. */
60 char hex_errno[sizeof(saved_errno)*2+1];
61
62 /* Close parent's pipe ends. */
63 if (p2cwrite != -1) {
64 POSIX_CALL(close(p2cwrite));
65 }
66 if (c2pread != -1) {
67 POSIX_CALL(close(c2pread));
68 }
69 if (errread != -1) {
70 POSIX_CALL(close(errread));
71 }
72 POSIX_CALL(close(errpipe_read));
73
Ross Lagerwalld98646e2011-07-27 07:16:31 +020074 /* When duping fds, if there arises a situation where one of the fds is
75 either 0, 1 or 2, it is possible that it is overwritten (#12607). */
76 if (c2pwrite == 0)
77 POSIX_CALL(c2pwrite = dup(c2pwrite));
78 if (errwrite == 0 || errwrite == 1)
79 POSIX_CALL(errwrite = dup(errwrite));
80
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +000081 /* Dup fds for child.
82 dup2() removes the CLOEXEC flag but we must do it ourselves if dup2()
83 would be a no-op (issue #10806). */
84 if (p2cread == 0) {
85 int old = fcntl(p2cread, F_GETFD);
86 if (old != -1)
87 fcntl(p2cread, F_SETFD, old & ~FD_CLOEXEC);
88 } else if (p2cread != -1) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000089 POSIX_CALL(dup2(p2cread, 0)); /* stdin */
90 }
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +000091 if (c2pwrite == 1) {
92 int old = fcntl(c2pwrite, F_GETFD);
93 if (old != -1)
94 fcntl(c2pwrite, F_SETFD, old & ~FD_CLOEXEC);
95 } else if (c2pwrite != -1) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000096 POSIX_CALL(dup2(c2pwrite, 1)); /* stdout */
97 }
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +000098 if (errwrite == 2) {
99 int old = fcntl(errwrite, F_GETFD);
100 if (old != -1)
101 fcntl(errwrite, F_SETFD, old & ~FD_CLOEXEC);
102 } else if (errwrite != -1) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000103 POSIX_CALL(dup2(errwrite, 2)); /* stderr */
104 }
105
106 /* Close pipe fds. Make sure we don't close the same fd more than */
107 /* once, or standard fds. */
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +0000108 if (p2cread > 2) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000109 POSIX_CALL(close(p2cread));
110 }
Gregory P. Smith81218982011-03-15 14:56:39 -0400111 if (c2pwrite > 2 && c2pwrite != p2cread) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000112 POSIX_CALL(close(c2pwrite));
113 }
Gregory P. Smith81218982011-03-15 14:56:39 -0400114 if (errwrite != c2pwrite && errwrite != p2cread && errwrite > 2) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000115 POSIX_CALL(close(errwrite));
116 }
117
118 /* close() is intentionally not checked for errors here as we are closing */
119 /* a large range of fds, some of which may be invalid. */
120 if (close_fds) {
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000121 Py_ssize_t keep_seq_idx;
122 int start_fd = 3;
123 for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) {
124 PyObject* py_keep_fd = PySequence_Fast_GET_ITEM(py_fds_to_keep,
125 keep_seq_idx);
126 int keep_fd = PyLong_AsLong(py_keep_fd);
127 if (keep_fd < 0) { /* Negative number, overflow or not a Long. */
128 err_msg = "bad value in fds_to_keep.";
129 errno = 0; /* We don't want to report an OSError. */
130 goto error;
131 }
Gregory P. Smith8edd99d2010-12-14 13:43:30 +0000132 if (keep_fd < start_fd)
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000133 continue;
134 for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) {
135 close(fd_num);
136 }
137 start_fd = keep_fd + 1;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000138 }
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000139 if (start_fd <= max_fd) {
140 for (fd_num = start_fd; fd_num < max_fd; ++fd_num) {
141 close(fd_num);
142 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000143 }
144 }
145
146 if (cwd)
147 POSIX_CALL(chdir(cwd));
148
149 if (restore_signals)
150 _Py_RestoreSignals();
151
152#ifdef HAVE_SETSID
153 if (call_setsid)
154 POSIX_CALL(setsid());
155#endif
156
157 if (preexec_fn != Py_None && preexec_fn_args_tuple) {
158 /* This is where the user has asked us to deadlock their program. */
159 result = PyObject_Call(preexec_fn, preexec_fn_args_tuple, NULL);
160 if (result == NULL) {
161 /* Stringifying the exception or traceback would involve
162 * memory allocation and thus potential for deadlock.
163 * We've already faced potential deadlock by calling back
164 * into Python in the first place, so it probably doesn't
165 * matter but we avoid it to minimize the possibility. */
166 err_msg = "Exception occurred in preexec_fn.";
167 errno = 0; /* We don't want to report an OSError. */
168 goto error;
169 }
170 /* Py_DECREF(result); - We're about to exec so why bother? */
171 }
172
173 /* This loop matches the Lib/os.py _execvpe()'s PATH search when */
174 /* given the executable_list generated by Lib/subprocess.py. */
175 saved_errno = 0;
176 for (i = 0; exec_array[i] != NULL; ++i) {
177 const char *executable = exec_array[i];
178 if (envp) {
179 execve(executable, argv, envp);
180 } else {
181 execv(executable, argv);
182 }
183 if (errno != ENOENT && errno != ENOTDIR && saved_errno == 0) {
184 saved_errno = errno;
185 }
186 }
187 /* Report the first exec error, not the last. */
188 if (saved_errno)
189 errno = saved_errno;
190
191error:
192 saved_errno = errno;
193 /* Report the posix error to our parent process. */
194 if (saved_errno) {
195 char *cur;
196 write(errpipe_write, "OSError:", 8);
197 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 }
202 write(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur);
203 write(errpipe_write, ":", 1);
204 /* 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 {
207 write(errpipe_write, "RuntimeError:0:", 15);
208 write(errpipe_write, err_msg, strlen(err_msg));
209 }
210}
211
212
213static PyObject *
214subprocess_fork_exec(PyObject* self, PyObject *args)
215{
216 PyObject *gc_module = NULL;
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000217 PyObject *executable_list, *py_close_fds, *py_fds_to_keep;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000218 PyObject *env_list, *preexec_fn;
Gregory P. Smith68f52172010-03-15 06:07:42 +0000219 PyObject *process_args, *converted_args = NULL, *fast_args = NULL;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000220 PyObject *preexec_fn_args_tuple = NULL;
221 int p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite;
222 int errpipe_read, errpipe_write, close_fds, restore_signals;
223 int call_setsid;
Victor Stinner0e59cc32010-04-16 23:49:32 +0000224 PyObject *cwd_obj, *cwd_obj2;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000225 const char *cwd;
226 pid_t pid;
227 int need_to_reenable_gc = 0;
228 char *const *exec_array, *const *argv = NULL, *const *envp = NULL;
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000229 Py_ssize_t arg_num, num_fds_to_keep;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000230
231 if (!PyArg_ParseTuple(
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000232 args, "OOOOOOiiiiiiiiiiO:fork_exec",
233 &process_args, &executable_list, &py_close_fds, &py_fds_to_keep,
Victor Stinner0e59cc32010-04-16 23:49:32 +0000234 &cwd_obj, &env_list,
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000235 &p2cread, &p2cwrite, &c2pread, &c2pwrite,
236 &errread, &errwrite, &errpipe_read, &errpipe_write,
237 &restore_signals, &call_setsid, &preexec_fn))
238 return NULL;
239
240 close_fds = PyObject_IsTrue(py_close_fds);
241 if (close_fds && errpipe_write < 3) { /* precondition */
242 PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3");
243 return NULL;
244 }
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000245 num_fds_to_keep = PySequence_Length(py_fds_to_keep);
246 if (num_fds_to_keep < 0) {
247 PyErr_SetString(PyExc_ValueError, "bad fds_to_keep");
248 return NULL;
249 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000250
251 /* We need to call gc.disable() when we'll be calling preexec_fn */
252 if (preexec_fn != Py_None) {
253 PyObject *result;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200254 _Py_identifier(isenabled);
255 _Py_identifier(disable);
256
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000257 gc_module = PyImport_ImportModule("gc");
258 if (gc_module == NULL)
259 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200260 result = _PyObject_CallMethodId(gc_module, &PyId_isenabled, NULL);
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000261 if (result == NULL) {
262 Py_DECREF(gc_module);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000263 return NULL;
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000264 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000265 need_to_reenable_gc = PyObject_IsTrue(result);
266 Py_DECREF(result);
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000267 if (need_to_reenable_gc == -1) {
268 Py_DECREF(gc_module);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000269 return NULL;
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000270 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200271 result = _PyObject_CallMethodId(gc_module, &PyId_disable, NULL);
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000272 if (result == NULL) {
273 Py_DECREF(gc_module);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000274 return NULL;
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000275 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000276 Py_DECREF(result);
277 }
278
279 exec_array = _PySequence_BytesToCharpArray(executable_list);
280 if (!exec_array)
281 return NULL;
282
283 /* Convert args and env into appropriate arguments for exec() */
284 /* These conversions are done in the parent process to avoid allocating
285 or freeing memory in the child process. */
286 if (process_args != Py_None) {
Gregory P. Smith68f52172010-03-15 06:07:42 +0000287 Py_ssize_t num_args;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000288 /* Equivalent to: */
289 /* tuple(PyUnicode_FSConverter(arg) for arg in process_args) */
Gregory P. Smith68f52172010-03-15 06:07:42 +0000290 fast_args = PySequence_Fast(process_args, "argv must be a tuple");
291 num_args = PySequence_Fast_GET_SIZE(fast_args);
292 converted_args = PyTuple_New(num_args);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000293 if (converted_args == NULL)
294 goto cleanup;
Gregory P. Smith68f52172010-03-15 06:07:42 +0000295 for (arg_num = 0; arg_num < num_args; ++arg_num) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000296 PyObject *borrowed_arg, *converted_arg;
Gregory P. Smith68f52172010-03-15 06:07:42 +0000297 borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000298 if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0)
299 goto cleanup;
300 PyTuple_SET_ITEM(converted_args, arg_num, converted_arg);
301 }
302
303 argv = _PySequence_BytesToCharpArray(converted_args);
304 Py_CLEAR(converted_args);
Gregory P. Smith68f52172010-03-15 06:07:42 +0000305 Py_CLEAR(fast_args);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000306 if (!argv)
307 goto cleanup;
308 }
309
310 if (env_list != Py_None) {
311 envp = _PySequence_BytesToCharpArray(env_list);
312 if (!envp)
313 goto cleanup;
314 }
315
316 if (preexec_fn != Py_None) {
317 preexec_fn_args_tuple = PyTuple_New(0);
318 if (!preexec_fn_args_tuple)
319 goto cleanup;
Victor Stinner0e59cc32010-04-16 23:49:32 +0000320 _PyImport_AcquireLock();
321 }
322
323 if (cwd_obj != Py_None) {
324 if (PyUnicode_FSConverter(cwd_obj, &cwd_obj2) == 0)
325 goto cleanup;
Victor Stinnerdcb24032010-04-22 12:08:36 +0000326 cwd = PyBytes_AsString(cwd_obj2);
Victor Stinner0e59cc32010-04-16 23:49:32 +0000327 } else {
328 cwd = NULL;
329 cwd_obj2 = NULL;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000330 }
331
332 pid = fork();
333 if (pid == 0) {
334 /* Child process */
Victor Stinner0e59cc32010-04-16 23:49:32 +0000335 /*
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000336 * Code from here to _exit() must only use async-signal-safe functions,
337 * listed at `man 7 signal` or
338 * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
339 */
340
341 if (preexec_fn != Py_None) {
342 /* We'll be calling back into Python later so we need to do this.
343 * This call may not be async-signal-safe but neither is calling
344 * back into Python. The user asked us to use hope as a strategy
345 * to avoid deadlock... */
346 PyOS_AfterFork();
347 }
348
349 child_exec(exec_array, argv, envp, cwd,
350 p2cread, p2cwrite, c2pread, c2pwrite,
351 errread, errwrite, errpipe_read, errpipe_write,
352 close_fds, restore_signals, call_setsid,
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000353 num_fds_to_keep, py_fds_to_keep,
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000354 preexec_fn, preexec_fn_args_tuple);
355 _exit(255);
356 return NULL; /* Dead code to avoid a potential compiler warning. */
357 }
Victor Stinner0e59cc32010-04-16 23:49:32 +0000358 Py_XDECREF(cwd_obj2);
359
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000360 if (pid == -1) {
361 /* Capture the errno exception before errno can be clobbered. */
362 PyErr_SetFromErrno(PyExc_OSError);
363 }
364 if (preexec_fn != Py_None &&
365 _PyImport_ReleaseLock() < 0 && !PyErr_Occurred()) {
366 PyErr_SetString(PyExc_RuntimeError,
367 "not holding the import lock");
368 }
369
370 /* Parent process */
371 if (envp)
372 _Py_FreeCharPArray(envp);
373 if (argv)
374 _Py_FreeCharPArray(argv);
375 _Py_FreeCharPArray(exec_array);
376
377 /* Reenable gc in the parent process (or if fork failed). */
378 if (need_to_reenable_gc && _enable_gc(gc_module)) {
379 Py_XDECREF(gc_module);
380 return NULL;
381 }
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000382 Py_XDECREF(preexec_fn_args_tuple);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000383 Py_XDECREF(gc_module);
384
385 if (pid == -1)
386 return NULL; /* fork() failed. Exception set earlier. */
387
388 return PyLong_FromPid(pid);
389
390cleanup:
391 if (envp)
392 _Py_FreeCharPArray(envp);
393 if (argv)
394 _Py_FreeCharPArray(argv);
395 _Py_FreeCharPArray(exec_array);
396 Py_XDECREF(converted_args);
Gregory P. Smith68f52172010-03-15 06:07:42 +0000397 Py_XDECREF(fast_args);
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000398 Py_XDECREF(preexec_fn_args_tuple);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000399
400 /* Reenable gc if it was disabled. */
401 if (need_to_reenable_gc)
402 _enable_gc(gc_module);
403 Py_XDECREF(gc_module);
404 return NULL;
405}
406
407
408PyDoc_STRVAR(subprocess_fork_exec_doc,
409"fork_exec(args, executable_list, close_fds, cwd, env,\n\
410 p2cread, p2cwrite, c2pread, c2pwrite,\n\
411 errread, errwrite, errpipe_read, errpipe_write,\n\
412 restore_signals, call_setsid, preexec_fn)\n\
413\n\
414Forks a child process, closes parent file descriptors as appropriate in the\n\
415child and dups the few that are needed before calling exec() in the child\n\
416process.\n\
417\n\
418The preexec_fn, if supplied, will be called immediately before exec.\n\
419WARNING: preexec_fn is NOT SAFE if your application uses threads.\n\
420 It may trigger infrequent, difficult to debug deadlocks.\n\
421\n\
422If an error occurs in the child process before the exec, it is\n\
423serialized and written to the errpipe_write fd per subprocess.py.\n\
424\n\
425Returns: the child process's PID.\n\
426\n\
427Raises: Only on an error in the parent process.\n\
428");
429
Gregory P. Smith51ee2702010-12-13 07:59:39 +0000430PyDoc_STRVAR(subprocess_cloexec_pipe_doc,
431"cloexec_pipe() -> (read_end, write_end)\n\n\
432Create a pipe whose ends have the cloexec flag set.");
433
434static PyObject *
435subprocess_cloexec_pipe(PyObject *self, PyObject *noargs)
436{
437 int fds[2];
438 int res;
439#ifdef HAVE_PIPE2
440 Py_BEGIN_ALLOW_THREADS
441 res = pipe2(fds, O_CLOEXEC);
442 Py_END_ALLOW_THREADS
Gregory P. Smithabcfcba2011-01-02 20:52:48 +0000443 if (res != 0 && errno == ENOSYS)
444 {
445 if (PyErr_WarnEx(
446 PyExc_RuntimeWarning,
447 "pipe2 set errno ENOSYS; falling "
448 "back to non-atomic pipe+fcntl.", 1) != 0) {
449 return NULL;
450 }
451 {
452#endif
453 /* We hold the GIL which offers some protection from other code calling
454 * fork() before the CLOEXEC flags have been set but we can't guarantee
455 * anything without pipe2(). */
456 long oldflags;
Gregory P. Smith51ee2702010-12-13 07:59:39 +0000457
Gregory P. Smithabcfcba2011-01-02 20:52:48 +0000458 res = pipe(fds);
Gregory P. Smith51ee2702010-12-13 07:59:39 +0000459
Gregory P. Smithabcfcba2011-01-02 20:52:48 +0000460 if (res == 0) {
461 oldflags = fcntl(fds[0], F_GETFD, 0);
462 if (oldflags < 0) res = oldflags;
463 }
464 if (res == 0)
465 res = fcntl(fds[0], F_SETFD, oldflags | FD_CLOEXEC);
466
467 if (res == 0) {
468 oldflags = fcntl(fds[1], F_GETFD, 0);
469 if (oldflags < 0) res = oldflags;
470 }
471 if (res == 0)
472 res = fcntl(fds[1], F_SETFD, oldflags | FD_CLOEXEC);
473#ifdef HAVE_PIPE2
474 }
Gregory P. Smith51ee2702010-12-13 07:59:39 +0000475 }
Gregory P. Smith51ee2702010-12-13 07:59:39 +0000476#endif
477 if (res != 0)
478 return PyErr_SetFromErrno(PyExc_OSError);
479 return Py_BuildValue("(ii)", fds[0], fds[1]);
480}
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000481
482/* module level code ********************************************************/
483
484PyDoc_STRVAR(module_doc,
485"A POSIX helper for the subprocess module.");
486
487
488static PyMethodDef module_methods[] = {
489 {"fork_exec", subprocess_fork_exec, METH_VARARGS, subprocess_fork_exec_doc},
Gregory P. Smith51ee2702010-12-13 07:59:39 +0000490 {"cloexec_pipe", subprocess_cloexec_pipe, METH_NOARGS, subprocess_cloexec_pipe_doc},
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000491 {NULL, NULL} /* sentinel */
492};
493
494
495static struct PyModuleDef _posixsubprocessmodule = {
496 PyModuleDef_HEAD_INIT,
497 "_posixsubprocess",
498 module_doc,
499 -1, /* No memory is needed. */
500 module_methods,
501};
502
503PyMODINIT_FUNC
504PyInit__posixsubprocess(void)
505{
506#ifdef _SC_OPEN_MAX
507 max_fd = sysconf(_SC_OPEN_MAX);
508 if (max_fd == -1)
509#endif
510 max_fd = 256; /* Matches Lib/subprocess.py */
511
512 return PyModule_Create(&_posixsubprocessmodule);
513}