diff options
author | Zac Medico <zmedico@gentoo.org> | 2013-09-01 16:57:02 -0700 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2013-09-01 16:57:02 -0700 |
commit | bd2128b7a750a68470f857162784e55b8ac39de2 (patch) | |
tree | a762944fda2c55e6e7295ad54de783de91011ad8 | |
parent | _setup_pipes: os.set_inheritable() for Python 3.4 (diff) | |
download | portage-bd2128b7a750a68470f857162784e55b8ac39de2.tar.gz portage-bd2128b7a750a68470f857162784e55b8ac39de2.tar.bz2 portage-bd2128b7a750a68470f857162784e55b8ac39de2.zip |
_setup_pipes: copy descriptor flags after dup2
-rw-r--r-- | pym/portage/process.py | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/pym/portage/process.py b/pym/portage/process.py index 3ec6d70cf..2a2fcac77 100644 --- a/pym/portage/process.py +++ b/pym/portage/process.py @@ -35,6 +35,17 @@ except ImportError: if sys.hexversion >= 0x3000000: basestring = str +# Support PEP 446 for Python >=3.4 +try: + _set_inheritable = _os.set_inheritable +except AttributeError: + _set_inheritable = None + +try: + _FD_CLOEXEC = fcntl.FD_CLOEXEC +except AttributeError: + _FD_CLOEXEC = None + # Prefer /proc/self/fd if available (/dev/fd # doesn't work on solaris, see bug #474536). for _fd_dir in ("/proc/self/fd", "/dev/fd"): @@ -539,12 +550,6 @@ def _setup_pipes(fd_pipes, close_fds=True, inheritable=None): interference. """ - # Support PEP 446 for Python >=3.4 - try: - set_inheritable = _os.set_inheritable - except AttributeError: - set_inheritable = None - reverse_map = {} # To protect from cases where direct assignment could # clobber needed fds ({1:2, 2:1}) we create a reverse map @@ -564,6 +569,7 @@ def _setup_pipes(fd_pipes, close_fds=True, inheritable=None): while reverse_map: oldfd, newfds = reverse_map.popitem() + old_fdflags = None for newfd in newfds: if newfd in reverse_map: @@ -574,14 +580,26 @@ def _setup_pipes(fd_pipes, close_fds=True, inheritable=None): # unused file discriptors). backup_fd = os.dup(newfd) reverse_map[backup_fd] = reverse_map.pop(newfd) + if oldfd != newfd: os.dup2(oldfd, newfd) + if old_fdflags is None: + old_fdflags = fcntl.fcntl(oldfd, fcntl.F_GETFD) + fcntl.fcntl(newfd, fcntl.F_SETFD, old_fdflags) + + if _set_inheritable is not None: + + inheritable_state = None + if not (old_fdflags is None or _FD_CLOEXEC is None): + inheritable_state = not bool(old_fdflags & _FD_CLOEXEC) - if set_inheritable is not None: if inheritable is not None: - set_inheritable(newfd, inheritable) + if inheritable_state is not inheritable: + _set_inheritable(newfd, inheritable) + elif newfd in (0, 1, 2): - set_inheritable(newfd, True) + if inheritable_state is not True: + _set_inheritable(newfd, True) if oldfd not in fd_pipes: # If oldfd is not a key in fd_pipes, then it's safe |