version 1.28, 2004/10/02 18:13:24 |
version 1.29, 2004/11/26 20:09:56 |
|
|
slurpdir(char *path, char **bufp, int enoentok) |
slurpdir(char *path, char **bufp, int enoentok) |
{ |
{ |
char *buf, *ebuf, *cp; |
char *buf, *ebuf, *cp; |
size_t bufsize; |
size_t bufsize, have, need; |
long base; |
long base; |
int fd, nbytes, entries; |
int fd, nbytes, entries; |
struct stat sb; |
struct stat sb; |
|
|
} |
} |
return (&dummy); |
return (&dummy); |
} |
} |
fstat(fd, &sb); |
if (fstat(fd, &sb) == -1) { |
|
warn("%s", path); |
|
close(fd); |
|
return (NULL); |
|
} |
|
|
bufsize = 0; |
need = roundup(sb.st_blksize, sizeof(struct dirent)); |
ebuf = buf = NULL; |
have = bufsize = roundup(MAX(sb.st_size, sb.st_blksize), |
|
sizeof(struct dirent)) + need; |
|
ebuf = buf = emalloc(bufsize); |
|
|
do { |
do { |
bufsize += roundup(MAX(sb.st_size, sb.st_blksize), |
if (have < need) { |
sizeof(struct dirent)); |
bufsize += need; |
if (buf == NULL) |
have += need; |
buf = ebuf = emalloc(bufsize); |
|
else { |
|
cp = erealloc(buf, bufsize); |
cp = erealloc(buf, bufsize); |
ebuf = cp + (ebuf - buf); |
ebuf = cp + (ebuf - buf); |
buf = cp; |
buf = cp; |
} |
} |
nbytes = getdirentries(fd, ebuf, bufsize, &base); |
nbytes = getdirentries(fd, ebuf, have, &base); |
if (nbytes == -1) { |
if (nbytes == -1) { |
free(buf); |
|
warn("%s", path); |
warn("%s", path); |
|
free(buf); |
|
close(fd); |
return (NULL); |
return (NULL); |
} |
} |
ebuf += nbytes; |
ebuf += nbytes; |
} while (nbytes == bufsize); |
have -= nbytes; |
|
} while (nbytes != 0); |
close(fd); |
close(fd); |
|
|
/* |
/* |
|
|
} |
} |
dirlist[entries] = NULL; |
dirlist[entries] = NULL; |
|
|
qsort(dirlist, entries, sizeof(struct dir *), dircompare); |
qsort(dirlist, entries, sizeof(struct dirent *), dircompare); |
|
|
*bufp = buf; |
*bufp = buf; |
return (dirlist); |
return (dirlist); |