Issue #22524: Fix os.scandir() for platforms which don't have a d_type field in
the dirent structure (ex: OpenIndiana).
This commit is contained in:
parent
6036e4431d
commit
35a97c0bed
|
@ -16364,7 +16364,9 @@ typedef struct {
|
||||||
__int64 win32_file_index;
|
__int64 win32_file_index;
|
||||||
int got_file_index;
|
int got_file_index;
|
||||||
#else /* POSIX */
|
#else /* POSIX */
|
||||||
|
#ifdef HAVE_DIRENT_D_TYPE
|
||||||
unsigned char d_type;
|
unsigned char d_type;
|
||||||
|
#endif
|
||||||
ino_t d_ino;
|
ino_t d_ino;
|
||||||
#endif
|
#endif
|
||||||
} DirEntry;
|
} DirEntry;
|
||||||
|
@ -16389,11 +16391,15 @@ DirEntry_is_symlink(DirEntry *self)
|
||||||
{
|
{
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
|
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)
|
if (self->d_type != DT_UNKNOWN)
|
||||||
return self->d_type == DT_LNK;
|
return self->d_type == DT_LNK;
|
||||||
else
|
else
|
||||||
return DirEntry_test_mode(self, 0, S_IFLNK);
|
return DirEntry_test_mode(self, 0, S_IFLNK);
|
||||||
|
#else
|
||||||
|
/* POSIX without d_type */
|
||||||
|
return DirEntry_test_mode(self, 0, S_IFLNK);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16505,22 +16511,26 @@ DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits
|
||||||
PyObject *st_mode = NULL;
|
PyObject *st_mode = NULL;
|
||||||
long mode;
|
long mode;
|
||||||
int result;
|
int result;
|
||||||
|
#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
|
||||||
int is_symlink;
|
int is_symlink;
|
||||||
int need_stat;
|
int need_stat;
|
||||||
_Py_IDENTIFIER(st_mode);
|
#endif
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
unsigned long dir_bits;
|
unsigned long dir_bits;
|
||||||
#endif
|
#endif
|
||||||
|
_Py_IDENTIFIER(st_mode);
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
|
is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
|
||||||
need_stat = follow_symlinks && is_symlink;
|
need_stat = follow_symlinks && is_symlink;
|
||||||
#else /* POSIX */
|
#elif defined(HAVE_DIRENT_D_TYPE)
|
||||||
is_symlink = self->d_type == DT_LNK;
|
is_symlink = self->d_type == DT_LNK;
|
||||||
need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
|
need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
|
||||||
if (need_stat) {
|
if (need_stat) {
|
||||||
|
#endif
|
||||||
stat = DirEntry_get_stat(self, follow_symlinks);
|
stat = DirEntry_get_stat(self, follow_symlinks);
|
||||||
if (!stat) {
|
if (!stat) {
|
||||||
if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
|
if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
|
||||||
|
@ -16541,6 +16551,7 @@ DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits
|
||||||
Py_CLEAR(st_mode);
|
Py_CLEAR(st_mode);
|
||||||
Py_CLEAR(stat);
|
Py_CLEAR(stat);
|
||||||
result = (mode & S_IFMT) == mode_bits;
|
result = (mode & S_IFMT) == mode_bits;
|
||||||
|
#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
|
||||||
}
|
}
|
||||||
else if (is_symlink) {
|
else if (is_symlink) {
|
||||||
assert(mode_bits != S_IFLNK);
|
assert(mode_bits != S_IFLNK);
|
||||||
|
@ -16561,6 +16572,7 @@ DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits
|
||||||
result = self->d_type == DT_REG;
|
result = self->d_type == DT_REG;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
@ -16812,7 +16824,11 @@ join_path_filename(char *path_narrow, char* filename, Py_ssize_t filename_len)
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
|
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;
|
DirEntry *entry;
|
||||||
char *joined_path;
|
char *joined_path;
|
||||||
|
@ -16841,7 +16857,9 @@ DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
|
||||||
if (!entry->name || !entry->path)
|
if (!entry->name || !entry->path)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
#ifdef HAVE_DIRENT_D_TYPE
|
||||||
entry->d_type = d_type;
|
entry->d_type = d_type;
|
||||||
|
#endif
|
||||||
entry->d_ino = d_ino;
|
entry->d_ino = d_ino;
|
||||||
|
|
||||||
return (PyObject *)entry;
|
return (PyObject *)entry;
|
||||||
|
@ -16941,7 +16959,6 @@ ScandirIterator_iternext(ScandirIterator *iterator)
|
||||||
struct dirent *direntp;
|
struct dirent *direntp;
|
||||||
Py_ssize_t name_len;
|
Py_ssize_t name_len;
|
||||||
int is_dot;
|
int is_dot;
|
||||||
unsigned char d_type;
|
|
||||||
|
|
||||||
/* Happens if the iterator is iterated twice */
|
/* Happens if the iterator is iterated twice */
|
||||||
if (!iterator->dirp) {
|
if (!iterator->dirp) {
|
||||||
|
@ -16967,13 +16984,12 @@ ScandirIterator_iternext(ScandirIterator *iterator)
|
||||||
is_dot = direntp->d_name[0] == '.' &&
|
is_dot = direntp->d_name[0] == '.' &&
|
||||||
(name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
|
(name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
|
||||||
if (!is_dot) {
|
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,
|
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 */
|
/* Loop till we get a non-dot directory or finish iterating */
|
||||||
|
|
|
@ -15798,6 +15798,38 @@ esac
|
||||||
$as_echo "$ENSUREPIP" >&6; }
|
$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
|
# generate output files
|
||||||
ac_config_files="$ac_config_files Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh"
|
ac_config_files="$ac_config_files Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh"
|
||||||
|
|
||||||
|
|
20
configure.ac
20
configure.ac
|
@ -4944,6 +4944,26 @@ AS_CASE($with_ensurepip,
|
||||||
AC_MSG_RESULT($ENSUREPIP)
|
AC_MSG_RESULT($ENSUREPIP)
|
||||||
AC_SUBST(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
|
# generate output files
|
||||||
AC_CONFIG_FILES(Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh)
|
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])
|
AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
|
||||||
|
|
|
@ -183,6 +183,9 @@
|
||||||
/* Define to 1 if you have the <direct.h> header file. */
|
/* Define to 1 if you have the <direct.h> header file. */
|
||||||
#undef HAVE_DIRECT_H
|
#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'.
|
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||||
*/
|
*/
|
||||||
#undef HAVE_DIRENT_H
|
#undef HAVE_DIRENT_H
|
||||||
|
|
Loading…
Reference in New Issue