static void try_getdirentry(int dofork) { int a0 = randint(); void * a1 = randptr(); size_t a2 = randsize(); int result, pid, status; char buf[128]; snprintf(buf, sizeof(buf), "getdirentry(%d, %p, %lu)", (a0), (a1), (unsigned long)(a2)); printf("%-47s", buf); pid = dofork ? fork() : 0; if (pid<0) { err(1, "fork"); } if (pid>0) { waitpid(pid, &status, 0); return; } result = getdirentry(a0, a1, a2); printf(" result %d, errno %d\n", result, errno); if (dofork) { exit(0); } }
static int getdirentry_badfd(int fd) { char buf[32]; return getdirentry(fd, buf, sizeof(buf)); }
static void inval_read(void) { char buf[4096]; int len; len = getdirentry(dirfd, buf, sizeof(buf)-1); /* Any result is ok, as long as the system doesn't crash */ (void)len; }
static void recursedir(const char *path) { int fd; char buf[1024]; char newpath[1024]; int len; /* * Open it. */ fd = open(path, O_RDONLY); if (fd<0) { err(1, "%s", path); } /* * List the directory. */ while ((len = getdirentry(fd, buf, sizeof(buf)-1)) > 0) { buf[len] = 0; /* Assemble the full name of the new item */ snprintf(newpath, sizeof(newpath), "%s/%s", path, buf); if (!aopt && buf[0]=='.') { /* skip this one */ continue; } if (!strcmp(buf, ".") || !strcmp(buf, "..")) { /* always skip these */ continue; } if (!isdir(newpath)) { continue; } listdir(newpath, 1 /*showheader*/); if (Ropt) { recursedir(newpath); } } if (len<0) { err(1, "%s", path); } close(fd); }
/* * Now try listing the directory. */ static void test6(void) { char buf[PATH_MAX]; int fd, len; tprintf("Now trying to list the directory...\n"); startup(); fd = open(".", O_RDONLY); if (fd<0) { err(1, ".: open"); } killdir(); while ((len = getdirentry(fd, buf, sizeof(buf)-1))>0) { if ((unsigned)len >= sizeof(buf)-1) { errx(1, ".: getdirentry: returned invalid length"); } buf[len] = 0; if (!strcmp(buf, ".") || !strcmp(buf, "..")) { /* these are allowed to appear */ continue; } errx(1, ".: getdirentry: returned unexpected name %s", buf); } if (len==0) { /* EOF - ok */ } else { /* len < 0 */ switch (errno) { case EINVAL: case EIO: break; default: err(1, ".: getdirentry"); break; } } finish(); /* close *after* leaving, just for excitement */ if (close(fd)<0) { err(1, "removed %s: close", testdir); } }
/* * List a directory. */ static void listdir(const char *path, int showheader) { int fd; char buf[1024]; char newpath[1024]; int len; if (showheader) { printheader(path); } /* * Open it. */ fd = open(path, O_RDONLY); if (fd<0) { err(1, "%s", path); } /* * List the directory. */ while ((len = getdirentry(fd, buf, sizeof(buf)-1)) > 0) { buf[len] = 0; /* Assemble the full name of the new item */ snprintf(newpath, sizeof(newpath), "%s/%s", path, buf); if (aopt || buf[0]!='.') { /* Print it */ print(newpath); } } if (len<0) { err(1, "%s: getdirentry", path); } /* Done */ close(fd); }
static void readateof(void) { char buf[4096]; int len; len = getdirentry(dirfd, buf, sizeof(buf)-1); if (len < 0) { err(1, ".: at EOF: getdirentry"); } if (len==0) { return; } if ((unsigned)len >= sizeof(buf)-1) { errx(1, ".: at EOF: getdirentry returned " "invalid length %d", len); } buf[len] = 0; errx(1, ".: at EOF: got unexpected name %s", buf); }
static void readone(const char *shouldbe) { char buf[4096]; int len; len = getdirentry(dirfd, buf, sizeof(buf)-1); if (len < 0) { err(1, ".: getdirentry"); } if ((unsigned)len >= sizeof(buf)-1) { errx(1, ".: getdirentry returned invalid length %d", len); } buf[len] = 0; if (strcmp(buf, shouldbe)) { errx(1, ".: getdirentry returned %s (expected %s)", buf, shouldbe); } }
static void readit(void) { char buf[4096]; off_t pos; int len; int n, i, ix; for (i=0; testfiles[i].name; i++) { testfiles[i].pos = -1; } pos = lseek(dirfd, 0, SEEK_CUR); if (pos < 0) { err(1, ".: lseek(0, SEEK_CUR)"); } n = 0; while ((len = getdirentry(dirfd, buf, sizeof(buf)-1)) > 0) { if ((unsigned)len >= sizeof(buf)-1) { errx(1, ".: entry %d: getdirentry returned " "invalid length %d", n, len); } buf[len] = 0; ix = findentry(buf); if (ix < 0) { errx(1, ".: entry %d: getdirentry returned " "unexpected name %s", n, buf); } if (testfiles[ix].pos >= 0) { errx(1, ".: entry %d: getdirentry returned " "%s a second time", n, buf); } testfiles[ix].pos = pos; pos = lseek(dirfd, 0, SEEK_CUR); if (pos < 0) { err(1, ".: lseek(0, SEEK_CUR)"); } n++; } if (len<0) { err(1, ".: entry %d: getdirentry", n); } for (i=0; testfiles[i].name; i++) { if (testfiles[i].pos < 0) { errx(1, ".: getdirentry failed to return %s", testfiles[i].name); } } if (i!=n) { /* * If all of the other checks have passed, this should not * be able to fail. But... just in case I forgot something * or there's a bug... */ errx(1, ".: getdirentry returned %d names, not %d (huh...?)", n, i); } }