From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id EE5FA15815E for ; Tue, 6 Feb 2024 02:24:24 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id E97E5E2A79; Tue, 6 Feb 2024 02:24:23 +0000 (UTC) Received: from smtp.gentoo.org (mail.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id C8377E2A79 for ; Tue, 6 Feb 2024 02:24:23 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id A318A34309D for ; Tue, 6 Feb 2024 02:24:22 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id B5C8614AB for ; Tue, 6 Feb 2024 02:24:20 +0000 (UTC) From: "Zac Medico" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Zac Medico" Message-ID: <1707183021.e8b31c86eaed645a8740fb2844e2935aee161e43.zmedico@gentoo> Subject: [gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/util/_async/ X-VCS-Repository: proj/portage X-VCS-Files: lib/_emerge/SpawnProcess.py lib/portage/util/_async/ForkProcess.py X-VCS-Directories: lib/_emerge/ lib/portage/util/_async/ X-VCS-Committer: zmedico X-VCS-Committer-Name: Zac Medico X-VCS-Revision: e8b31c86eaed645a8740fb2844e2935aee161e43 X-VCS-Branch: master Date: Tue, 6 Feb 2024 02:24:20 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 6bc4423a-fac1-40ff-8c54-a3a6913097e7 X-Archives-Hash: 22e80b4ab001fb36b679170698010038 commit: e8b31c86eaed645a8740fb2844e2935aee161e43 Author: Zac Medico gentoo org> AuthorDate: Mon Feb 5 05:55:11 2024 +0000 Commit: Zac Medico gentoo org> CommitDate: Tue Feb 6 01:30:21 2024 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=e8b31c86 ForkProcess: Prevent redundant pipe and set_term_size recursion When process.spawn is updated to call ForkProcess for bug 916566, it needs to avoid recursion via set_term_size. Bug: https://bugs.gentoo.org/916566 Bug: https://bugs.gentoo.org/923750 Signed-off-by: Zac Medico gentoo.org> lib/_emerge/SpawnProcess.py | 31 ++++++++++++++++++++++++------- lib/portage/util/_async/ForkProcess.py | 28 +++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/lib/_emerge/SpawnProcess.py b/lib/_emerge/SpawnProcess.py index 7f4a23892b..716e94d665 100644 --- a/lib/_emerge/SpawnProcess.py +++ b/lib/_emerge/SpawnProcess.py @@ -41,7 +41,7 @@ class SpawnProcess(SubProcess): ) __slots__ = ( - ("args", "log_filter_file") + ("args", "create_pipe", "log_filter_file") + _spawn_kwarg_names + ( "_main_task", @@ -60,15 +60,30 @@ class SpawnProcess(SubProcess): else: self.fd_pipes = self.fd_pipes.copy() fd_pipes = self.fd_pipes + log_file_path = None if fd_pipes or self.logfile or not self.background: - master_fd, slave_fd = self._pipe(fd_pipes) + if self.create_pipe is not False: + master_fd, slave_fd = self._pipe(fd_pipes) - can_log = self._can_log(slave_fd) - if can_log: - log_file_path = self.logfile + can_log = self._can_log(slave_fd) + if can_log: + log_file_path = self.logfile else: - log_file_path = None + if self.logfile: + raise NotImplementedError( + "logfile conflicts with create_pipe=False" + ) + # When called via process.spawn and ForkProcess._start, + # SpawnProcess will have created a pipe earlier, so it + # would be redundant to do it here (it could also trigger + # spawn recursion via set_term_size as in bug 923750). + # Use /dev/null for master_fd, triggering early return + # of _main, followed by _async_waitpid. + # TODO: Optimize away the need for master_fd here. + master_fd = os.open(os.devnull, os.O_RDONLY) + slave_fd = None + can_log = False null_input = None if not self.background or 0 in fd_pipes: @@ -97,7 +112,9 @@ class SpawnProcess(SubProcess): fd_pipes_orig = fd_pipes.copy() - if log_file_path is not None or self.background: + if slave_fd is None: + pass + elif log_file_path is not None or self.background: fd_pipes[1] = slave_fd fd_pipes[2] = slave_fd diff --git a/lib/portage/util/_async/ForkProcess.py b/lib/portage/util/_async/ForkProcess.py index 3acbe34fc6..cb240d0712 100644 --- a/lib/portage/util/_async/ForkProcess.py +++ b/lib/portage/util/_async/ForkProcess.py @@ -75,12 +75,29 @@ class ForkProcess(SpawnProcess): self.fd_pipes.setdefault(0, portage._get_stdin().fileno()) self.fd_pipes.setdefault(1, sys.__stdout__.fileno()) self.fd_pipes.setdefault(2, sys.__stderr__.fileno()) - stdout_fd = os.dup(self.fd_pipes[1]) + if self.create_pipe is not False: + stdout_fd = os.dup(self.fd_pipes[1]) if self._HAVE_SEND_HANDLE: - master_fd, slave_fd = self._pipe(self.fd_pipes) - self.fd_pipes[1] = slave_fd - self.fd_pipes[2] = slave_fd + if self.create_pipe is not False: + master_fd, slave_fd = self._pipe(self.fd_pipes) + self.fd_pipes[1] = slave_fd + self.fd_pipes[2] = slave_fd + else: + if self.logfile: + raise NotImplementedError( + "logfile conflicts with create_pipe=False" + ) + # When called via process.spawn, SpawnProcess + # will have created a pipe earlier, so it would be + # redundant to do it here (it could also trigger spawn + # recursion via set_term_size as in bug 923750). Use + # /dev/null for master_fd, triggering early return + # of _main, followed by _async_waitpid. + # TODO: Optimize away the need for master_fd here. + master_fd = os.open(os.devnull, os.O_RDONLY) + slave_fd = None + self._files = self._files_dict(connection=connection, slave_fd=slave_fd) # Create duplicate file descriptors in self._fd_pipes @@ -167,7 +184,8 @@ class ForkProcess(SpawnProcess): self._files.connection.close() del self._files.connection if hasattr(self._files, "slave_fd"): - os.close(self._files.slave_fd) + if self._files.slave_fd is not None: + os.close(self._files.slave_fd) del self._files.slave_fd await super()._main(build_logger, pipe_logger, loop=loop)