PR/32609: Tanaka Akira: seekdir blocks if pthread is linked

Do locking consistently to avoid recursive locks (like the bug reported in
this pr), and to avoid leaking locks on errors.
This commit is contained in:
christos 2006-01-24 14:00:57 +00:00
parent 964e09988d
commit 28463c62e1
4 changed files with 38 additions and 34 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: opendir.c,v 1.28 2005/09/13 01:44:09 christos Exp $ */
/* $NetBSD: opendir.c,v 1.29 2006/01/24 14:00:57 christos Exp $ */
/*
* Copyright (c) 1983, 1993
@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)opendir.c 8.7 (Berkeley) 12/10/94";
#else
__RCSID("$NetBSD: opendir.c,v 1.28 2005/09/13 01:44:09 christos Exp $");
__RCSID("$NetBSD: opendir.c,v 1.29 2006/01/24 14:00:57 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -303,7 +303,7 @@ retry:
mutex_init((mutex_t *)dirp->dd_lock, NULL);
}
#endif
dirp->dd_rewind = telldir(dirp);
dirp->dd_rewind = __telldir(dirp);
return (dirp);
error:
serrno = errno;

View File

@ -1,4 +1,4 @@
/* $NetBSD: readdir.c,v 1.20 2005/09/13 01:44:09 christos Exp $ */
/* $NetBSD: readdir.c,v 1.21 2006/01/24 14:00:57 christos 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.20 2005/09/13 01:44:09 christos Exp $");
__RCSID("$NetBSD: readdir.c,v 1.21 2006/01/24 14:00:57 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -50,8 +50,8 @@ __RCSID("$NetBSD: readdir.c,v 1.20 2005/09/13 01:44:09 christos Exp $");
/*
* get next entry in a directory.
*/
static struct dirent *
_readdir_unlocked(DIR *dirp)
struct dirent *
__readdir(DIR *dirp)
{
struct dirent *dp;
@ -94,12 +94,12 @@ readdir(dirp)
#ifdef _REENTRANT
if (__isthreaded) {
mutex_lock((mutex_t *)dirp->dd_lock);
dp = _readdir_unlocked(dirp);
dp = __readdir(dirp);
mutex_unlock((mutex_t *)dirp->dd_lock);
}
else
#endif
dp = _readdir_unlocked(dirp);
dp = __readdir(dirp);
return (dp);
}
@ -117,13 +117,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(dirp)) != 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(dirp)) != NULL)
memcpy(entry, dp, (size_t)_DIRENT_SIZE(dp));
if (errno != 0) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: seekdir.c,v 1.11 2003/08/07 16:42:56 agc Exp $ */
/* $NetBSD: seekdir.c,v 1.12 2006/01/24 14:00:57 christos Exp $ */
/*
* Copyright (c) 1983, 1993
@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)seekdir.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: seekdir.c,v 1.11 2003/08/07 16:42:56 agc Exp $");
__RCSID("$NetBSD: seekdir.c,v 1.12 2006/01/24 14:00:57 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -59,14 +59,11 @@ seekdir(dirp, loc)
{
#ifdef _REENTRANT
if (__isthreaded)
if (__isthreaded) {
mutex_lock((mutex_t *)dirp->dd_lock);
#endif
__seekdir(dirp, loc);
#ifdef _REENTRANT
if (__isthreaded)
__seekdir(dirp, loc);
mutex_unlock((mutex_t *)dirp->dd_lock);
} else
#endif
__seekdir(dirp, loc);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: telldir.c,v 1.15 2003/08/07 16:42:58 agc Exp $ */
/* $NetBSD: telldir.c,v 1.16 2006/01/24 14:00:57 christos 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.15 2003/08/07 16:42:58 agc Exp $");
__RCSID("$NetBSD: telldir.c,v 1.16 2006/01/24 14:00:57 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -77,21 +77,32 @@ struct ddloc {
static long dd_loccnt; /* Index of entry for sequential readdir's */
static struct ddloc *dd_hash[NDIRHASH]; /* Hash list heads for ddlocs */
long __telldir(const DIR *dirp);
long
telldir(const DIR *dirp)
{
long rv;
#ifdef _REENTRANT
if (__isthreaded) {
mutex_lock((mutex_t *)dirp->dd_lock);
rv = __telldir(dirp);
mutex_unlock((mutex_t *)dirp->dd_lock);
} else
#endif
rv = __telldir(dirp);
return rv;
}
/*
* return a pointer into a directory
*/
long
telldir(dirp)
const DIR *dirp;
__telldir(const DIR *dirp)
{
long idx;
struct ddloc *lp;
#ifdef _REENTRANT
if (__isthreaded)
mutex_lock((mutex_t *)dirp->dd_lock);
#endif
if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL)
return (-1);
idx = dd_loccnt++;
@ -100,10 +111,6 @@ telldir(dirp)
lp->loc_loc = dirp->dd_loc;
lp->loc_next = dd_hash[LOCHASH(idx)];
dd_hash[LOCHASH(idx)] = lp;
#ifdef _REENTRANT
if (__isthreaded)
mutex_unlock((mutex_t *)dirp->dd_lock);
#endif
return (idx);
}
@ -138,7 +145,7 @@ __seekdir(dirp, loc)
dirp->dd_seek = lp->loc_seek;
dirp->dd_loc = 0;
while (dirp->dd_loc < lp->loc_loc) {
dp = readdir(dirp);
dp = __readdir(dirp);
if (dp == NULL)
break;
}