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:
parent
964e09988d
commit
28463c62e1
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue