aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2024-08-30 21:52:23 +0200
committerFlorian Weimer <fweimer@redhat.com>2024-09-05 12:05:32 +0200
commit61f2c2e1d1287a791c22d86c943b44bcf66bb8ad (patch)
tree91468df783dd54e8f9fc817ba79e6a4d68f4f046
parent3b1d32177635023e37bec7fbfd77c3cfb2659eb1 (diff)
downloadglibc-61f2c2e1d1287a791c22d86c943b44bcf66bb8ad.zip
glibc-61f2c2e1d1287a791c22d86c943b44bcf66bb8ad.tar.gz
glibc-61f2c2e1d1287a791c22d86c943b44bcf66bb8ad.tar.bz2
Linux: readdir_r needs to report getdents failures (bug 32124)
Upon error, return the errno value set by the __getdents call in __readdir_unlocked. Previously, kernel-reported errors were ignored. Reviewed-by: DJ Delorie <dj@redhat.com>
-rw-r--r--sysdeps/unix/sysv/linux/readdir_r.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/sysdeps/unix/sysv/linux/readdir_r.c b/sysdeps/unix/sysv/linux/readdir_r.c
index ffd5262..1d59568 100644
--- a/sysdeps/unix/sysv/linux/readdir_r.c
+++ b/sysdeps/unix/sysv/linux/readdir_r.c
@@ -25,14 +25,22 @@ __readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
{
struct dirent *dp;
size_t reclen;
+ int saved_errno = errno;
__libc_lock_lock (dirp->lock);
while (1)
{
+ /* If errno is changed from 0, the NULL return value indicates
+ an actual error. It overrides a pending ENAMETOOLONG error. */
+ __set_errno (0);
dp = __readdir_unlocked (dirp);
if (dp == NULL)
- break;
+ {
+ if (errno != 0)
+ dirp->errcode = errno;
+ break;
+ }
reclen = dp->d_reclen;
if (reclen <= offsetof (struct dirent, d_name) + NAME_MAX + 1)
@@ -61,6 +69,7 @@ __readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
__libc_lock_unlock (dirp->lock);
+ __set_errno (saved_errno);
return dp != NULL ? 0 : dirp->errcode;
}