summaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
authorPedro Martelletto <pedro@cvs.openbsd.org>2005-05-26 03:48:19 +0000
committerPedro Martelletto <pedro@cvs.openbsd.org>2005-05-26 03:48:19 +0000
commitace142c89cb83cf6c8f04ed0bdc58d648ae9df20 (patch)
tree91e48a1bd4b3e7aa82b2053d33ff34320b19c019 /lib/libc
parent3173f06181eb64c6de5843ff6477e37438ec7e44 (diff)
union is gone, ok millert@
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/gen/opendir.c174
1 files changed, 9 insertions, 165 deletions
diff --git a/lib/libc/gen/opendir.c b/lib/libc/gen/opendir.c
index bc09745f2cc..1c6204dc0ee 100644
--- a/lib/libc/gen/opendir.c
+++ b/lib/libc/gen/opendir.c
@@ -28,7 +28,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: opendir.c,v 1.11 2005/03/01 13:51:47 miod Exp $";
+static char rcsid[] = "$OpenBSD: opendir.c,v 1.12 2005/05/26 03:48:18 pedro Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -77,7 +77,6 @@ __opendir2(const char *name, int flags)
struct stat sb;
int pagesz;
int incr;
- int unionstack;
if ((fd = open(name, O_RDONLY | O_NONBLOCK)) == -1)
return (NULL);
@@ -103,171 +102,16 @@ __opendir2(const char *name, int flags)
else
incr = DIRBLKSIZ;
- /*
- * Determine whether this directory is the top of a union stack.
- */
- if (flags & DTF_NODUP) {
- struct statfs sfb;
-
- if (fstatfs(fd, &sfb) < 0) {
- free(dirp);
- close(fd);
- return (NULL);
- }
- unionstack = strncmp(sfb.f_fstypename, MOUNT_UNION, MFSNAMELEN) == 0 ||
- (sfb.f_flags & MNT_UNION);
- } else {
- unionstack = 0;
+ dirp->dd_len = incr;
+ dirp->dd_buf = malloc(dirp->dd_len);
+ if (dirp->dd_buf == NULL) {
+ free(dirp);
+ close (fd);
+ return (NULL);
}
- if (unionstack) {
- int len = 0;
- int space = 0;
- char *buf = 0;
- char *ddptr = 0;
- char *ddeptr;
- int n;
- struct dirent **dpv;
-
- /*
- * The strategy here is to read all the directory
- * entries into a buffer, sort the buffer, and
- * remove duplicate entries by setting the inode
- * number to zero.
- */
-
- do {
- /*
- * Always make at least DIRBLKSIZ bytes
- * available to getdirentries
- */
- if (space < DIRBLKSIZ) {
- char *nbuf;
-
- space += incr;
- len += incr;
- nbuf = realloc(buf, len);
- if (nbuf == NULL) {
- if (buf)
- free(buf);
- free(dirp);
- close(fd);
- return (NULL);
- }
- buf = nbuf;
- ddptr = buf + (len - space);
- }
-
- n = getdirentries(fd, ddptr, space, &dirp->dd_seek);
- if (n > 0) {
- ddptr += n;
- space -= n;
- }
- } while (n > 0);
-
- ddeptr = ddptr;
- flags |= __DTF_READALL;
-
- /*
- * Re-open the directory.
- * This has the effect of rewinding back to the
- * top of the union stack and is needed by
- * programs which plan to fchdir to a descriptor
- * which has also been read -- see fts.c.
- */
- if (flags & DTF_REWIND) {
- (void) close(fd);
- if ((fd = open(name, O_RDONLY)) == -1) {
- free(buf);
- free(dirp);
- return (NULL);
- }
- }
-
- /*
- * There is now a buffer full of (possibly) duplicate
- * names.
- */
- dirp->dd_buf = buf;
-
- /*
- * Go round this loop twice...
- *
- * Scan through the buffer, counting entries.
- * On the second pass, save pointers to each one.
- * Then sort the pointers and remove duplicate names.
- */
- for (dpv = 0;;) {
- for (n = 0, ddptr = buf; ddptr < ddeptr;) {
- struct dirent *dp;
-
- dp = (struct dirent *) ddptr;
- if ((long)dp & 03)
- break;
- if ((dp->d_reclen <= 0) ||
- (dp->d_reclen > (ddeptr + 1 - ddptr)))
- break;
- ddptr += dp->d_reclen;
- if (dp->d_fileno) {
- if (dpv)
- dpv[n] = dp;
- n++;
- }
- }
-
- if (dpv) {
- struct dirent *xp;
-
- /*
- * This sort must be stable.
- */
- qsort(dpv, n, sizeof(*dpv), direntcmp);
-
- dpv[n] = NULL;
- xp = NULL;
-
- /*
- * Scan through the buffer in sort order,
- * zapping the inode number of any
- * duplicate names.
- */
- for (n = 0; dpv[n]; n++) {
- struct dirent *dp = dpv[n];
-
- if ((xp == NULL) ||
- strcmp(dp->d_name, xp->d_name))
- xp = dp;
- else
- dp->d_fileno = 0;
- if (dp->d_type == DT_WHT &&
- (flags & DTF_HIDEW))
- dp->d_fileno = 0;
- }
-
- free(dpv);
- break;
- } else {
- if (n+1 > SIZE_T_MAX / sizeof(struct dirent *))
- break;
- dpv = malloc((n+1) * sizeof(struct dirent *));
- if (dpv == NULL)
- break;
- }
- }
-
- dirp->dd_len = len;
- dirp->dd_size = ddptr - dirp->dd_buf;
- } else {
- dirp->dd_len = incr;
- dirp->dd_buf = malloc(dirp->dd_len);
- if (dirp->dd_buf == NULL) {
- free(dirp);
- close (fd);
- return (NULL);
- }
- dirp->dd_seek = 0;
- flags &= ~DTF_REWIND;
- }
+ dirp->dd_seek = 0;
+ flags &= ~DTF_REWIND;
dirp->dd_loc = 0;
dirp->dd_fd = fd;