Skip to content

Commit

Permalink
bpo-46364: Use sockets for stdin of asyncio only on AIX (pythonGH-30596)
Browse files Browse the repository at this point in the history
Signed-off-by: Christoph Hamsen <hamsen.christoph@posteo.de>
Co-authored-by: July Tikhonov <july.tikh@gmail.com>
(cherry picked from commit c9ed032)

Co-authored-by: Christoph Hamsen <37963496+xopham@users.noreply.github.com>
  • Loading branch information
xopham authored and miss-islington committed Oct 13, 2022
1 parent c7761bb commit c482e9a
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
7 changes: 3 additions & 4 deletions Lib/asyncio/unix_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -800,12 +800,11 @@ class _UnixSubprocessTransport(base_subprocess.BaseSubprocessTransport):

def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs):
stdin_w = None
if stdin == subprocess.PIPE:
# Use a socket pair for stdin, since not all platforms
if stdin == subprocess.PIPE and sys.platform.startswith('aix'):
# Use a socket pair for stdin on AIX, since it does not
# support selecting read events on the write end of a
# socket (which we use in order to detect closing of the
# other end). Notably this is needed on AIX, and works
# just fine on other platforms.
# other end).
stdin, stdin_w = socket.socketpair()
try:
self._proc = subprocess.Popen(
Expand Down
20 changes: 20 additions & 0 deletions Lib/test/test_asyncio/test_subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,26 @@ async def empty_error():
self.assertEqual(output, None)
self.assertEqual(exitcode, 0)

@unittest.skipIf(sys.platform != 'linux', "Don't have /dev/stdin")
def test_devstdin_input(self):

async def devstdin_input(message):
code = 'file = open("/dev/stdin"); data = file.read(); print(len(data))'
proc = await asyncio.create_subprocess_exec(
sys.executable, '-c', code,
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
close_fds=False,
)
stdout, stderr = await proc.communicate(message)
exitcode = await proc.wait()
return (stdout, exitcode)

output, exitcode = self.loop.run_until_complete(devstdin_input(b'abc'))
self.assertEqual(output.rstrip(), b'3')
self.assertEqual(exitcode, 0)

def test_cancel_process_wait(self):
# Issue #23140: cancel Process.wait()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Restrict use of sockets instead of pipes for stdin of subprocesses created by :mod:`asyncio` to AIX platform only.

0 comments on commit c482e9a

Please sign in to comment.