[Python-checkins] cpython: Issue #22524: Fix os.scandir() for platforms which don't have a d_type field in

victor.stinner python-checkins at python.org
Sun Mar 8 03:01:26 CET 2015


https://hg.python.org/cpython/rev/60e5c34ec53a
changeset:   94898:60e5c34ec53a
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Sun Mar 08 02:59:09 2015 +0100
summary:
  Issue #22524: Fix os.scandir() for platforms which don't have a d_type field in
the dirent structure (ex: OpenIndiana).

files:
  Modules/posixmodule.c |  42 +++++++++++++++++++++---------
  configure             |  32 +++++++++++++++++++++++
  configure.ac          |  20 ++++++++++++++
  pyconfig.h.in         |   3 ++
  4 files changed, 84 insertions(+), 13 deletions(-)


diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -16364,7 +16364,9 @@
     __int64 win32_file_index;
     int got_file_index;
 #else /* POSIX */
+#ifdef HAVE_DIRENT_D_TYPE
     unsigned char d_type;
+#endif
     ino_t d_ino;
 #endif
 } DirEntry;
@@ -16389,11 +16391,15 @@
 {
 #ifdef MS_WINDOWS
     return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
-#else /* POSIX */
+#elif defined(HAVE_DIRENT_D_TYPE)
+    /* POSIX */
     if (self->d_type != DT_UNKNOWN)
         return self->d_type == DT_LNK;
     else
         return DirEntry_test_mode(self, 0, S_IFLNK);
+#else
+    /* POSIX without d_type */
+    return DirEntry_test_mode(self, 0, S_IFLNK);
 #endif
 }
 
@@ -16505,22 +16511,26 @@
     PyObject *st_mode = NULL;
     long mode;
     int result;
+#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
     int is_symlink;
     int need_stat;
+#endif
+#ifdef MS_WINDOWS
+    unsigned long dir_bits;
+#endif
     _Py_IDENTIFIER(st_mode);
-#ifdef MS_WINDOWS
-    unsigned long dir_bits;
-#endif
 
 #ifdef MS_WINDOWS
     is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
     need_stat = follow_symlinks && is_symlink;
-#else /* POSIX */
+#elif defined(HAVE_DIRENT_D_TYPE)
     is_symlink = self->d_type == DT_LNK;
     need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
 #endif
 
+#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
     if (need_stat) {
+#endif
         stat = DirEntry_get_stat(self, follow_symlinks);
         if (!stat) {
             if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
@@ -16541,6 +16551,7 @@
         Py_CLEAR(st_mode);
         Py_CLEAR(stat);
         result = (mode & S_IFMT) == mode_bits;
+#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
     }
     else if (is_symlink) {
         assert(mode_bits != S_IFLNK);
@@ -16561,6 +16572,7 @@
             result = self->d_type == DT_REG;
 #endif
     }
+#endif
 
     return result;
 
@@ -16812,7 +16824,11 @@
 
 static PyObject *
 DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
-                         unsigned char d_type, ino_t d_ino)
+                         ino_t d_ino
+#ifdef HAVE_DIRENT_D_TYPE
+                         , unsigned char d_type
+#endif
+                         )
 {
     DirEntry *entry;
     char *joined_path;
@@ -16841,7 +16857,9 @@
     if (!entry->name || !entry->path)
         goto error;
 
+#ifdef HAVE_DIRENT_D_TYPE
     entry->d_type = d_type;
+#endif
     entry->d_ino = d_ino;
 
     return (PyObject *)entry;
@@ -16941,7 +16959,6 @@
     struct dirent *direntp;
     Py_ssize_t name_len;
     int is_dot;
-    unsigned char d_type;
 
     /* Happens if the iterator is iterated twice */
     if (!iterator->dirp) {
@@ -16967,13 +16984,12 @@
         is_dot = direntp->d_name[0] == '.' &&
                  (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
         if (!is_dot) {
-#if defined(__GLIBC__) && !defined(_DIRENT_HAVE_D_TYPE)
-            d_type = DT_UNKNOWN;  /* System doesn't support d_type */
-#else
-            d_type = direntp->d_type;
-#endif
             return DirEntry_from_posix_info(&iterator->path, direntp->d_name,
-                                            name_len, d_type, direntp->d_ino);
+                                            name_len, direntp->d_ino
+#ifdef HAVE_DIRENT_D_TYPE
+                                            , direntp->d_type
+#endif
+                                            );
         }
 
         /* Loop till we get a non-dot directory or finish iterating */
diff --git a/configure b/configure
--- a/configure
+++ b/configure
@@ -15798,6 +15798,38 @@
 $as_echo "$ENSUREPIP" >&6; }
 
 
+# check if the dirent structure of a d_type field and DT_UNKNOWN is defined
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the dirent structure of a d_type field" >&5
+$as_echo_n "checking if the dirent structure of a d_type field... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+    #include <dirent.h>
+
+    int main() {
+      struct dirent entry;
+      return entry.d_type == DT_UNKNOWN;
+    }
+
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have_dirent_d_type=yes
+else
+  have_dirent_d_type=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_dirent_d_type" >&5
+$as_echo "$have_dirent_d_type" >&6; }
+
+if test "$have_dirent_d_type" = yes; then
+
+$as_echo "#define HAVE_DIRENT_D_TYPE 1" >>confdefs.h
+
+fi
+
 # generate output files
 ac_config_files="$ac_config_files Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh"
 
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -4944,6 +4944,26 @@
 AC_MSG_RESULT($ENSUREPIP)
 AC_SUBST(ENSUREPIP)
 
+# check if the dirent structure of a d_type field and DT_UNKNOWN is defined
+AC_MSG_CHECKING(if the dirent structure of a d_type field)
+AC_LINK_IFELSE(
+[
+  AC_LANG_SOURCE([[
+    #include <dirent.h>
+
+    int main() {
+      struct dirent entry;
+      return entry.d_type == DT_UNKNOWN;
+    }
+  ]])
+],[have_dirent_d_type=yes],[have_dirent_d_type=no])
+AC_MSG_RESULT($have_dirent_d_type)
+
+if test "$have_dirent_d_type" = yes; then
+    AC_DEFINE(HAVE_DIRENT_D_TYPE, 1,
+              [Define to 1 if the dirent structure has a d_type field])
+fi
+
 # generate output files
 AC_CONFIG_FILES(Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh)
 AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
diff --git a/pyconfig.h.in b/pyconfig.h.in
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -183,6 +183,9 @@
 /* Define to 1 if you have the <direct.h> header file. */
 #undef HAVE_DIRECT_H
 
+/* Define to 1 if the dirent structure has a d_type field */
+#undef HAVE_DIRENT_D_TYPE
+
 /* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
    */
 #undef HAVE_DIRENT_H

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


More information about the Python-checkins mailing list