This is mostly to document the bug. If these old platforms were still common I suppose we should change the readdir module to work around it. However, I’m not sure it’s worth the hassle at this point. * doc/posix-functions/readdir.texi, doc/posix-functions/readdir_r.texi: Document the bug. * lib/fts.c (fts_build): * lib/savedir.c (streamsavedir): Work around it. --- ChangeLog | 13 +++++++++++++ doc/posix-functions/readdir.texi | 5 +++++ doc/posix-functions/readdir_r.texi | 5 +++++ lib/fts.c | 7 +++++++ lib/savedir.c | 10 +++++++++- 5 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog index bf54cbd836..d4e849e8a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2025-01-13 Paul Eggert <egg...@cs.ucla.edu> + + fts, savedir: avoid glibc 2.2 readdir ENOENT bug + This is mostly to document the bug. + If these old platforms were still common I suppose we should + change the readdir module to work around it. However, I’m not + sure it’s worth the hassle at this point. + * doc/posix-functions/readdir.texi, doc/posix-functions/readdir_r.texi: + Document the bug. + * lib/fts.c (fts_build): + * lib/savedir.c (streamsavedir): + Work around it. + 2025-01-13 Bruno Haible <br...@clisp.org> stdlib-h: Define WCOREDUMP, as required by POSIX:2024. diff --git a/doc/posix-functions/readdir.texi b/doc/posix-functions/readdir.texi index 97d83ce946..3e28b35bde 100644 --- a/doc/posix-functions/readdir.texi +++ b/doc/posix-functions/readdir.texi @@ -30,4 +30,9 @@ readdir misbehavior on standard systems and so Gnulib does not attempt to cater to them any more. If you know of any problems caused by this, please send a bug report. +@item +When reading a directory that has been removed, +this function sets @code{errno} to @code{ENOENT} +instead of leaving @code{errno} alone to indicate EOF: +glibc 2.2.5. @end itemize diff --git a/doc/posix-functions/readdir_r.texi b/doc/posix-functions/readdir_r.texi index 76904314d7..c1e8aaad09 100644 --- a/doc/posix-functions/readdir_r.texi +++ b/doc/posix-functions/readdir_r.texi @@ -28,4 +28,9 @@ readdir_r @item This function is missing on some platforms: Minix 3.1.8, mingw, MSVC 14. +@item +When reading a directory that has been removed, +this function sets @code{errno} to @code{ENOENT} +instead of leaving @code{errno} alone to indicate EOF: +glibc 2.2.5. @end itemize diff --git a/lib/fts.c b/lib/fts.c index d31443902b..b611e997d4 100644 --- a/lib/fts.c +++ b/lib/fts.c @@ -1443,6 +1443,13 @@ fts_build (register FTS *sp, int type) __set_errno (0); struct dirent *dp = readdir(cur->fts_dirp); if (dp == NULL) { + /* Some readdir()s do not absorb ENOENT (dir + deleted but open). This bug was fixed in + glibc 2.3 (2002). */ +#if ! (2 < __GLIBC__ + (3 <= __GLIBC_MINOR__)) + if (errno == ENOENT) + errno = 0; +#endif if (errno) { cur->fts_errno = errno; /* If we've not read any items yet, treat diff --git a/lib/savedir.c b/lib/savedir.c index 93c2c36f7d..40e3b8cebc 100644 --- a/lib/savedir.c +++ b/lib/savedir.c @@ -123,7 +123,15 @@ streamsavedir (DIR *dirp, enum savedir_option option) errno = 0; dp = readdir (dirp); if (! dp) - break; + { + /* Some readdir()s do not absorb ENOENT (dir deleted but open). + This bug was fixed in glibc 2.3 (2002). */ +#if ! (2 < __GLIBC__ + (3 <= __GLIBC_MINOR__)) + if (errno == ENOENT) + errno = 0; +#endif + break; + } /* Skip "", ".", and "..". "" is returned by at least one buggy implementation: Solaris 2.4 readdir on NFS file systems. */ -- 2.47.1