Skip to content

Instantly share code, notes, and snippets.

@abrasive
Created May 28, 2019 12:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abrasive/f062f967cc41c797bd08ec11f30f8fbf to your computer and use it in GitHub Desktop.
Save abrasive/f062f967cc41c797bd08ec11f30f8fbf to your computer and use it in GitHub Desktop.
/* Reproduce incorrect lseek(fd, 0, SEEK_DATA) results on freshly written files. */
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
int rand_fd;
char buf[1000000];
void make_random_file(const char *filename, size_t size) {
// it must be a new file
unlink(filename);
int fd = open(filename, O_CREAT|O_WRONLY, 0644);
if (fd < 0) {
perror("open");
exit(1);
}
size_t len = read(rand_fd, buf, size);
if (len < 0) {
perror("read /dev/urandom");
exit(1);
}
write(fd, buf, len);
close(fd);
}
int main(int argc, char **argv) {
int nfiles = 1000;
if (argc != 2) {
printf("usage: %s workdir\n", argv[0]);
return 1;
}
rand_fd = open("/dev/urandom", O_RDONLY);
if (rand_fd < 0) {
perror("open /dev/urandom");
exit(1);
}
char srcname[PATH_MAX];
for (int i=0; i<nfiles; i++) {
sprintf(srcname, "%s/test%05x", argv[1], i);
int size = (i & 1) ? 10000 : 1000000;
make_random_file(srcname, size);
}
close(rand_fd);
int bad = 0;
for (int i=0; i<nfiles; i++) {
sprintf(srcname, "%s/test%05x", argv[1], i);
int fd = open(srcname, O_RDONLY);
struct stat st;
fstat(fd, &st);
off_t offset = lseek(fd, 0, SEEK_DATA);
if (offset < 0) {
if (errno == ENXIO)
printf("%s: SEEK_DATA says no data, true size %ld\n", srcname, st.st_size);
else
printf("%s: unexpected error??\n", srcname);
bad = 1;
}
}
return bad;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment