summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio/unix_events.py
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2014-12-11 22:30:17 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2014-12-11 22:30:17 (GMT)
commit1e40f10886f1c83e47f69ab229b27ab2eceff939 (patch)
treec179e9c1d536065d17c2c3dbc09576272dbd2ce5 /Lib/asyncio/unix_events.py
parentdf75d5b402fa7d9377dd6e38f3ad7551de6746d5 (diff)
downloadcpython-1e40f10886f1c83e47f69ab229b27ab2eceff939.zip
cpython-1e40f10886f1c83e47f69ab229b27ab2eceff939.tar.gz
cpython-1e40f10886f1c83e47f69ab229b27ab2eceff939.tar.bz2
asyncio, tulip issue 209: Fix subprocess for close_fds=False on Python 3.3
Mark the write end of the stdin pipe as non-inheritable.
Diffstat (limited to 'Lib/asyncio/unix_events.py')
-rw-r--r--Lib/asyncio/unix_events.py22
1 files changed, 22 insertions, 0 deletions
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index d5db4d5..d1461fd 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -547,6 +547,22 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
self._loop = None
+if hasattr(os, 'set_inheritable'):
+ # Python 3.4 and newer
+ _set_inheritable = os.set_inheritable
+else:
+ import fcntl
+
+ def _set_inheritable(fd, inheritable):
+ cloexec_flag = getattr(fcntl, 'FD_CLOEXEC', 1)
+
+ old = fcntl.fcntl(fd, fcntl.F_GETFD)
+ if not inheritable:
+ fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag)
+ else:
+ fcntl.fcntl(fd, fcntl.F_SETFD, old & ~cloexec_flag)
+
+
class _UnixSubprocessTransport(base_subprocess.BaseSubprocessTransport):
def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs):
@@ -558,6 +574,12 @@ class _UnixSubprocessTransport(base_subprocess.BaseSubprocessTransport):
# other end). Notably this is needed on AIX, and works
# just fine on other platforms.
stdin, stdin_w = self._loop._socketpair()
+
+ # Mark the write end of the stdin pipe as non-inheritable,
+ # needed by close_fds=False on Python 3.3 and older
+ # (Python 3.4 implements the PEP 446, socketpair returns
+ # non-inheritable sockets)
+ _set_inheritable(stdin_w.fileno(), False)
self._proc = subprocess.Popen(
args, shell=shell, stdin=stdin, stdout=stdout, stderr=stderr,
universal_newlines=False, bufsize=bufsize, **kwargs)