features/pep-446: f8a52518be4c (original) (raw)
Mercurial > features > pep-446
changeset 84891:f8a52518be4c
os.dup2() now behaves differently for fd < 3
Victor Stinner victor.stinner@gmail.com | |
---|---|
date | Mon, 29 Jul 2013 23:24:50 +0200 |
parents | 00689f56b418 |
children | 75e5d34898aa |
files | Doc/library/os.rst Lib/http/server.py Lib/pty.py Lib/test/test_os.py Modules/posixmodule.c |
diffstat | 5 files changed, 25 insertions(+), 9 deletions(-)[+] [-] Doc/library/os.rst 4 Lib/http/server.py 2 Lib/pty.py 3 Lib/test/test_os.py 17 Modules/posixmodule.c 8 |
line wrap: on
line diff
--- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -701,7 +701,9 @@ as internal buffering of data. .. function:: dup2(fd, fd2) Duplicate file descriptor fd to fd2, closing the latter first if necessary.
- If fd2 is
0
(stdin),1
(stdout) or2
(stderr), fd2 is set to - :ref:
inheritable <fd_inheritance>
, otherwise fd2 is set to - non-inheritable. Availability: Unix, Windows.
--- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -1132,9 +1132,7 @@ class CGIHTTPRequestHandler(SimpleHTTPRe except OSError: pass os.dup2(self.rfile.fileno(), 0)
os.set_inheritable(0, True)[](#l2.7) os.dup2(self.wfile.fileno(), 1)[](#l2.8)
os.set_inheritable(1, True)[](#l2.9) os.execve(scriptfile, args, env)[](#l2.10) except:[](#l2.11) self.server.handle_error(self.request, self.client_address)[](#l2.12)
--- a/Lib/pty.py +++ b/Lib/pty.py @@ -102,11 +102,8 @@ def fork(): # Slave becomes stdin/stdout/stderr of child. os.dup2(slave_fd, STDIN_FILENO)
os.set_inheritable(STDIN_FILENO, True)[](#l3.7) os.dup2(slave_fd, STDOUT_FILENO)[](#l3.8)
os.set_inheritable(STDOUT_FILENO, True)[](#l3.9) os.dup2(slave_fd, STDERR_FILENO)[](#l3.10)
os.set_inheritable(STDERR_FILENO, True)[](#l3.11) if (slave_fd > STDERR_FILENO):[](#l3.12) os.close(slave_fd)[](#l3.13)
--- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -2326,6 +2326,23 @@ class FDInheritanceTests(unittest.TestCa finally: os.close(fd1)
- @unittest.skipUnless(hasattr(os, 'dup2'), "need os.dup2()")
- def test_dup2_std_inheritable(self):
new_fd = os.open(__file__, os.O_RDONLY)[](#l4.9)
self.addCleanup(os.close, new_fd)[](#l4.10)
for fd in range(4):[](#l4.12)
with self.subTest("fd %s" % fd):[](#l4.13)
saved = os.dup(fd)[](#l4.14)
was_inheritable = os.get_inheritable(fd)[](#l4.15)
try:[](#l4.16)
os.dup2(new_fd, fd)[](#l4.17)
self.assertEqual(os.get_inheritable(fd), fd < 3)[](#l4.18)
finally:[](#l4.19)
os.dup2(saved, fd)[](#l4.20)
os.set_inheritable(fd, was_inheritable)[](#l4.21)
os.close(saved)[](#l4.22)
+ @unittest.skipUnless(hasattr(os, 'openpty'), "need os.openpty()") def test_openpty_inheritable(self): master_fd, slave_fd = os.openpty()
--- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7463,6 +7463,7 @@ static PyObject * posix_dup2(PyObject *self, PyObject *args) { int fd, fd2, res;
#ifdef HAVE_DUP3 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */ int dup3_works = -1; @@ -7472,9 +7473,10 @@ posix_dup2(PyObject *self, PyObject *arg return NULL; if (!_PyVerify_fd_dup2(fd, fd2)) return posix_error();
- if (!inheritable && dup3_works != 0) { Py_BEGIN_ALLOW_THREADS res = dup3(fd, fd2, O_CLOEXEC); Py_END_ALLOW_THREADS
@@ -7486,7 +7488,7 @@ posix_dup2(PyObject *self, PyObject *arg } }
#endif Py_BEGIN_ALLOW_THREADS @@ -7494,7 +7496,7 @@ posix_dup2(PyObject *self, PyObject *arg Py_END_ALLOW_THREADS if (res < 0) return posix_error();
if (_Py_set_inheritable(fd2, 0, NULL) < 0) {[](#l5.36)
if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {[](#l5.37) close(fd2);[](#l5.38) return NULL;[](#l5.39) }[](#l5.40)