aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2013-09-01 16:57:02 -0700
committerZac Medico <zmedico@gentoo.org>2013-09-01 16:57:02 -0700
commitbd2128b7a750a68470f857162784e55b8ac39de2 (patch)
treea762944fda2c55e6e7295ad54de783de91011ad8
parent_setup_pipes: os.set_inheritable() for Python 3.4 (diff)
downloadportage-bd2128b7a750a68470f857162784e55b8ac39de2.tar.gz
portage-bd2128b7a750a68470f857162784e55b8ac39de2.tar.bz2
portage-bd2128b7a750a68470f857162784e55b8ac39de2.zip
_setup_pipes: copy descriptor flags after dup2
-rw-r--r--pym/portage/process.py36
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