socsvn commit: r224051 -
soc2011/gk/ino64-head/tools/regression/readdir-lint
gk at FreeBSD.org
gk at FreeBSD.org
Fri Jul 8 15:49:53 UTC 2011
Author: gk
Date: Fri Jul 8 15:49:51 2011
New Revision: 224051
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=224051
Log:
Update readdir-lint, support building on old systems without dirent.d_off
Modified:
soc2011/gk/ino64-head/tools/regression/readdir-lint/Makefile
soc2011/gk/ino64-head/tools/regression/readdir-lint/readdir-lint.c
Modified: soc2011/gk/ino64-head/tools/regression/readdir-lint/Makefile
==============================================================================
--- soc2011/gk/ino64-head/tools/regression/readdir-lint/Makefile Fri Jul 8 15:49:39 2011 (r224050)
+++ soc2011/gk/ino64-head/tools/regression/readdir-lint/Makefile Fri Jul 8 15:49:51 2011 (r224051)
@@ -4,6 +4,10 @@
PROG= readdir-lint
NO_MAN=
-DEBUG_FLAGS= -O0 -g -I${.CURDIR}/../../../sys
+NO_WERROR=
+DEBUG_FLAGS= -O0 -g -I/usr/src/sys
+
+# disable dirent.d_off
+# CFLAGS+= -DNO_DIRENT_OFF
.include <bsd.prog.mk>
Modified: soc2011/gk/ino64-head/tools/regression/readdir-lint/readdir-lint.c
==============================================================================
--- soc2011/gk/ino64-head/tools/regression/readdir-lint/readdir-lint.c Fri Jul 8 15:49:39 2011 (r224050)
+++ soc2011/gk/ino64-head/tools/regression/readdir-lint/readdir-lint.c Fri Jul 8 15:49:51 2011 (r224051)
@@ -40,21 +40,26 @@
#define HAVE_GETPROGNAME
#endif
+#ifdef NO_DIRENT_OFF
+#define d_off d_fileno
+#endif
+
#define DIRSIZE_MAX (4*1024*1024)
#define DIRSIZE_ENTRY (sizeof(struct dirent))
#define DIRSIZE_MIN ((sizeof (struct dirent) - (MAXNAMLEN+1)) + 4)
#define DIRSIZE_BLOCK 512
#define DIRSIZE_PAGE 4096
-#define DIRENT_MAX 512
+#define DIRENT_HDRSIZE (sizeof(struct dirent) - MAXNAMLEN - 1)
#define DP_NEXT(a) ((struct dirent *)(((char *)(a)) + a->d_reclen))
+#define WARN_NOISE 10
#define WARNX(var, fmt, ...) \
do { \
- if ((var) == 0) { \
+ if ((var) < WARN_NOISE) { \
printf(fmt "\n", ## __VA_ARGS__ ); \
- var = 1; \
+ var++; \
} \
} while (0)
@@ -64,12 +69,16 @@
#ifdef HAVE_DIRENT_NAMLEN
static int warn_nameterm;
+static int warn_namelen;
#endif
-static int warn_noerr;
+#ifndef NO_DIRENT_OFF
static int warn_seekoff;
-static int warn_zeroino;
static int warn_zerooff;
+#endif
+static int warn_noerr;
+static int warn_zeroino;
static int warn_reclen;
+static int warn_overflow;
struct dirbuf {
struct dirent *dp, *begin, *end;
@@ -115,9 +124,11 @@
off_t seekoff;
int rv;
+ memset(dir->begin, 0xAA, dir->bufsize);
rv = getdirentries(dir->fd, (char *)dir->begin, dir->bufsize, &dir->base);
if (opt_verbose >= 3)
- printf("dir_read %d: len=%d base=%ld\n", dir->fd, rv, dir->base);
+ printf("dir_read %d: len=%d base=%ld\n",
+ dir->fd, rv, dir->base);
if (rv == -1)
return (rv);
if (rv == 0) {
@@ -125,36 +136,61 @@
dir->dp = NULL;
dir->end = NULL;
} else {
+ if (rv > (int)dir->bufsize)
+ WARNX(warn_overflow, "Buffer overflow: buffer size %zd,"
+ " %d bytes written", dir->bufsize, rv);
dir->dp = dir->begin;
dir->end = (struct dirent *)((char *)dir->begin + rv);
seekoff = dir_offset(dir);
for (di = dir->dp; di < dir->end; di = DP_NEXT(di)) {
if (di->d_reclen <= 0 ||
di->d_reclen > (char *)dir->end - (char *)di) {
- WARNX(warn_reclen, "Invalid entry size: %d", di->d_reclen);
- dir->end = di;
- break;
+ WARNX(warn_reclen, "Invalid entry size: %d, "
+ "space left %d: d_fileno=%ju d_off=%08jx",
+ di->d_reclen,
+ (int)((char *)dir->end - (char *)di),
+ (uintmax_t)di->d_fileno,
+ (uintmax_t)di->d_off);
+ if (di->d_reclen <= 0) {
+ rv -= (char *)dir->end - (char *)di;
+ dir->end = di;
+ break;
+ }
+
+ di->d_reclen = (char *)dir->end - (char *)di;
}
#ifdef HAVE_DIRENT_NAMLEN
- if (di->d_namlen > MAXNAMLEN)
- errx(1, "Ivalid name lenghth: %d", di->d_namlen);
+ if (di->d_namlen > MAXNAMLEN || di->d_namlen >=
+ di->d_reclen - DIRENT_HDRSIZE)
+ WARNX(warn_namelen, "Ivalid name length: %d "
+ "(reclen %d, max %d)",
+ di->d_namlen, di->d_reclen,
+ di->d_reclen - (int)DIRENT_HDRSIZE);
if (di->d_name[di->d_namlen] != '\0') {
di->d_name[di->d_namlen] = '\0';
- WARNX(warn_nameterm, "Entry names are not NUL-terminated");
+ WARNX(warn_nameterm,
+ "Entry names are not NUL-terminated");
}
#else
#endif
if (di->d_fileno == 0) {
- WARNX(warn_zeroino, "Zero d_fileno: %08jx %s",
- (uintmax_t)di->d_off, di->d_name);
+ WARNX(warn_zeroino,
+ "Zero d_fileno: 0x%08jx #%ju %s",
+ (uintmax_t)di->d_off,
+ (uintmax_t)di->d_fileno, di->d_name);
}
+#ifndef NO_DIRENT_OFF
if (di->d_off == 0)
- WARNX(warn_zerooff, "Zero d_off: %ju %s",
+ WARNX(warn_zerooff,
+ "Zero d_off: 0x%08jx #%ju %s",
+ (uintmax_t)di->d_off,
(uintmax_t)di->d_fileno, di->d_name);
if (DP_NEXT(di) >= dir->end && di->d_off != seekoff) {
- WARNX(warn_seekoff, "Directory(%zd) and last entry offsets mismatch: %ju -- %ju",
- dir->bufsize, (uintmax_t)seekoff, (uintmax_t)di->d_off);
+ WARNX(warn_seekoff, "Directory and last "
+ "entry offsets mismatch: %08jx -- %08jx",
+ (uintmax_t)seekoff, (uintmax_t)di->d_off);
}
+#endif
}
}
@@ -196,6 +232,9 @@
int rv;
rv = lseek(dir->fd, off, SEEK_SET);
+ if (opt_verbose >= 3)
+ printf("dir_seek %d: offset 0x%08jx, result %d\n",
+ dir->fd, (uintmax_t)off, rv);
if (rv == -1)
err(3, "seek(%jd, SEEK_SET)", (uintmax_t)off);
dir->dp = NULL;
@@ -213,19 +252,27 @@
dp2 = dir2->dp;
if (dir1->eof != dir2->eof)
- errx(3, "Invalid EOF: %d %ld -- %d %ld",
+ errx(3, "Invalid EOF: %d base: 0x%08lx -- %d base: 0x%08lx",
dir1->eof, dir1->base, dir2->eof, dir2->base);
else if (dir1->eof)
return (1);
if (opt_verbose >= 2)
- printf(" %08jx (%d bytes) %-12s -- %08jx (%d bytes) %-12s\n",
- (uintmax_t)dp1->d_off, dp1->d_reclen, dp1->d_name,
- (uintmax_t)dp2->d_off, dp2->d_reclen, dp2->d_name);
+ printf(" 0x%08jx #%-8ju %-12s (reclen %d) -- "
+ "0x%08jx #%-8ju %-12s (reclen %d)\n",
+ (uintmax_t)dp1->d_off, (uintmax_t)dp1->d_fileno,
+ dp1->d_name, dp1->d_reclen,
+ (uintmax_t)dp2->d_off, (uintmax_t)dp2->d_fileno,
+ dp2->d_name, dp2->d_reclen);
if (strcmp(dp1->d_name, dp2->d_name) != 0 ||
- dp1->d_off != dp2->d_off)
- printf("Entries mismatch: %08jx (%d bytes) %-12s -- %08jx (%d bytes) %-12s\n",
- (uintmax_t)dp1->d_off, dp1->d_reclen, dp1->d_name,
- (uintmax_t)dp2->d_off, dp2->d_reclen, dp2->d_name);
+ dp1->d_fileno != dp2->d_fileno ||
+ dp1->d_off != dp2->d_off) {
+ printf("Entries mismatch: 0x%08jx #%-8ju %-12s (reclen %d) "
+ "-- 0x%08jx #%-8ju %-12s (reclen %d)\n",
+ (uintmax_t)dp1->d_off, (uintmax_t)dp1->d_fileno,
+ dp1->d_name, dp1->d_reclen,
+ (uintmax_t)dp2->d_off, (uintmax_t)dp2->d_fileno,
+ dp2->d_name, dp2->d_reclen);
+ }
return (0);
}
@@ -266,31 +313,44 @@
}
static void
-test_minbufsize(struct dirbuf *dir_expect, struct dirbuf *dir)
+test_minbufsize(struct dirbuf *dir_expect, struct dirbuf *dir, int fuzzy)
{
- int len;
+ off_t prevoff;
+ int len, cnt;
if (opt_skip > 0) {
opt_skip--;
return;
}
- printf("Test minimal buffer size\n");
+ printf("Test minimal buffer size (fuzzy %d)\n", fuzzy);
dir_init(dir, opt_path, DIRSIZE_ENTRY);
dir_seek(dir_expect, 0);
dir_read(dir_expect);
+ cnt = 0;
while(!dir_expect->eof) {
- off_t prevoff = dir_offset(dir);
-
+ cnt++;
+#ifndef NO_DIRENT_OFF
+ if (fuzzy >= 2 && cnt % fuzzy == 0) {
+ dir_seek(dir, dir_expect->dp->d_off);
+ dir_next(dir_expect);
+ continue;
+ }
+#endif
+ prevoff = dir_offset(dir);
for (dir->bufsize = DIRSIZE_MIN; dir->bufsize <= DIRSIZE_ENTRY;
dir->bufsize += 4) {
len = dir_readx(dir);
if (len <= 0) {
if (prevoff != dir_offset(dir))
- errx(2, "Directory offset changed but no data read: %jd %jd",
- (uintmax_t)prevoff, (uintmax_t)dir_offset(dir));
+ errx(2, "Directory offset changed but "
+ "no data read: 0x%08jx 0x%08jx",
+ (uintmax_t)prevoff,
+ (uintmax_t)dir_offset(dir));
if (len == 0) {
- WARNX(warn_noerr, "EINVAL expected for small buffer read, 0 byte result");
+ WARNX(warn_noerr,
+ "EINVAL expected for small buffer "
+ "read, 0 byte result");
continue;
}
if (errno == EINVAL)
@@ -298,20 +358,25 @@
err(1, "Directory read");
}
if (opt_verbose >= 1)
- printf(" min size %08jx (%d of %zd bytes) %s\n",
- (uintmax_t)dir->dp->d_off, dir->dp->d_reclen, dir->bufsize,
- dir->dp->d_name);
+ printf(" min size: 0x%08jx #%-8ju %s "
+ "(buffer: %d of %zd bytes)\n",
+ (uintmax_t)dir->dp->d_off,
+ (uintmax_t)dir->dp->d_fileno,
+ dir->dp->d_name,
+ dir->dp->d_reclen, dir->bufsize);
break;
}
if (dir->bufsize > DIRSIZE_ENTRY) {
- errx(2, "Couldn't read entry at offset %jd",
+ errx(2, "Couldn't read entry at offset 0x%08jx",
(uintmax_t)dir_offset(dir));
}
dir->eof = 0;
if (dir_cmpent(dir_expect, dir) != 0)
break;
+#ifndef NO_DIRENT_OFF
+ dir_seek(dir, dir_expect->dp->d_off);
+#endif
dir_next(dir_expect);
- dir_seek(dir, dir->dp->d_off);
}
dir_destroy(dir);
}
@@ -363,7 +428,11 @@
errx(1, "Directory is too large");
test_bufsize(&dir_max, &dir_i);
- test_minbufsize(&dir_max, &dir_i);
+ test_minbufsize(&dir_max, &dir_i, 0);
+#ifndef NO_DIRENT_OFF
+ test_minbufsize(&dir_max, &dir_i, 2);
+ test_minbufsize(&dir_max, &dir_i, 5);
+#endif
return (0);
}
More information about the svn-soc-all
mailing list