1 |
commit: bd2128b7a750a68470f857162784e55b8ac39de2 |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun Sep 1 23:57:02 2013 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Sep 1 23:57:02 2013 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=bd2128b7 |
7 |
|
8 |
_setup_pipes: copy descriptor flags after dup2 |
9 |
|
10 |
--- |
11 |
pym/portage/process.py | 36 +++++++++++++++++++++++++++--------- |
12 |
1 file changed, 27 insertions(+), 9 deletions(-) |
13 |
|
14 |
diff --git a/pym/portage/process.py b/pym/portage/process.py |
15 |
index 3ec6d70..2a2fcac 100644 |
16 |
--- a/pym/portage/process.py |
17 |
+++ b/pym/portage/process.py |
18 |
@@ -35,6 +35,17 @@ except ImportError: |
19 |
if sys.hexversion >= 0x3000000: |
20 |
basestring = str |
21 |
|
22 |
+# Support PEP 446 for Python >=3.4 |
23 |
+try: |
24 |
+ _set_inheritable = _os.set_inheritable |
25 |
+except AttributeError: |
26 |
+ _set_inheritable = None |
27 |
+ |
28 |
+try: |
29 |
+ _FD_CLOEXEC = fcntl.FD_CLOEXEC |
30 |
+except AttributeError: |
31 |
+ _FD_CLOEXEC = None |
32 |
+ |
33 |
# Prefer /proc/self/fd if available (/dev/fd |
34 |
# doesn't work on solaris, see bug #474536). |
35 |
for _fd_dir in ("/proc/self/fd", "/dev/fd"): |
36 |
@@ -539,12 +550,6 @@ def _setup_pipes(fd_pipes, close_fds=True, inheritable=None): |
37 |
interference. |
38 |
""" |
39 |
|
40 |
- # Support PEP 446 for Python >=3.4 |
41 |
- try: |
42 |
- set_inheritable = _os.set_inheritable |
43 |
- except AttributeError: |
44 |
- set_inheritable = None |
45 |
- |
46 |
reverse_map = {} |
47 |
# To protect from cases where direct assignment could |
48 |
# clobber needed fds ({1:2, 2:1}) we create a reverse map |
49 |
@@ -564,6 +569,7 @@ def _setup_pipes(fd_pipes, close_fds=True, inheritable=None): |
50 |
while reverse_map: |
51 |
|
52 |
oldfd, newfds = reverse_map.popitem() |
53 |
+ old_fdflags = None |
54 |
|
55 |
for newfd in newfds: |
56 |
if newfd in reverse_map: |
57 |
@@ -574,14 +580,26 @@ def _setup_pipes(fd_pipes, close_fds=True, inheritable=None): |
58 |
# unused file discriptors). |
59 |
backup_fd = os.dup(newfd) |
60 |
reverse_map[backup_fd] = reverse_map.pop(newfd) |
61 |
+ |
62 |
if oldfd != newfd: |
63 |
os.dup2(oldfd, newfd) |
64 |
+ if old_fdflags is None: |
65 |
+ old_fdflags = fcntl.fcntl(oldfd, fcntl.F_GETFD) |
66 |
+ fcntl.fcntl(newfd, fcntl.F_SETFD, old_fdflags) |
67 |
+ |
68 |
+ if _set_inheritable is not None: |
69 |
+ |
70 |
+ inheritable_state = None |
71 |
+ if not (old_fdflags is None or _FD_CLOEXEC is None): |
72 |
+ inheritable_state = not bool(old_fdflags & _FD_CLOEXEC) |
73 |
|
74 |
- if set_inheritable is not None: |
75 |
if inheritable is not None: |
76 |
- set_inheritable(newfd, inheritable) |
77 |
+ if inheritable_state is not inheritable: |
78 |
+ _set_inheritable(newfd, inheritable) |
79 |
+ |
80 |
elif newfd in (0, 1, 2): |
81 |
- set_inheritable(newfd, True) |
82 |
+ if inheritable_state is not True: |
83 |
+ _set_inheritable(newfd, True) |
84 |
|
85 |
if oldfd not in fd_pipes: |
86 |
# If oldfd is not a key in fd_pipes, then it's safe |