summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2004-11-26 20:09:57 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2004-11-26 20:09:57 +0000
commit4157921535281a74d8ad3b91b803cdead55d4792 (patch)
tree4e0c47ae0cd75348e395d1bb67a81e2e3abbfc9c /usr.bin
parent8f40035a88fee575709a5aa28fed7b098e3854ad (diff)
Fix the getdirentries() loop memory handling and EOF detection.
Also fix typo in sizeof. Problem spotted by YAMAMOTO Takashi; this diff joint work with millert@ ok millert@
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/diff/diffdir.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/usr.bin/diff/diffdir.c b/usr.bin/diff/diffdir.c
index 1a870701533..771052243fb 100644
--- a/usr.bin/diff/diffdir.c
+++ b/usr.bin/diff/diffdir.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: diffdir.c,v 1.28 2004/10/02 18:13:24 millert Exp $ */
+/* $OpenBSD: diffdir.c,v 1.29 2004/11/26 20:09:56 otto Exp $ */
/*
* Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -21,7 +21,7 @@
*/
#ifndef lint
-static const char rcsid[] = "$OpenBSD: diffdir.c,v 1.28 2004/10/02 18:13:24 millert Exp $";
+static const char rcsid[] = "$OpenBSD: diffdir.c,v 1.29 2004/11/26 20:09:56 otto Exp $";
#endif /* not lint */
#include <sys/param.h>
@@ -165,7 +165,7 @@ static struct dirent **
slurpdir(char *path, char **bufp, int enoentok)
{
char *buf, *ebuf, *cp;
- size_t bufsize;
+ size_t bufsize, have, need;
long base;
int fd, nbytes, entries;
struct stat sb;
@@ -181,28 +181,35 @@ slurpdir(char *path, char **bufp, int enoentok)
}
return (&dummy);
}
- fstat(fd, &sb);
+ if (fstat(fd, &sb) == -1) {
+ warn("%s", path);
+ close(fd);
+ return (NULL);
+ }
+
+ need = roundup(sb.st_blksize, sizeof(struct dirent));
+ have = bufsize = roundup(MAX(sb.st_size, sb.st_blksize),
+ sizeof(struct dirent)) + need;
+ ebuf = buf = emalloc(bufsize);
- bufsize = 0;
- ebuf = buf = NULL;
do {
- bufsize += roundup(MAX(sb.st_size, sb.st_blksize),
- sizeof(struct dirent));
- if (buf == NULL)
- buf = ebuf = emalloc(bufsize);
- else {
+ if (have < need) {
+ bufsize += need;
+ have += need;
cp = erealloc(buf, bufsize);
ebuf = cp + (ebuf - buf);
buf = cp;
}
- nbytes = getdirentries(fd, ebuf, bufsize, &base);
+ nbytes = getdirentries(fd, ebuf, have, &base);
if (nbytes == -1) {
- free(buf);
warn("%s", path);
+ free(buf);
+ close(fd);
return (NULL);
}
ebuf += nbytes;
- } while (nbytes == bufsize);
+ have -= nbytes;
+ } while (nbytes != 0);
close(fd);
/*
@@ -232,7 +239,7 @@ slurpdir(char *path, char **bufp, int enoentok)
}
dirlist[entries] = NULL;
- qsort(dirlist, entries, sizeof(struct dir *), dircompare);
+ qsort(dirlist, entries, sizeof(struct dirent *), dircompare);
*bufp = buf;
return (dirlist);