summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2006-04-10 12:04:21 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2006-04-10 12:04:21 +0000
commitb1ed248b9d27839ae587bfba6ce748391d93f822 (patch)
tree8043001441b8ab63a6615f80278ae5aebacb1a45
parent8daf75a59aebaf705f358ad191f37df523ea7f7b (diff)
telldir/seekdir optimization, avoid scanning the complete list,
while still returning the correct index for seekdir(); telldir() Tested by Fred Crowson and others; "put it in" deraadt@
-rw-r--r--lib/libc/gen/opendir.c4
-rw-r--r--lib/libc/gen/telldir.c14
-rw-r--r--lib/libc/gen/telldir.h3
3 files changed, 14 insertions, 7 deletions
diff --git a/lib/libc/gen/opendir.c b/lib/libc/gen/opendir.c
index 35c8f08346c..73413b02bdb 100644
--- a/lib/libc/gen/opendir.c
+++ b/lib/libc/gen/opendir.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: opendir.c,v 1.16 2006/04/01 18:06:59 otto Exp $ */
+/* $OpenBSD: opendir.c,v 1.17 2006/04/10 12:04:20 otto Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -78,7 +78,7 @@ __opendir2(const char *name, int flags)
dirp->dd_td->td_locs = NULL;
dirp->dd_td->td_sz = 0;
dirp->dd_td->td_loccnt = 0;
-
+ dirp->dd_td->td_last = 0;
/*
* If the machine's page size is an exact multiple of DIRBLKSIZ,
diff --git a/lib/libc/gen/telldir.c b/lib/libc/gen/telldir.c
index e25bb53bca3..708b923f3a0 100644
--- a/lib/libc/gen/telldir.c
+++ b/lib/libc/gen/telldir.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: telldir.c,v 1.8 2006/04/01 18:06:59 otto Exp $ */
+/* $OpenBSD: telldir.c,v 1.9 2006/04/10 12:04:20 otto Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -42,14 +42,18 @@
long
telldir(DIR *dirp)
{
- long i = 0;
- struct ddloc *lp = dirp->dd_td->td_locs;
+ long i = dirp->dd_td->td_last;
+ struct ddloc *lp;
+
+ lp = &dirp->dd_td->td_locs[i];
/* return previous telldir, if there */
for (; i < dirp->dd_td->td_loccnt; i++, lp++) {
if (lp->loc_seek == dirp->dd_seek &&
- lp->loc_loc == dirp->dd_loc)
+ lp->loc_loc == dirp->dd_loc) {
+ dirp->dd_td->td_last = i;
return (i);
+ }
}
if (dirp->dd_td->td_loccnt == dirp->dd_td->td_sz) {
@@ -65,6 +69,7 @@ telldir(DIR *dirp)
dirp->dd_td->td_loccnt++;
lp->loc_seek = dirp->dd_seek;
lp->loc_loc = dirp->dd_loc;
+ dirp->dd_td->td_last = i;
return (i);
}
@@ -81,6 +86,7 @@ __seekdir(DIR *dirp, long loc)
if (loc < 0 || loc >= dirp->dd_td->td_loccnt)
return;
lp = &dirp->dd_td->td_locs[loc];
+ dirp->dd_td->td_last = loc;
if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek)
return;
(void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET);
diff --git a/lib/libc/gen/telldir.h b/lib/libc/gen/telldir.h
index 7e10ed9e497..7991212d22d 100644
--- a/lib/libc/gen/telldir.h
+++ b/lib/libc/gen/telldir.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: telldir.h,v 1.1 2006/04/01 18:06:59 otto Exp $ */
+/* $OpenBSD: telldir.h,v 1.2 2006/04/10 12:04:20 otto Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -55,6 +55,7 @@ struct _telldir {
struct ddloc *td_locs; /* locations */
size_t td_sz; /* size of locations */
long td_loccnt; /* index of entry for sequential readdir's */
+ long td_last; /* last tell/seekdir */
};
void __seekdir(DIR *, long);