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