summaryrefslogtreecommitdiff
path: root/lib/libc/gen/readdir.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/gen/readdir.c')
-rw-r--r--lib/libc/gen/readdir.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/lib/libc/gen/readdir.c b/lib/libc/gen/readdir.c
index 577a51a0995..cd6c046549c 100644
--- a/lib/libc/gen/readdir.c
+++ b/lib/libc/gen/readdir.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readdir.c,v 1.13 2008/04/04 21:26:07 okan Exp $ */
+/* $OpenBSD: readdir.c,v 1.14 2008/05/01 19:49:18 otto Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -38,7 +38,7 @@
* get next entry in a directory.
*/
int
-_readdir_unlocked(DIR *dirp, struct dirent **result)
+_readdir_unlocked(DIR *dirp, struct dirent **result, int skipdeleted)
{
struct dirent *dp;
@@ -61,7 +61,13 @@ _readdir_unlocked(DIR *dirp, struct dirent **result)
dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc)
return (-1);
dirp->dd_loc += dp->d_reclen;
- if (dp->d_ino == 0)
+ /*
+ * When called from seekdir(), we let it decide on
+ * the end condition to avoid overshooting: the next
+ * readdir call should produce the next non-deleted entry,
+ * and we already advanced dd_loc.
+ */
+ if (dp->d_ino == 0 && skipdeleted)
continue;
*result = dp;
return (0);
@@ -74,7 +80,7 @@ readdir(DIR *dirp)
struct dirent *dp;
_MUTEX_LOCK(&dirp->dd_lock);
- _readdir_unlocked(dirp, &dp);
+ _readdir_unlocked(dirp, &dp, 1);
_MUTEX_UNLOCK(&dirp->dd_lock);
return (dp);
@@ -86,7 +92,7 @@ readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
struct dirent *dp;
_MUTEX_LOCK(&dirp->dd_lock);
- if (_readdir_unlocked(dirp, &dp) != 0) {
+ if (_readdir_unlocked(dirp, &dp, 1) != 0) {
_MUTEX_UNLOCK(&dirp->dd_lock);
return errno;
}