commit:     9a56879ec26bfb39dc3551932d664fd6bec80500
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sun Oct 22 16:46:22 2023 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sun Oct 22 17:42:26 2023 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=9a56879e

SpawnProcess/ForkProcess: Pass stdin via fd_pipes if not background

Bug: https://bugs.gentoo.org/916116
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/_emerge/SpawnProcess.py                     |  2 +-
 lib/portage/tests/process/test_AsyncFunction.py | 33 ++++++++++++++++---------
 lib/portage/util/_async/ForkProcess.py          |  2 +-
 3 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/lib/_emerge/SpawnProcess.py b/lib/_emerge/SpawnProcess.py
index b4eabd07ad..72fa72c613 100644
--- a/lib/_emerge/SpawnProcess.py
+++ b/lib/_emerge/SpawnProcess.py
@@ -62,7 +62,7 @@ class SpawnProcess(SubProcess):
             self.fd_pipes = self.fd_pipes.copy()
         fd_pipes = self.fd_pipes
 
-        if fd_pipes or self.logfile:
+        if fd_pipes or self.logfile or not self.background:
             master_fd, slave_fd = self._pipe(fd_pipes)
 
             can_log = self._can_log(slave_fd)

diff --git a/lib/portage/tests/process/test_AsyncFunction.py 
b/lib/portage/tests/process/test_AsyncFunction.py
index e30ff770b3..d02a3395c1 100644
--- a/lib/portage/tests/process/test_AsyncFunction.py
+++ b/lib/portage/tests/process/test_AsyncFunction.py
@@ -16,25 +16,36 @@ from portage.util.futures.unix_events import 
_set_nonblocking
 
 class AsyncFunctionTestCase(TestCase):
     @staticmethod
-    def _read_from_stdin(pr, pw):
+    def _read_from_stdin(pw):
         if pw is not None:
             os.close(pw)
-        os.dup2(pr.fileno(), sys.stdin.fileno())
         return "".join(sys.stdin)
 
     async def _testAsyncFunctionStdin(self, loop):
         test_string = "1\n2\n3\n"
         pr, pw = multiprocessing.Pipe(duplex=False)
-        reader = AsyncFunction(
-            scheduler=loop,
-            target=self._read_from_stdin,
-            args=(
-                pr,
-                pw.fileno() if multiprocessing.get_start_method() == "fork" 
else None,
-            ),
-        )
-        reader.start()
+        stdin_backup = os.dup(portage._get_stdin().fileno())
+        os.dup2(pr.fileno(), portage._get_stdin().fileno())
         pr.close()
+        try:
+            reader = AsyncFunction(
+                # Should automatically inherit stdin as fd_pipes[0]
+                # when background is False, for things like
+                # emerge --sync --ask (bug 916116).
+                background=False,
+                scheduler=loop,
+                target=self._read_from_stdin,
+                args=(
+                    pw.fileno()
+                    if multiprocessing.get_start_method() == "fork"
+                    else None,
+                ),
+            )
+            reader.start()
+        finally:
+            os.dup2(stdin_backup, portage._get_stdin().fileno())
+            os.close(stdin_backup)
+
         _set_nonblocking(pw.fileno())
         with open(pw.fileno(), mode="wb", buffering=0, closefd=False) as 
pipe_write:
             await _writer(pipe_write, test_string.encode("utf_8"))

diff --git a/lib/portage/util/_async/ForkProcess.py 
b/lib/portage/util/_async/ForkProcess.py
index 6d216a5c43..780545be0e 100644
--- a/lib/portage/util/_async/ForkProcess.py
+++ b/lib/portage/util/_async/ForkProcess.py
@@ -52,7 +52,7 @@ class ForkProcess(SpawnProcess):
                 'fd_pipes only supported with HAVE_SEND_HANDLE or 
multiprocessing start method "fork"'
             )
 
-        if self.fd_pipes or self.logfile:
+        if self.fd_pipes or self.logfile or not self.background:
             # Log via multiprocessing.Pipe if necessary.
             connection, self._child_connection = multiprocessing.Pipe(
                 duplex=self._HAVE_SEND_HANDLE

Reply via email to