update
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/dirent.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct dirent *entry;
|
||||
off_t base, before, start;
|
||||
char *buffer;
|
||||
char *end;
|
||||
size_t buffer_size;
|
||||
ssize_t bytes;
|
||||
int calls, fd;
|
||||
|
||||
if (argc < 2 || argc > 5)
|
||||
errx(2, "usage: %s directory [offset [buffer-size [calls]]]",
|
||||
argv[0]);
|
||||
start = argc >= 3 ? strtoll(argv[2], NULL, 0) : 0;
|
||||
buffer_size = argc >= 4 ? strtoul(argv[3], NULL, 0) : 128;
|
||||
calls = argc >= 5 ? strtol(argv[4], NULL, 0) : 32;
|
||||
if (buffer_size < 32 || calls < 1)
|
||||
errx(2, "invalid buffer size or call count");
|
||||
|
||||
fd = open(argv[1], O_RDONLY | O_DIRECTORY);
|
||||
if (fd < 0)
|
||||
err(1, "open %s", argv[1]);
|
||||
if (lseek(fd, start, SEEK_SET) < 0)
|
||||
err(1, "lseek %jd", (intmax_t)start);
|
||||
buffer = malloc(buffer_size);
|
||||
if (buffer == NULL)
|
||||
err(1, "malloc");
|
||||
|
||||
for (int call = 0; call < calls; call++) {
|
||||
before = lseek(fd, 0, SEEK_CUR);
|
||||
if (before < 0)
|
||||
err(1, "lseek current");
|
||||
base = -1;
|
||||
bytes = getdirentries(fd, buffer, buffer_size, &base);
|
||||
if (bytes < 0)
|
||||
err(1, "getdirentries");
|
||||
printf("call=%d before=%jd after=%jd base=%jd bytes=%zd\n",
|
||||
call, (intmax_t)before,
|
||||
(intmax_t)lseek(fd, 0, SEEK_CUR), (intmax_t)base, bytes);
|
||||
if (bytes == 0)
|
||||
break;
|
||||
end = buffer + bytes;
|
||||
for (entry = (struct dirent *)buffer;
|
||||
(char *)entry < end;
|
||||
entry = (struct dirent *)((char *)entry + entry->d_reclen)) {
|
||||
if (entry->d_reclen == 0 ||
|
||||
(char *)entry + entry->d_reclen > end)
|
||||
errx(1, "invalid dirent record");
|
||||
printf(" off=%jd ino=%ju reclen=%u type=%u name=%.*s\n",
|
||||
(intmax_t)entry->d_off, (uintmax_t)entry->d_fileno,
|
||||
entry->d_reclen, entry->d_type, entry->d_namlen,
|
||||
entry->d_name);
|
||||
}
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
Reference in New Issue
Block a user