aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/gen/telldir.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/gen/telldir.c')
-rw-r--r--lib/libc/gen/telldir.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/lib/libc/gen/telldir.c b/lib/libc/gen/telldir.c
index 4954b973a915..d72b500b051c 100644
--- a/lib/libc/gen/telldir.c
+++ b/lib/libc/gen/telldir.c
@@ -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
}
/*