# HG changeset patch # User Taylor R Campbell # Date 1725116374 0 # Sat Aug 31 14:59:34 2024 +0000 # Branch trunk # Node ID 3025a24c81195e00a12e2455ba3159e39d8de555 # Parent 9aaaa3422f6c6a29e9679ebd97936a4038ca0060 # EXP-Topic riastradh-pr57145-readdirerrno readdir(3): Preserve errno on end-of-directory. PR pkg/57145: gmake: *** INTERNAL: readdir: Operation not supported. Stop. diff -r 9aaaa3422f6c -r 3025a24c8119 lib/libc/gen/readdir.c --- a/lib/libc/gen/readdir.c Thu Aug 29 13:39:42 2024 +0000 +++ b/lib/libc/gen/readdir.c Sat Aug 31 14:59:34 2024 +0000 @@ -56,12 +56,13 @@ static char sccsid[] = "@(#)readdir.c 8. struct dirent * _readdir_unlocked(DIR *dirp, int skipdeleted) { + const int saved_errno = errno; struct dirent *dp; for (;;) { if (dirp->dd_loc >= dirp->dd_size) { if (dirp->dd_flags & __DTF_READALL) - return (NULL); + break; dirp->dd_loc = 0; } if (dirp->dd_loc == 0 && !(dirp->dd_flags & __DTF_READALL)) { @@ -69,22 +70,25 @@ struct dirent * dirp->dd_size = getdents(dirp->dd_fd, dirp->dd_buf, (size_t)dirp->dd_len); if (dirp->dd_size <= 0) - return (NULL); + return NULL; /* getdents sets errno */ } dp = (struct dirent *) (void *)(dirp->dd_buf + (size_t)dirp->dd_loc); if ((intptr_t)dp & _DIRENT_ALIGN(dp))/* bogus pointer check */ - return (NULL); + break; /* d_reclen is unsigned; no need to compare it <= 0 */ if (dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) - return (NULL); + break; dirp->dd_loc += dp->d_reclen; if (dp->d_ino == 0 && skipdeleted) continue; if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW)) continue; - return (dp); + return dp; } + + errno = saved_errno; + return NULL; } struct dirent *