diff options
author | Gregory P. Smith <greg@mad-scientist.com> | 2010-12-13 07:59:39 (GMT) |
---|---|---|
committer | Gregory P. Smith <greg@mad-scientist.com> | 2010-12-13 07:59:39 (GMT) |
commit | 51ee270876f4e18ec579e57772e16fce146d805e (patch) | |
tree | ca518334c744fca3ed243def81dd72d4b9f0c8ba /Lib/subprocess.py | |
parent | f5604853889bfbbf84b48311c63c0e775dff38cc (diff) | |
download | cpython-51ee270876f4e18ec579e57772e16fce146d805e.zip cpython-51ee270876f4e18ec579e57772e16fce146d805e.tar.gz cpython-51ee270876f4e18ec579e57772e16fce146d805e.tar.bz2 |
issue7213: Open the pipes used by subprocesses with the FD_CLOEXEC flag from
the C code, using pipe2() when available. Adds unittests for close_fds and
cloexec behaviors.
Diffstat (limited to 'Lib/subprocess.py')
-rw-r--r-- | Lib/subprocess.py | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 62dfd36..729a53b 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -390,6 +390,23 @@ else: # POSIX defines PIPE_BUF as >= 512. _PIPE_BUF = getattr(select, 'PIPE_BUF', 512) + if _posixsubprocess: + _create_pipe = _posixsubprocess.cloexec_pipe + else: + def _create_pipe(): + try: + cloexec_flag = fcntl.FD_CLOEXEC + except AttributeError: + cloexec_flag = 1 + + fds = os.pipe() + + old = fcntl.fcntl(fds[0], fcntl.F_GETFD) + fcntl.fcntl(fds[0], fcntl.F_SETFD, old | cloexec_flag) + old = fcntl.fcntl(fds[1], fcntl.F_GETFD) + fcntl.fcntl(fds[1], fcntl.F_SETFD, old | cloexec_flag) + + return fds __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput", "getoutput", "check_output", "CalledProcessError"] @@ -1031,7 +1048,7 @@ class Popen(object): if stdin is None: pass elif stdin == PIPE: - p2cread, p2cwrite = os.pipe() + p2cread, p2cwrite = _create_pipe() elif isinstance(stdin, int): p2cread = stdin else: @@ -1041,7 +1058,7 @@ class Popen(object): if stdout is None: pass elif stdout == PIPE: - c2pread, c2pwrite = os.pipe() + c2pread, c2pwrite = _create_pipe() elif isinstance(stdout, int): c2pwrite = stdout else: @@ -1051,7 +1068,7 @@ class Popen(object): if stderr is None: pass elif stderr == PIPE: - errread, errwrite = os.pipe() + errread, errwrite = _create_pipe() elif stderr == STDOUT: errwrite = c2pwrite elif isinstance(stderr, int): @@ -1065,16 +1082,6 @@ class Popen(object): errread, errwrite) - def _set_cloexec_flag(self, fd): - try: - cloexec_flag = fcntl.FD_CLOEXEC - except AttributeError: - cloexec_flag = 1 - - old = fcntl.fcntl(fd, fcntl.F_GETFD) - fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag) - - def _close_fds(self, but): os.closerange(3, but) os.closerange(but + 1, MAXFD) @@ -1116,10 +1123,9 @@ class Popen(object): # For transferring possible exec failure from child to parent. # Data format: "exception name:hex errno:description" # Pickle is not used; it is complex and involves memory allocation. - errpipe_read, errpipe_write = os.pipe() + errpipe_read, errpipe_write = _create_pipe() try: try: - self._set_cloexec_flag(errpipe_write) if _posixsubprocess: # We must avoid complex work that could involve |