From a335429c5e718de598104418c73c67c187983b0f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Fri, 1 Aug 2025 16:44:36 +0200 Subject: [PATCH] Drop support for readdir_r() There has never been a good reason to prefer it over readdir(), and it has now been marked obsolete in POSIX-1.2024. --- CMakeLists.txt | 6 -- build/cmake/config.h.in | 3 - configure.ac | 8 -- contrib/android/config/windows_host.h | 3 - contrib/android/include/android_lf.h | 3 +- libarchive/archive_platform.h | 10 -- libarchive/archive_read_disk_posix.c | 134 -------------------------- 7 files changed, 1 insertion(+), 166 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 83a02857e..38eb2795c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1586,12 +1586,6 @@ CHECK_C_SOURCE_COMPILES( "#include \n#include \nint main(void) { struct statfs s; return sizeof(s);}" HAVE_STRUCT_STATFS) -# Make sure we have the POSIX version of readdir_r, not the -# older 2-argument version. -CHECK_C_SOURCE_COMPILES( - "#include \nint main() {DIR *d = opendir(\".\"); struct dirent e,*r; return readdir_r(d,&e,&r);}" - HAVE_READDIR_R) - # dirfd can be either a function or a macro. CHECK_C_SOURCE_COMPILES( "#include \nint main() {DIR *d = opendir(\".\"); return dirfd(d);}" diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in index 692d4516a..bea6cc7c0 100644 --- a/build/cmake/config.h.in +++ b/build/cmake/config.h.in @@ -970,9 +970,6 @@ typedef uint64_t uintmax_t; /* Define to 1 if you have the header file. */ #cmakedefine HAVE_PWD_H 1 -/* Define to 1 if you have the `readdir_r' function. */ -#cmakedefine HAVE_READDIR_R 1 - /* Define to 1 if you have the `readlink' function. */ #cmakedefine HAVE_READLINK 1 diff --git a/configure.ac b/configure.ac index cacc97ee6..57b2e2cb9 100644 --- a/configure.ac +++ b/configure.ac @@ -881,14 +881,6 @@ AC_CHECK_TYPES(struct statfs,,, #include ]) -# There are several variants of readdir_r around; we only -# accept the POSIX-compliant version. -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[#include ]], - [[DIR *dir; struct dirent e, *r; - return(readdir_r(dir, &e, &r));]])], - [AC_DEFINE(HAVE_READDIR_R,1,[Define to 1 if you have a POSIX compatible readdir_r])] -) # dirfd can be either a function or a macro. AC_LINK_IFELSE( [AC_LANG_PROGRAM([[#include diff --git a/contrib/android/config/windows_host.h b/contrib/android/config/windows_host.h index 4754744d8..98c005c51 100644 --- a/contrib/android/config/windows_host.h +++ b/contrib/android/config/windows_host.h @@ -620,9 +620,6 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_PWD_H */ -/* Define to 1 if you have a POSIX compatible readdir_r */ -#define HAVE_READDIR_R 1 - /* Define to 1 if you have the `readlink' function. */ /* #undef HAVE_READLINK */ diff --git a/contrib/android/include/android_lf.h b/contrib/android/include/android_lf.h index 3c5475e35..86d32e26b 100644 --- a/contrib/android/include/android_lf.h +++ b/contrib/android/include/android_lf.h @@ -1,4 +1,4 @@ -/* +/* * Macros for file64 functions * * Android does not support the macro _FILE_OFFSET_BITS=64 @@ -19,7 +19,6 @@ #include //dirent.h -#define readdir_r readdir64_r #define readdir readdir64 #define dirent dirent64 //fcntl.h diff --git a/libarchive/archive_platform.h b/libarchive/archive_platform.h index f30df1104..33dc5582b 100644 --- a/libarchive/archive_platform.h +++ b/libarchive/archive_platform.h @@ -183,16 +183,6 @@ #define CAN_RESTORE_METADATA_FD #endif -/* - * glibc 2.24 deprecates readdir_r - * bionic c deprecates readdir_r too - */ -#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24)) && (!defined(__ANDROID__)) -#define USE_READDIR_R 1 -#else -#undef USE_READDIR_R -#endif - /* Set up defaults for internal error codes. */ #ifndef ARCHIVE_ERRNO_FILE_FORMAT #if HAVE_EFTYPE diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c index 39fcf11c3..5d8f4be82 100644 --- a/libarchive/archive_read_disk_posix.c +++ b/libarchive/archive_read_disk_posix.c @@ -168,9 +168,6 @@ struct filesystem { int synthetic; int remote; int noatime; -#if defined(USE_READDIR_R) - size_t name_max; -#endif long incr_xfer_size; long max_xfer_size; long min_xfer_size; @@ -203,10 +200,6 @@ struct tree { DIR *d; #define INVALID_DIR_HANDLE NULL struct dirent *de; -#if defined(USE_READDIR_R) - struct dirent *dirent; - size_t dirent_allocated; -#endif int flags; int visit_type; /* Error code from last failed operation. */ @@ -1647,35 +1640,6 @@ setup_current_filesystem(struct archive_read_disk *a) #endif t->current_filesystem->noatime = 0; -#if defined(USE_READDIR_R) - /* Set maximum filename length. */ -#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX) - t->current_filesystem->name_max = sfs.f_namemax; -#else -# if defined(_PC_NAME_MAX) - /* Mac OS X does not have f_namemax in struct statfs. */ - if (tree_current_is_symblic_link_target(t)) { - if (tree_enter_working_dir(t) != 0) { - archive_set_error(&a->archive, errno, "fchdir failed"); - return (ARCHIVE_FAILED); - } - nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX); - } else - nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX); -# else - nm = -1; -# endif - if (nm == -1) - t->current_filesystem->name_max = NAME_MAX; - else - t->current_filesystem->name_max = nm; -#endif - if (t->current_filesystem->name_max == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot determine name_max"); - return (ARCHIVE_FAILED); - } -#endif /* USE_READDIR_R */ return (ARCHIVE_OK); } @@ -1863,19 +1827,6 @@ setup_current_filesystem(struct archive_read_disk *a) #endif t->current_filesystem->noatime = 0; -#if defined(USE_READDIR_R) - /* Set maximum filename length. */ -#if defined(HAVE_STATVFS) - t->current_filesystem->name_max = svfs.f_namemax; -#else - t->current_filesystem->name_max = sfs.f_namelen; -#endif - if (t->current_filesystem->name_max == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot determine name_max"); - return (ARCHIVE_FAILED); - } -#endif return (ARCHIVE_OK); } @@ -1953,15 +1904,6 @@ setup_current_filesystem(struct archive_read_disk *a) #endif t->current_filesystem->noatime = 0; -#if defined(USE_READDIR_R) - /* Set maximum filename length. */ - t->current_filesystem->name_max = svfs.f_namemax; - if (t->current_filesystem->name_max == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot determine name_max"); - return (ARCHIVE_FAILED); - } -#endif return (ARCHIVE_OK); } @@ -1975,9 +1917,6 @@ static int setup_current_filesystem(struct archive_read_disk *a) { struct tree *t = a->tree; -#if defined(_PC_NAME_MAX) && defined(USE_READDIR_R) - long nm; -#endif t->current_filesystem->synthetic = -1;/* Not supported */ t->current_filesystem->remote = -1;/* Not supported */ t->current_filesystem->noatime = 0; @@ -1987,40 +1926,6 @@ setup_current_filesystem(struct archive_read_disk *a) t->current_filesystem->min_xfer_size = -1; t->current_filesystem->incr_xfer_size = -1; -#if defined(USE_READDIR_R) - /* Set maximum filename length. */ -# if defined(_PC_NAME_MAX) - if (tree_current_is_symblic_link_target(t)) { - if (tree_enter_working_dir(t) != 0) { - archive_set_error(&a->archive, errno, "fchdir failed"); - return (ARCHIVE_FAILED); - } - nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX); - } else - nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX); - if (nm == -1) -# endif /* _PC_NAME_MAX */ - /* - * Some systems (HP-UX or others?) incorrectly defined - * NAME_MAX macro to be a smaller value. - */ -# if defined(NAME_MAX) && NAME_MAX >= 255 - t->current_filesystem->name_max = NAME_MAX; -# else - /* No way to get a trusted value of maximum filename - * length. */ - t->current_filesystem->name_max = PATH_MAX; -# endif /* NAME_MAX */ -# if defined(_PC_NAME_MAX) - else - t->current_filesystem->name_max = nm; -# endif /* _PC_NAME_MAX */ - if (t->current_filesystem->name_max == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot determine name_max"); - return (ARCHIVE_FAILED); - } -#endif /* USE_READDIR_R */ return (ARCHIVE_OK); } @@ -2457,9 +2362,6 @@ tree_dir_next_posix(struct tree *t) size_t namelen; if (t->d == NULL) { -#if defined(USE_READDIR_R) - size_t dirent_size; -#endif #if defined(HAVE_FDOPENDIR) int fd = tree_dup(t->working_dir_fd); @@ -2480,45 +2382,12 @@ tree_dir_next_posix(struct tree *t) t->visit_type = r != 0 ? r : TREE_ERROR_DIR; return (t->visit_type); } -#if defined(USE_READDIR_R) - dirent_size = offsetof(struct dirent, d_name) + - t->filesystem_table[t->current->filesystem_id].name_max + 1; - if (t->dirent == NULL || t->dirent_allocated < dirent_size) { - free(t->dirent); - t->dirent = malloc(dirent_size); - if (t->dirent == NULL) { - closedir(t->d); - t->d = INVALID_DIR_HANDLE; - (void)tree_ascend(t); - tree_pop(t); - t->tree_errno = ENOMEM; - t->visit_type = TREE_ERROR_DIR; - return (t->visit_type); - } - t->dirent_allocated = dirent_size; - } -#endif /* USE_READDIR_R */ } for (;;) { errno = 0; -#if defined(USE_READDIR_R) - r = readdir_r(t->d, t->dirent, &t->de); -#ifdef _AIX - /* Note: According to the man page, return value 9 indicates - * that the readdir_r was not successful and the error code - * is set to the global errno variable. And then if the end - * of directory entries was reached, the return value is 9 - * and the third parameter is set to NULL and errno is - * unchanged. */ - if (r == 9) - r = errno; -#endif /* _AIX */ - if (r != 0 || t->de == NULL) { -#else t->de = readdir(t->d); if (t->de == NULL) { r = errno; -#endif closedir(t->d); t->d = INVALID_DIR_HANDLE; if (r != 0) { @@ -2757,9 +2626,6 @@ tree_free(struct tree *t) if (t == NULL) return; archive_string_free(&t->path); -#if defined(USE_READDIR_R) - free(t->dirent); -#endif free(t->sparse_list); for (i = 0; i < t->max_filesystem_id; i++) free(t->filesystem_table[i].allocation_ptr); -- 2.47.2