svn commit: r269204 - head/lib/libc/gen
John Baldwin
jhb at FreeBSD.org
Tue Jul 29 00:16:34 UTC 2014
Author: jhb
Date: Tue Jul 29 00:16:33 2014
New Revision: 269204
URL: http://svnweb.freebsd.org/changeset/base/269204
Log:
If telldir() is called immediately after a call to seekdir(), POSIX
requires the return value of telldir() to equal the value passed to
seekdir(). The current seekdir code with SINGLEUSE enabled breaks
this case as each call to telldir() allocates a new cookie. Instead,
remove the SINGLEUSE code and change telldir() to look for an existing
cookie for the directory's current location rather than always creating
a new cookie.
CR: https://phabric.freebsd.org/D490
PR: 121656
Reviewed by: jilles
MFC after: 1 week
Modified:
head/lib/libc/gen/directory.3
head/lib/libc/gen/telldir.c
Modified: head/lib/libc/gen/directory.3
==============================================================================
--- head/lib/libc/gen/directory.3 Mon Jul 28 23:36:21 2014 (r269203)
+++ head/lib/libc/gen/directory.3 Tue Jul 29 00:16:33 2014 (r269204)
@@ -28,7 +28,7 @@
.\" @(#)directory.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd August 18, 2013
+.Dd July 28, 2014
.Dt DIRECTORY 3
.Os
.Sh NAME
@@ -169,6 +169,10 @@ If the directory is closed and then
reopened, prior values returned by
.Fn telldir
will no longer be valid.
+Values returned by
+.Fn telldir
+are also invalidated by a call to
+.Fn rewinddir .
.Pp
The
.Fn seekdir
@@ -182,13 +186,6 @@ The new position reverts to the one asso
when the
.Fn telldir
operation was performed.
-State associated with the token returned by
-.Fn telldir is freed when it is passed to
-.Fn seekdir .
-If you wish return to the same location again,
-then you must create a new token with another
-.Fn telldir
-call.
.Pp
The
.Fn rewinddir
Modified: head/lib/libc/gen/telldir.c
==============================================================================
--- head/lib/libc/gen/telldir.c Mon Jul 28 23:36:21 2014 (r269203)
+++ head/lib/libc/gen/telldir.c Tue Jul 29 00:16:33 2014 (r269204)
@@ -47,13 +47,6 @@ __FBSDID("$FreeBSD$");
#include "telldir.h"
/*
- * The option SINGLEUSE may be defined to say that a telldir
- * cookie may be used only once before it is freed. This option
- * is used to avoid having memory usage grow without bound.
- */
-#define SINGLEUSE
-
-/*
* return a pointer into a directory
*/
long
@@ -61,18 +54,31 @@ telldir(dirp)
DIR *dirp;
{
struct ddloc *lp;
+ long idx;
- if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL)
- return (-1);
if (__isthreaded)
_pthread_mutex_lock(&dirp->dd_lock);
- lp->loc_index = dirp->dd_td->td_loccnt++;
- lp->loc_seek = dirp->dd_seek;
- lp->loc_loc = dirp->dd_loc;
- LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe);
+ LIST_FOREACH(lp, &dirp->dd_td->td_locq, loc_lqe) {
+ if (lp->loc_seek == dirp->dd_seek &&
+ lp->loc_loc == dirp->dd_loc)
+ break;
+ }
+ if (lp == NULL) {
+ lp = malloc(sizeof(struct ddloc));
+ if (lp == NULL) {
+ if (__isthreaded)
+ _pthread_mutex_unlock(&dirp->dd_lock);
+ return (-1);
+ }
+ lp->loc_index = dirp->dd_td->td_loccnt++;
+ lp->loc_seek = dirp->dd_seek;
+ lp->loc_loc = dirp->dd_loc;
+ LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe);
+ }
+ idx = lp->loc_index;
if (__isthreaded)
_pthread_mutex_unlock(&dirp->dd_lock);
- return (lp->loc_index);
+ return (idx);
}
/*
@@ -94,7 +100,7 @@ _seekdir(dirp, loc)
if (lp == NULL)
return;
if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek)
- goto found;
+ return;
(void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET);
dirp->dd_seek = lp->loc_seek;
dirp->dd_loc = 0;
@@ -103,11 +109,6 @@ _seekdir(dirp, loc)
if (dp == NULL)
break;
}
-found:
-#ifdef SINGLEUSE
- LIST_REMOVE(lp, loc_lqe);
- free((caddr_t)lp);
-#endif
}
/*
More information about the svn-src-head
mailing list