Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fb94c5f

Browse files
committed
* Replaces the internals of the subprocess module from fork through exec on
POSIX systems with a C extension module. This is required in order for the subprocess module to be made thread safe. The pure python implementation is retained so that it can continue to be used if for some reason the _posixsubprocess extension module is not available. The unittest executes tests on both code paths to guarantee compatibility. * Moves PyLong_FromPid and PyLong_AsPid from posixmodule.c into longobject.h. Code reviewed by jeffrey.yasskin at http://codereview.appspot.com/223077/show
1 parent dddd5e9 commit fb94c5f

11 files changed

Lines changed: 816 additions & 129 deletions

File tree

Doc/library/subprocess.rst

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Using the subprocess Module
2828
This module defines one class called :class:`Popen`:
2929

3030

31-
.. class:: Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
31+
.. class:: Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False)
3232

3333
Arguments are:
3434

@@ -41,7 +41,8 @@ This module defines one class called :class:`Popen`:
4141
name for the executing program in utilities such as :program:`ps`.
4242

4343
On Unix, with *shell=False* (default): In this case, the Popen class uses
44-
:meth:`os.execvp` to execute the child program. *args* should normally be a
44+
:meth:`os.execvp` like behavior to execute the child program.
45+
*args* should normally be a
4546
sequence. If a string is specified for *args*, it will be used as the name
4647
or path of the program to execute; this will only work if the program is
4748
being given no arguments.
@@ -108,7 +109,23 @@ This module defines one class called :class:`Popen`:
108109
applications should be captured into the same file handle as for stdout.
109110

110111
If *preexec_fn* is set to a callable object, this object will be called in the
111-
child process just before the child is executed. (Unix only)
112+
child process just before the child is executed.
113+
(Unix only)
114+
115+
.. warning::
116+
117+
The *preexec_fn* parameter is not safe to use in the presence of threads
118+
in your application. The child process could deadlock before exec is
119+
called.
120+
If you must use it, keep it trivial! Minimize the number of libraries
121+
you call into.
122+
123+
.. note::
124+
125+
If you need to modify the environment for the child use the *env*
126+
parameter rather than doing it in a *preexec_fn*.
127+
The *start_new_session* parameter can take the place of a previously
128+
common use of *preexec_fn* to call os.setsid() in the child.
112129

113130
If *close_fds* is true, all file descriptors except :const:`0`, :const:`1` and
114131
:const:`2` will be closed before the child process is executed. (Unix only).
@@ -124,9 +141,23 @@ This module defines one class called :class:`Popen`:
124141
searching the executable, so you can't specify the program's path relative to
125142
*cwd*.
126143

144+
If *restore_signals* is True (the default) all signals that Python has set to
145+
SIG_IGN are restored to SIG_DFL in the child process before the exec.
146+
Currently this includes the SIGPIPE, SIGXFZ and SIGXFSZ signals.
147+
(Unix only)
148+
149+
.. versionchanged:: 3.2
150+
*restore_signals* was added.
151+
152+
If *start_new_session* is True the setsid() system call will be made in the
153+
child process prior to the execution of the subprocess. (Unix only)
154+
155+
.. versionchanged:: 3.2
156+
*start_new_session* was added.
157+
127158
If *env* is not ``None``, it must be a mapping that defines the environment
128-
variables for the new process; these are used instead of inheriting the current
129-
process' environment, which is the default behavior.
159+
variables for the new process; these are used instead of the default
160+
behavior of inheriting the current process' environment.
130161

131162
.. note::
132163

Include/abstract.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,9 @@ PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls);
12321232

12331233
PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
12341234

1235+
PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self);
1236+
1237+
PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]);
12351238

12361239
#ifdef __cplusplus
12371240
}

Include/longobject.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,23 @@ PyAPI_FUNC(PyObject *) PyLong_GetInfo(void);
4141
#define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLongLong(fd)
4242
#endif
4343

44+
/* Issue #1983: pid_t can be longer than a C long on some systems */
45+
#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
46+
#define PARSE_PID "i"
47+
#define PyLong_FromPid PyLong_FromLong
48+
#define PyLong_AsPid PyLong_AsLong
49+
#elif SIZEOF_PID_T == SIZEOF_LONG
50+
#define PARSE_PID "l"
51+
#define PyLong_FromPid PyLong_FromLong
52+
#define PyLong_AsPid PyLong_AsLong
53+
#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
54+
#define PARSE_PID "L"
55+
#define PyLong_FromPid PyLong_FromLongLong
56+
#define PyLong_AsPid PyLong_AsLongLong
57+
#else
58+
#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
59+
#endif /* SIZEOF_PID_T */
60+
4461
/* For use by intobject.c only */
4562
PyAPI_DATA(unsigned char) _PyLong_DigitValue[256];
4663

Include/pythonrun.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ PyAPI_FUNC(int) Py_AtExit(void (*func)(void));
8181

8282
PyAPI_FUNC(void) Py_Exit(int);
8383

84+
/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */
85+
PyAPI_FUNC(void) _Py_RestoreSignals(void);
86+
8487
PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
8588

8689
/* Bootstrap */

0 commit comments

Comments
 (0)