Merge 3.4 (asyncio)
This commit is contained in:
commit
d625a1819d
|
@ -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)
|
||||
|
|
|
@ -198,6 +198,27 @@ class SubprocessMixin:
|
|||
self.assertTrue(transport.pause_reading.called)
|
||||
self.assertTrue(transport.resume_reading.called)
|
||||
|
||||
def test_stdin_not_inheritable(self):
|
||||
# Tulip issue #209: stdin must not be inheritable, otherwise
|
||||
# the Process.communicate() hangs
|
||||
@asyncio.coroutine
|
||||
def len_message(message):
|
||||
code = 'import sys; data = sys.stdin.read(); print(len(data))'
|
||||
proc = yield from asyncio.create_subprocess_exec(
|
||||
sys.executable, '-c', code,
|
||||
stdin=asyncio.subprocess.PIPE,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
close_fds=False,
|
||||
loop=self.loop)
|
||||
stdout, stderr = yield from proc.communicate(message)
|
||||
exitcode = yield from proc.wait()
|
||||
return (stdout, exitcode)
|
||||
|
||||
output, exitcode = self.loop.run_until_complete(len_message(b'abc'))
|
||||
self.assertEqual(output.rstrip(), b'3')
|
||||
self.assertEqual(exitcode, 0)
|
||||
|
||||
|
||||
if sys.platform != 'win32':
|
||||
# Unix
|
||||
|
|
Loading…
Reference in New Issue