diff options
author | Pedro Martelletto <pedro@cvs.openbsd.org> | 2005-05-26 03:48:19 +0000 |
---|---|---|
committer | Pedro Martelletto <pedro@cvs.openbsd.org> | 2005-05-26 03:48:19 +0000 |
commit | ace142c89cb83cf6c8f04ed0bdc58d648ae9df20 (patch) | |
tree | 91e48a1bd4b3e7aa82b2053d33ff34320b19c019 /lib/libc | |
parent | 3173f06181eb64c6de5843ff6477e37438ec7e44 (diff) |
union is gone, ok millert@
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/gen/opendir.c | 174 |
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; |