diff options
author | Bruno Haible <bruno@clisp.org> | 2023-04-27 01:42:25 +0200 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2023-04-27 01:42:25 +0200 |
commit | 3f0950f65abb5162c42b51a9bb32c9e87deeb405 (patch) | |
tree | bd2794c98d44013cf67c6b39c0863054315ebd68 /m4 | |
parent | d70f555e34d9f4a9110e65dd5669fce701a61929 (diff) | |
download | gnulib-3f0950f65abb5162c42b51a9bb32c9e87deeb405.tar.gz |
fdopendir: Fix fd leak and test failure on native Windows.
* lib/dirent-private.h: On mingw, define 'struct gl_directory' as a
wrapper around the original DIR. On MSVC, add an 'fd_to_close' field to
'struct gl_directory'.
* lib/dirent.in.h (DIR): Define when DIR_HAS_FD_MEMBER is 0, i.e. on
both mingw and MSVC.
(GNULIB_defined_DIR): New macro.
(opendir): Avoid incompatible redeclaration.
(readdir): Consider REPLACE_READDIR.
(rewinddir): Consider REPLACE_REWINDDIR.
* m4/dirent_h.m4 (gl_DIRENT_DIR): New macro.
(gl_DIRENT_H): Invoke it.
(gl_DIRENT_H_DEFAULTS): Initialize REPLACE_READDIR, REPLACE_REWINDDIR.
* modules/dirent (Makefile.am): Substitute DIR_HAS_FD_MEMBER,
REPLACE_READDIR, REPLACE_REWINDDIR.
--
* lib/dirfd.c (dirfd): If GNULIB_defined_DIR, just use the
'fd_to_close' field.
* m4/dirfd.m4 (gl_FUNC_DIRFD): Set HAVE_DIRFD. Don't set REPLACE_DIRFD
to 1 if HAVE_DIRFD is 0. If DIR_HAS_FD_MEMBER is 0, ensure dirfd.c gets
compiled.
* modules/dirfd (Files): Add lib/dirent-private.h.
(Depends-on, configure.ac): Simplify conditions.
--
* lib/closedir.c: Include <stdlib.h> always, for free().
(closedir): If GNULIB_defined_DIR, arrange to call close(dirfd(dirp)) at
the end. On mingw, call free() of dirp. Prefer testing HAVE_DIRENT_H,
for consistency with dirent.h.
* m4/closedir.m4 (gl_FUNC_CLOSEDIR): Don't set REPLACE_CLOSEDIR to 1 if
HAVE_CLOSEDIR is 0. If DIR_HAS_FD_MEMBER is 0, ensure closedir.c gets
compiled.
--
* lib/opendir.c: Include <stdlib.h> always. Include <string.h>.
(opendir): On mingw, allocate the 'struct gl_directory' through malloc.
If GNULIB_defined_DIR, set the 'fd_to_close' field to -1. Prefer
testing HAVE_DIRENT_H, for consistency with dirent.h.
* m4/opendir.m4 (gl_FUNC_OPENDIR): Don't set REPLACE_OPENDIR to 1 if
HAVE_OPENDIR is 0. If DIR_HAS_FD_MEMBER is 0, ensure opendir.c gets
compiled.
--
* lib/fdopendir.c (fdopendir): If GNULIB_defined_DIR, use a simple
implementation based on opendir and the fchdir module. If __KLIBC__,
don't define unused auxiliary functions.
* modules/fdopendir (Files): Add lib/dirent-private.h.
--
* lib/readdir.c (readdir): On mingw, redirect to the original readdir
function. Prefer testing HAVE_DIRENT_H, for consistency with dirent.h.
* m4/readdir.m4 (gl_FUNC_READDIR): If DIR_HAS_FD_MEMBER is 0, ensure
readdir.c gets compiled.
* modules/readdir (configure.ac): Consider REPLACE_READDIR.
--
* lib/rewinddir.c (rewinddir): On mingw, redirect to the original
rewinddir function. Prefer testing HAVE_DIRENT_H, for consistency with
dirent.h.
* m4/rewinddir.m4 (gl_FUNC_REWINDDIR): If DIR_HAS_FD_MEMBER is 0, ensure
rewinddir.c gets compiled.
* modules/rewinddir (configure.ac): Consider REPLACE_REWINDDIR.
--
* lib/fchdir.c (dir_info_t): Remove a FIXME.
Diffstat (limited to 'm4')
-rw-r--r-- | m4/closedir.m4 | 33 | ||||
-rw-r--r-- | m4/dirent_h.m4 | 21 | ||||
-rw-r--r-- | m4/dirfd.m4 | 29 | ||||
-rw-r--r-- | m4/opendir.m4 | 35 | ||||
-rw-r--r-- | m4/readdir.m4 | 8 | ||||
-rw-r--r-- | m4/rewinddir.m4 | 8 |
6 files changed, 90 insertions, 44 deletions
diff --git a/m4/closedir.m4 b/m4/closedir.m4 index 9c15354c3d..7e702def25 100644 --- a/m4/closedir.m4 +++ b/m4/closedir.m4 @@ -1,4 +1,4 @@ -# closedir.m4 serial 6 +# closedir.m4 serial 7 dnl Copyright (C) 2011-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -12,20 +12,23 @@ AC_DEFUN([gl_FUNC_CLOSEDIR], AC_CHECK_FUNCS([closedir]) if test $ac_cv_func_closedir = no; then HAVE_CLOSEDIR=0 - fi - dnl Replace closedir() for supporting the gnulib-defined fchdir() function, - dnl to keep fchdir's bookkeeping up-to-date. - m4_ifdef([gl_FUNC_FCHDIR], [ - gl_TEST_FCHDIR - if test $HAVE_FCHDIR = 0; then - if test $HAVE_CLOSEDIR = 1; then + else + dnl Replace closedir() on native Windows, to support fdopendir(). + AC_REQUIRE([gl_DIRENT_DIR]) + if test $DIR_HAS_FD_MEMBER = 0; then + REPLACE_CLOSEDIR=1 + fi + dnl Replace closedir() for supporting the gnulib-defined dirfd() function. + case $host_os in + os2*) REPLACE_CLOSEDIR=1 ;; + esac + dnl Replace closedir() for supporting the gnulib-defined fchdir() function, + dnl to keep fchdir's bookkeeping up-to-date. + m4_ifdef([gl_FUNC_FCHDIR], [ + gl_TEST_FCHDIR + if test $HAVE_FCHDIR = 0; then REPLACE_CLOSEDIR=1 fi - fi - ]) - dnl Replace closedir() for supporting the gnulib-defined dirfd() function. - case $host_os,$HAVE_CLOSEDIR in - os2*,1) - REPLACE_CLOSEDIR=1;; - esac + ]) + fi ]) diff --git a/m4/dirent_h.m4 b/m4/dirent_h.m4 index 2a232a7622..b6c189c0d9 100644 --- a/m4/dirent_h.m4 +++ b/m4/dirent_h.m4 @@ -1,4 +1,4 @@ -# dirent_h.m4 serial 19 +# dirent_h.m4 serial 20 dnl Copyright (C) 2008-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -21,12 +21,29 @@ AC_DEFUN_ONCE([gl_DIRENT_H], fi AC_SUBST([HAVE_DIRENT_H]) + gl_DIRENT_DIR + dnl Check for declarations of anything we want to poison if the dnl corresponding gnulib module is not in use. gl_WARN_ON_USE_PREPARE([[#include <dirent.h> ]], [alphasort closedir dirfd fdopendir opendir readdir rewinddir scandir]) ]) +dnl Determine whether <dirent.h> needs to override the DIR type. +AC_DEFUN_ONCE([gl_DIRENT_DIR], +[ + dnl Set DIR_HAS_FD_MEMBER if dirfd() works, i.e. not always returns -1, + dnl or has the __KLIBC__ workaround as in lib/dirfd.c. + dnl We could use the findings from gl_FUNC_DIRFD and gl_PREREQ_DIRFD, but + dnl it's simpler since we know the affected platforms. + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + mingw*) DIR_HAS_FD_MEMBER=0 ;; + *) DIR_HAS_FD_MEMBER=1 ;; + esac + AC_SUBST([DIR_HAS_FD_MEMBER]) +]) + # gl_DIRENT_MODULE_INDICATOR([modulename]) # sets the shell variable that indicates the presence of the given module # to a C preprocessor expression that will evaluate to 1. @@ -73,6 +90,8 @@ AC_DEFUN([gl_DIRENT_H_DEFAULTS], HAVE_SCANDIR=1; AC_SUBST([HAVE_SCANDIR]) HAVE_ALPHASORT=1; AC_SUBST([HAVE_ALPHASORT]) REPLACE_OPENDIR=0; AC_SUBST([REPLACE_OPENDIR]) + REPLACE_READDIR=0; AC_SUBST([REPLACE_READDIR]) + REPLACE_REWINDDIR=0; AC_SUBST([REPLACE_REWINDDIR]) REPLACE_CLOSEDIR=0; AC_SUBST([REPLACE_CLOSEDIR]) REPLACE_DIRFD=0; AC_SUBST([REPLACE_DIRFD]) REPLACE_FDOPENDIR=0; AC_SUBST([REPLACE_FDOPENDIR]) diff --git a/m4/dirfd.m4 b/m4/dirfd.m4 index 2135535042..d1ee2c7f61 100644 --- a/m4/dirfd.m4 +++ b/m4/dirfd.m4 @@ -1,4 +1,4 @@ -# serial 26 -*- Autoconf -*- +# serial 27 -*- Autoconf -*- dnl Find out how to get the file descriptor associated with an open DIR*. @@ -12,7 +12,7 @@ dnl From Jim Meyering AC_DEFUN([gl_FUNC_DIRFD], [ AC_REQUIRE([gl_DIRENT_H_DEFAULTS]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_REQUIRE([AC_CANONICAL_HOST]) dnl Persuade glibc <dirent.h> to declare dirfd(). AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) @@ -36,15 +36,24 @@ AC_DEFUN([gl_FUNC_DIRFD], [gl_cv_func_dirfd_macro=yes], [gl_cv_func_dirfd_macro=no])]) - # Use the replacement if we have no function or macro with that name, - # or if OS/2 kLIBC whose dirfd() does not work. - # Replace only if the system declares dirfd already. - case $ac_cv_func_dirfd,$gl_cv_func_dirfd_macro,$host_os,$ac_cv_have_decl_dirfd in - no,no,*,yes | *,*,os2*,yes) + if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no; then + HAVE_DIRFD=0 + else + HAVE_DIRFD=1 + dnl Replace only if the system declares dirfd already. + if test $ac_cv_have_decl_dirfd = yes; then REPLACE_DIRFD=1 - AC_DEFINE([REPLACE_DIRFD], [1], - [Define to 1 if gnulib's dirfd() replacement is used.]);; - esac + fi + dnl Replace dirfd() on native Windows, to support fdopendir(). + AC_REQUIRE([gl_DIRENT_DIR]) + if test $DIR_HAS_FD_MEMBER = 0; then + REPLACE_DIRFD=1 + fi + dnl OS/2 kLIBC dirfd() does not work. + case "$host_os" in + os2*) REPLACE_DIRFD=1 ;; + esac + fi ]) dnl Prerequisites of lib/dirfd.c. diff --git a/m4/opendir.m4 b/m4/opendir.m4 index 2fb90b6d57..2e9be769b5 100644 --- a/m4/opendir.m4 +++ b/m4/opendir.m4 @@ -1,4 +1,4 @@ -# opendir.m4 serial 5 +# opendir.m4 serial 6 dnl Copyright (C) 2011-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -12,21 +12,24 @@ AC_DEFUN([gl_FUNC_OPENDIR], AC_CHECK_FUNCS([opendir]) if test $ac_cv_func_opendir = no; then HAVE_OPENDIR=0 - fi - dnl Replace opendir() for supporting the gnulib-defined fchdir() function, - dnl to keep fchdir's bookkeeping up-to-date. - m4_ifdef([gl_FUNC_FCHDIR], [ - gl_TEST_FCHDIR - if test $HAVE_FCHDIR = 0; then - if test $HAVE_OPENDIR = 1; then + else + dnl Replace opendir() on native Windows, to support fdopendir(). + AC_REQUIRE([gl_DIRENT_DIR]) + if test $DIR_HAS_FD_MEMBER = 0; then + REPLACE_OPENDIR=1 + fi + dnl Replace opendir() on OS/2 kLIBC to support dirfd() function replaced + dnl by gnulib. + case $host_os in + os2*) REPLACE_OPENDIR=1 ;; + esac + dnl Replace opendir() for supporting the gnulib-defined fchdir() function, + dnl to keep fchdir's bookkeeping up-to-date. + m4_ifdef([gl_FUNC_FCHDIR], [ + gl_TEST_FCHDIR + if test $HAVE_FCHDIR = 0; then REPLACE_OPENDIR=1 fi - fi - ]) - dnl Replace opendir() on OS/2 kLIBC to support dirfd() function replaced - dnl by gnulib. - case $host_os,$HAVE_OPENDIR in - os2*,1) - REPLACE_OPENDIR=1;; - esac + ]) + fi ]) diff --git a/m4/readdir.m4 b/m4/readdir.m4 index 0a78739b3c..81337e2ffa 100644 --- a/m4/readdir.m4 +++ b/m4/readdir.m4 @@ -1,4 +1,4 @@ -# readdir.m4 serial 1 +# readdir.m4 serial 2 dnl Copyright (C) 2011-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -11,5 +11,11 @@ AC_DEFUN([gl_FUNC_READDIR], AC_CHECK_FUNCS([readdir]) if test $ac_cv_func_readdir = no; then HAVE_READDIR=0 + else + dnl Replace readdir() on native Windows, to support fdopendir(). + AC_REQUIRE([gl_DIRENT_DIR]) + if test $DIR_HAS_FD_MEMBER = 0; then + REPLACE_READDIR=1 + fi fi ]) diff --git a/m4/rewinddir.m4 b/m4/rewinddir.m4 index dc2c37d97a..d0d24de8a6 100644 --- a/m4/rewinddir.m4 +++ b/m4/rewinddir.m4 @@ -1,4 +1,4 @@ -# rewinddir.m4 serial 1 +# rewinddir.m4 serial 2 dnl Copyright (C) 2011-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -11,5 +11,11 @@ AC_DEFUN([gl_FUNC_REWINDDIR], AC_CHECK_FUNCS([rewinddir]) if test $ac_cv_func_rewinddir = no; then HAVE_REWINDDIR=0 + else + dnl Replace rewinddir() on native Windows, to support fdopendir(). + AC_REQUIRE([gl_DIRENT_DIR]) + if test $DIR_HAS_FD_MEMBER = 0; then + REPLACE_REWINDDIR=1 + fi fi ]) |