Charles-François Natali added the comment:

With patch :)

----------
Added file: http://bugs.python.org/file31342/subprocess_close.diff

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue18763>
_______________________________________
diff -r 5d4fe1da2c90 Lib/test/test_subprocess.py
--- a/Lib/test/test_subprocess.py       Fri Aug 16 23:19:56 2013 +0200
+++ b/Lib/test/test_subprocess.py       Sat Aug 17 20:53:01 2013 +0200
@@ -1972,6 +1972,19 @@
         self.assertRaises(OSError, os.waitpid, pid, 0)
         self.assertNotIn(ident, [id(o) for o in subprocess._active])
 
+    def test_close_fds_after_preexec(self):
+        fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
+
+        # FDs created by preexec_fn should be closed in the child
+        p = subprocess.Popen([sys.executable, fd_status],
+                             stdout=subprocess.PIPE, close_fds=True,
+                             preexec_fn=os.pipe)
+        output, ignored = p.communicate()
+
+        remaining_fds = set(map(int, output.split(b',')))
+
+        self.assertTrue(remaining_fds <= set([0, 1, 2]))
+
 
 @unittest.skipUnless(mswindows, "Windows specific tests")
 class Win32ProcessTestCase(BaseTestCase):
diff -r 5d4fe1da2c90 Modules/_posixsubprocess.c
--- a/Modules/_posixsubprocess.c        Fri Aug 16 23:19:56 2013 +0200
+++ b/Modules/_posixsubprocess.c        Sat Aug 17 20:53:01 2013 +0200
@@ -412,17 +412,6 @@
         POSIX_CALL(close(errwrite));
     }
 
-    if (close_fds) {
-        int local_max_fd = max_fd;
-#if defined(__NetBSD__)
-        local_max_fd = fcntl(0, F_MAXFD);
-        if (local_max_fd < 0)
-            local_max_fd = max_fd;
-#endif
-        /* TODO HP-UX could use pstat_getproc() if anyone cares about it. */
-        _close_open_fd_range(3, local_max_fd, py_fds_to_keep);
-    }
-
     if (cwd)
         POSIX_CALL(chdir(cwd));
 
@@ -451,6 +440,18 @@
         /* Py_DECREF(result); - We're about to exec so why bother? */
     }
 
+    /* close FDs after executing preexec_fn, which might open FDs */
+    if (close_fds) {
+        int local_max_fd = max_fd;
+#if defined(__NetBSD__)
+        local_max_fd = fcntl(0, F_MAXFD);
+        if (local_max_fd < 0)
+            local_max_fd = max_fd;
+#endif
+        /* TODO HP-UX could use pstat_getproc() if anyone cares about it. */
+        _close_open_fd_range(3, local_max_fd, py_fds_to_keep);
+    }
+
     /* This loop matches the Lib/os.py _execvpe()'s PATH search when */
     /* given the executable_list generated by Lib/subprocess.py.     */
     saved_errno = 0;
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to