(original) (raw)
changeset: 84891:f8a52518be4c user: Victor Stinner victor.stinner@gmail.com date: Mon Jul 29 23:24:50 2013 +0200 files: Doc/library/os.rst Lib/http/server.py Lib/pty.py Lib/test/test_os.py Modules/posixmodule.c description: os.dup2() now behaves differently for fd < 3 diff -r 00689f56b418 -r f8a52518be4c Doc/library/os.rst --- a/Doc/library/os.rst Sun Jul 28 09:39:13 2013 +0200 +++ b/Doc/library/os.rst Mon Jul 29 23:24:50 2013 +0200 @@ -701,7 +701,9 @@ .. function:: dup2(fd, fd2) Duplicate file descriptor *fd* to *fd2*, closing the latter first if necessary. - The file descriptor *fd2* is set to :ref:`non-inheritable `. + If *fd2* is ``0`` (stdin), ``1`` (stdout) or ``2`` (stderr), *fd2* is set to + :ref:`inheritable `, otherwise *fd2* is set to + non-inheritable. Availability: Unix, Windows. diff -r 00689f56b418 -r f8a52518be4c Lib/http/server.py --- a/Lib/http/server.py Sun Jul 28 09:39:13 2013 +0200 +++ b/Lib/http/server.py Mon Jul 29 23:24:50 2013 +0200 @@ -1132,9 +1132,7 @@ except OSError: pass os.dup2(self.rfile.fileno(), 0) - os.set_inheritable(0, True) os.dup2(self.wfile.fileno(), 1) - os.set_inheritable(1, True) os.execve(scriptfile, args, env) except: self.server.handle_error(self.request, self.client_address) diff -r 00689f56b418 -r f8a52518be4c Lib/pty.py --- a/Lib/pty.py Sun Jul 28 09:39:13 2013 +0200 +++ b/Lib/pty.py Mon Jul 29 23:24:50 2013 +0200 @@ -102,11 +102,8 @@ # Slave becomes stdin/stdout/stderr of child. os.dup2(slave_fd, STDIN_FILENO) - os.set_inheritable(STDIN_FILENO, True) os.dup2(slave_fd, STDOUT_FILENO) - os.set_inheritable(STDOUT_FILENO, True) os.dup2(slave_fd, STDERR_FILENO) - os.set_inheritable(STDERR_FILENO, True) if (slave_fd > STDERR_FILENO): os.close(slave_fd) diff -r 00689f56b418 -r f8a52518be4c Lib/test/test_os.py --- a/Lib/test/test_os.py Sun Jul 28 09:39:13 2013 +0200 +++ b/Lib/test/test_os.py Mon Jul 29 23:24:50 2013 +0200 @@ -2326,6 +2326,23 @@ 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) + self.addCleanup(os.close, new_fd) + + for fd in range(4): + with self.subTest("fd %s" % fd): + saved = os.dup(fd) + was_inheritable = os.get_inheritable(fd) + try: + os.dup2(new_fd, fd) + self.assertEqual(os.get_inheritable(fd), fd < 3) + finally: + os.dup2(saved, fd) + os.set_inheritable(fd, was_inheritable) + os.close(saved) + @unittest.skipUnless(hasattr(os, 'openpty'), "need os.openpty()") def test_openpty_inheritable(self): master_fd, slave_fd = os.openpty() diff -r 00689f56b418 -r f8a52518be4c Modules/posixmodule.c --- a/Modules/posixmodule.c Sun Jul 28 09:39:13 2013 +0200 +++ b/Modules/posixmodule.c Mon Jul 29 23:24:50 2013 +0200 @@ -7463,6 +7463,7 @@ posix_dup2(PyObject *self, PyObject *args) { int fd, fd2, res; + int inheritable; #ifdef HAVE_DUP3 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */ int dup3_works = -1; @@ -7472,9 +7473,10 @@ return NULL; if (!_PyVerify_fd_dup2(fd, fd2)) return posix_error(); + inheritable = (fd2 < 3); #ifdef HAVE_DUP3 - if (dup3_works != 0) { + if (!inheritable && dup3_works != 0) { Py_BEGIN_ALLOW_THREADS res = dup3(fd, fd2, O_CLOEXEC); Py_END_ALLOW_THREADS @@ -7486,7 +7488,7 @@ } } - if (dup3_works == 0) + if (inheritable || dup3_works == 0) { #endif Py_BEGIN_ALLOW_THREADS @@ -7494,7 +7496,7 @@ Py_END_ALLOW_THREADS if (res < 0) return posix_error(); - if (_Py_set_inheritable(fd2, 0, NULL) < 0) { + if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) { close(fd2); return NULL; }/victor.stinner@gmail.com