diff options
-rw-r--r-- | pym/_emerge/EbuildFetcher.py | 6 | ||||
-rw-r--r-- | pym/portage/dbapi/_MergeProcess.py | 7 | ||||
-rw-r--r-- | pym/portage/process.py | 20 |
3 files changed, 22 insertions, 11 deletions
diff --git a/pym/_emerge/EbuildFetcher.py b/pym/_emerge/EbuildFetcher.py index 61c7848ad..6ad434129 100644 --- a/pym/_emerge/EbuildFetcher.py +++ b/pym/_emerge/EbuildFetcher.py @@ -6,6 +6,7 @@ import traceback from _emerge.SpawnProcess import SpawnProcess import copy import io +import platform import signal import sys import portage @@ -166,7 +167,10 @@ class EbuildFetcher(SpawnProcess): portage.process.spawned_pids.append(pid) return [pid] - portage.process._setup_pipes(fd_pipes) + # TODO: Find out why PyPy 1.8 with close_fds=True triggers + # "[Errno 9] Bad file descriptor" in subprocesses. + close_fds = platform.python_implementation() != 'PyPy' + portage.process._setup_pipes(fd_pipes, close_fds=close_fds) # Use default signal handlers in order to avoid problems # killing subprocesses as reported in bug #353239. diff --git a/pym/portage/dbapi/_MergeProcess.py b/pym/portage/dbapi/_MergeProcess.py index 9bb67c9b6..cf5926529 100644 --- a/pym/portage/dbapi/_MergeProcess.py +++ b/pym/portage/dbapi/_MergeProcess.py @@ -2,6 +2,7 @@ # Distributed under the terms of the GNU General Public License v2 import io +import platform import signal import traceback @@ -143,7 +144,11 @@ class MergeProcess(SpawnProcess): return [pid] os.close(elog_reader_fd) - portage.process._setup_pipes(fd_pipes) + + # TODO: Find out why PyPy 1.8 with close_fds=True triggers + # "[Errno 9] Bad file descriptor" in subprocesses. + close_fds = platform.python_implementation() != 'PyPy' + portage.process._setup_pipes(fd_pipes, close_fds=close_fds) # Use default signal handlers since the ones inherited # from the parent process are irrelevant here. diff --git a/pym/portage/process.py b/pym/portage/process.py index 47b0a2147..e7313abc3 100644 --- a/pym/portage/process.py +++ b/pym/portage/process.py @@ -386,7 +386,7 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask, # And switch to the new process. os.execve(binary, myargs, env) -def _setup_pipes(fd_pipes): +def _setup_pipes(fd_pipes, close_fds=True): """Setup pipes for a forked process.""" my_fds = {} # To protect from cases where direct assignment could @@ -397,14 +397,16 @@ def _setup_pipes(fd_pipes): # Then assign them to what they should be. for fd in my_fds: os.dup2(my_fds[fd], fd) - # Then close _all_ fds that haven't been explicitly - # requested to be kept open. - for fd in get_open_fds(): - if fd not in my_fds: - try: - os.close(fd) - except OSError: - pass + + if close_fds: + # Then close _all_ fds that haven't been explicitly + # requested to be kept open. + for fd in get_open_fds(): + if fd not in my_fds: + try: + os.close(fd) + except OSError: + pass def find_binary(binary): """ |