[Python-checkins] cpython (3.2): Fix FreeBSD, NetBSD and OpenBSD behavior of the issue #8052 fix.

gregory.p.smith python-checkins at python.org
Sun Jan 22 06:06:33 CET 2012


http://hg.python.org/cpython/rev/754c2eb0a92c
changeset:   74573:754c2eb0a92c
branch:      3.2
parent:      74571:07bea5e8ad5f
user:        Gregory P. Smith <greg at krypto.org>
date:        Sat Jan 21 21:01:24 2012 -0800
summary:
  Fix FreeBSD, NetBSD and OpenBSD behavior of the issue #8052 fix.

files:
  Modules/_posixsubprocess.c |  56 +++++++++++++++++++++----
  1 files changed, 47 insertions(+), 9 deletions(-)


diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -8,6 +8,9 @@
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
+#if defined(HAVE_SYS_STAT_H) && defined(__FreeBSD__)
+#include <sys/stat.h>
+#endif
 #ifdef HAVE_SYS_SYSCALL_H
 #include <sys/syscall.h>
 #endif
@@ -26,8 +29,11 @@
 # endif
 #endif
 
-#define LINUX_SOLARIS_FD_DIR "/proc/self/fd"
-#define BSD_OSX_FD_DIR "/dev/fd"
+#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__))
+# define FD_DIR "/dev/fd"
+#else
+# define FD_DIR "/proc/self/fd"
+#endif
 
 #define POSIX_CALL(call)   if ((call) == -1) goto error
 
@@ -62,6 +68,28 @@
 }
 
 
+#if defined(__FreeBSD__)
+/* When /dev/fd isn't mounted it is often a static directory populated
+ * with 0 1 2 or entries for 0 .. 63 on FreeBSD, NetBSD and OpenBSD.
+ * NetBSD and OpenBSD have a /proc fs available (though not necessarily
+ * mounted) and do not have fdescfs for /dev/fd.  MacOS X has a devfs
+ * that properly supports /dev/fd.
+ */
+static int _is_fdescfs_mounted_on_dev_fd()
+{
+    struct stat dev_stat;
+    struct stat dev_fd_stat;
+    if (stat("/dev", &dev_stat) != 0)
+        return 0;
+    if (stat(FD_DIR, &dev_fd_stat) != 0)
+        return 0; 
+    if (dev_stat.st_dev == dev_fd_stat.st_dev)
+        return 0;  /* / == /dev == /dev/fd means it is static. #fail */
+    return 1;
+}
+#endif
+
+
 /* Returns 1 if there is a problem with fd_sequence, 0 otherwise. */
 static int _sanity_check_python_fd_sequence(PyObject *fd_sequence)
 {
@@ -169,8 +197,7 @@
     int fd_dir_fd;
     if (start_fd >= end_fd)
         return;
-    fd_dir_fd = open(LINUX_SOLARIS_FD_DIR, O_RDONLY | O_CLOEXEC, 0);
-    /* Not trying to open the BSD_OSX path as this is currently Linux only. */
+        fd_dir_fd = open(FD_DIR, O_RDONLY | O_CLOEXEC, 0);
     if (fd_dir_fd == -1) {
         /* No way to get a list of open fds. */
         _close_fds_by_brute_force(start_fd, end_fd, py_fds_to_keep);
@@ -237,9 +264,12 @@
     if (start_fd >= end_fd)
         return;
 
-    proc_fd_dir = opendir(BSD_OSX_FD_DIR);
-    if (!proc_fd_dir)
-        proc_fd_dir = opendir(LINUX_SOLARIS_FD_DIR);
+#if defined(__FreeBSD__)
+    if (!_is_fdescfs_mounted_on_dev_fd())
+        proc_fd_dir = NULL;
+    else
+#endif
+        proc_fd_dir = opendir(FD_DIR);
     if (!proc_fd_dir) {
         /* No way to get a list of open fds. */
         _close_fds_by_brute_force(start_fd, end_fd, py_fds_to_keep);
@@ -361,8 +391,16 @@
         POSIX_CALL(close(errwrite));
     }
 
-    if (close_fds)
-        _close_open_fd_range(3, max_fd, py_fds_to_keep);
+    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));

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list