]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-46364: Use sockets for stdin of asyncio only on AIX (GH-30596)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 13 Oct 2022 17:27:14 +0000 (10:27 -0700)
committerGitHub <noreply@github.com>
Thu, 13 Oct 2022 17:27:14 +0000 (10:27 -0700)
Signed-off-by: Christoph Hamsen <hamsen.christoph@posteo.de>
Co-authored-by: July Tikhonov <july.tikh@gmail.com>
(cherry picked from commit c9ed0327a9c741a1808926b409df29467baf303a)

Co-authored-by: Christoph Hamsen <37963496+xopham@users.noreply.github.com>
Lib/asyncio/unix_events.py
Lib/test/test_asyncio/test_subprocess.py
Misc/NEWS.d/next/Library/2022-01-14-10-49-20.bpo-46364.SzhlU9.rst [new file with mode: 0644]

index 39b5e8382e161e6bc1ff504a7d46ba5fa803a5a4..faaca305c98da775d278fd29220bc2bcd6fab8ab 100644 (file)
@@ -789,12 +789,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(
index 14fa6dd76f9ca867d7ae2149d8da81923215f4e3..7cd80fd68e3ba434bd3997c238db9f1999d98a24 100644 (file)
@@ -401,6 +401,26 @@ class SubprocessMixin:
         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()
 
diff --git a/Misc/NEWS.d/next/Library/2022-01-14-10-49-20.bpo-46364.SzhlU9.rst b/Misc/NEWS.d/next/Library/2022-01-14-10-49-20.bpo-46364.SzhlU9.rst
new file mode 100644 (file)
index 0000000..d547ffc
--- /dev/null
@@ -0,0 +1 @@
+Restrict use of sockets instead of pipes for stdin of subprocesses created by :mod:`asyncio` to AIX platform only.