Fix a bug in the implementation of seekdir(). If the first entry in
a block has been unlinked, seekdir() may overshoot by one entry. Thus, _readdir_unlinked() must not skip deleted entries when being called from seekdir(). Christos agreed.
This commit is contained in:
parent
dd178c786e
commit
34f7daa87e
|
@ -1,9 +1,9 @@
|
|||
# $NetBSD: Makefile.inc,v 1.5 2006/07/27 15:46:30 christos Exp $
|
||||
# $NetBSD: Makefile.inc,v 1.6 2008/05/04 18:53:26 tonnerre Exp $
|
||||
|
||||
.PATH: ${COMPATDIR}/gen
|
||||
SRCS+=compat_errlist.c compat_fts.c compat___fts13.c compat___fts30.c \
|
||||
compat___fts31.c compat_getmntinfo.c compat_glob.c compat___glob13.c \
|
||||
compat_opendir.c compat_readdir.c compat_scandir.c compat_siglist.c \
|
||||
compat_signame.c compat_sigsetops.c compat_times.c compat_timezone.c \
|
||||
compat_unvis.c compat_utmpx.c compat__sys_errlist.c compat__sys_nerr.c \
|
||||
compat__sys_siglist.c
|
||||
compat_opendir.c compat_readdir.c compat__readdir_unlocked30.c \
|
||||
compat_scandir.c compat_siglist.c compat_signame.c compat_sigsetops.c \
|
||||
compat_times.c compat_timezone.c compat_unvis.c compat_utmpx.c \
|
||||
compat__sys_errlist.c compat__sys_nerr.c compat__sys_siglist.c
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/* $NetBSD: compat__readdir_unlocked30.c,v 1.1 2008/05/04 18:53:26 tonnerre Exp $ */
|
||||
|
||||
#define __LIBC12_SOURCE__
|
||||
#include "namespace.h"
|
||||
#include <dirent.h>
|
||||
#include <compat/include/dirent.h>
|
||||
|
||||
#ifdef __warn_references
|
||||
__warn_references(___readdir_unlocked30,
|
||||
"warning: reference to compatibility _readdir_unlocked(); include <dirent.h> for correct reference")
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Compat version of _readdir_unlocked which always skips directories
|
||||
*/
|
||||
struct dirent *
|
||||
___readdir_unlocked30(DIR *dirp)
|
||||
{
|
||||
return ___readdir_unlocked50(dirp, 1);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: dirent.h,v 1.5 2006/03/26 18:22:40 christos Exp $ */
|
||||
/* $NetBSD: dirent.h,v 1.6 2008/05/04 18:53:26 tonnerre Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -51,7 +51,8 @@ struct dirent *__readdir30(DIR *);
|
|||
|
||||
#if defined(_NETBSD_SOURCE)
|
||||
|
||||
struct dirent12 *_readdir_unlocked(DIR *);
|
||||
struct dirent12 *_readdir_unlocked(DIR *, int);
|
||||
struct dirent *___readdir_unlocked50(DIR *, int);
|
||||
struct dirent *___readdir_unlocked30(DIR *);
|
||||
|
||||
DIR *__opendir2(const char *, int);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: dirent_private.h,v 1.1 2006/05/17 20:36:50 christos Exp $ */
|
||||
/* $NetBSD: dirent_private.h,v 1.2 2008/05/04 18:53:26 tonnerre Exp $ */
|
||||
|
||||
/*
|
||||
* One struct _dirpos is malloced to describe the current directory
|
||||
|
@ -17,6 +17,6 @@ void _seekdir_unlocked(struct _dirdesc *, long);
|
|||
long _telldir_unlocked(struct _dirdesc *);
|
||||
#ifndef __LIBC12_SOURCE__
|
||||
struct dirent;
|
||||
struct dirent *_readdir_unlocked(struct _dirdesc *)
|
||||
__RENAME(___readdir_unlocked30);
|
||||
struct dirent *_readdir_unlocked(struct _dirdesc *, int)
|
||||
__RENAME(___readdir_unlocked50);
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: readdir.c,v 1.23 2006/05/17 20:36:50 christos Exp $ */
|
||||
/* $NetBSD: readdir.c,v 1.24 2008/05/04 18:53:26 tonnerre Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)readdir.c 8.3 (Berkeley) 9/29/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: readdir.c,v 1.23 2006/05/17 20:36:50 christos Exp $");
|
||||
__RCSID("$NetBSD: readdir.c,v 1.24 2008/05/04 18:53:26 tonnerre Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
|
@ -54,7 +54,7 @@ __RCSID("$NetBSD: readdir.c,v 1.23 2006/05/17 20:36:50 christos Exp $");
|
|||
* get next entry in a directory.
|
||||
*/
|
||||
struct dirent *
|
||||
_readdir_unlocked(DIR *dirp)
|
||||
_readdir_unlocked(DIR *dirp, int skipdeleted)
|
||||
{
|
||||
struct dirent *dp;
|
||||
|
||||
|
@ -80,7 +80,7 @@ _readdir_unlocked(DIR *dirp)
|
|||
if (dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc)
|
||||
return (NULL);
|
||||
dirp->dd_loc += dp->d_reclen;
|
||||
if (dp->d_ino == 0)
|
||||
if (dp->d_ino == 0 && skipdeleted)
|
||||
continue;
|
||||
if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW))
|
||||
continue;
|
||||
|
@ -97,12 +97,12 @@ readdir(dirp)
|
|||
#ifdef _REENTRANT
|
||||
if (__isthreaded) {
|
||||
mutex_lock((mutex_t *)dirp->dd_lock);
|
||||
dp = _readdir_unlocked(dirp);
|
||||
dp = _readdir_unlocked(dirp, 1);
|
||||
mutex_unlock((mutex_t *)dirp->dd_lock);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
dp = _readdir_unlocked(dirp);
|
||||
dp = _readdir_unlocked(dirp, 1);
|
||||
return (dp);
|
||||
}
|
||||
|
||||
|
@ -120,13 +120,13 @@ readdir_r(dirp, entry, result)
|
|||
#ifdef _REENTRANT
|
||||
if (__isthreaded) {
|
||||
mutex_lock((mutex_t *)dirp->dd_lock);
|
||||
if ((dp = _readdir_unlocked(dirp)) != NULL)
|
||||
if ((dp = _readdir_unlocked(dirp, 1)) != NULL)
|
||||
memcpy(entry, dp, (size_t)_DIRENT_SIZE(dp));
|
||||
mutex_unlock((mutex_t *)dirp->dd_lock);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ((dp = _readdir_unlocked(dirp)) != NULL)
|
||||
if ((dp = _readdir_unlocked(dirp, 1)) != NULL)
|
||||
memcpy(entry, dp, (size_t)_DIRENT_SIZE(dp));
|
||||
|
||||
if (errno != 0) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: telldir.c,v 1.18 2006/05/17 20:36:50 christos Exp $ */
|
||||
/* $NetBSD: telldir.c,v 1.19 2008/05/04 18:53:26 tonnerre Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)telldir.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: telldir.c,v 1.18 2006/05/17 20:36:50 christos Exp $");
|
||||
__RCSID("$NetBSD: telldir.c,v 1.19 2008/05/04 18:53:26 tonnerre Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
|
@ -117,6 +117,6 @@ _seekdir_unlocked(DIR *dirp, long loc)
|
|||
dirp->dd_seek = lseek(dirp->dd_fd, lp->dp_seek, SEEK_SET);
|
||||
dirp->dd_loc = 0;
|
||||
while (dirp->dd_loc < lp->dp_loc)
|
||||
if (_readdir_unlocked(dirp) == NULL)
|
||||
if (_readdir_unlocked(dirp, 0) == NULL)
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue