#include #include #include #include #include #include #include #include #if 1 #define PREFIX "________________________________________________________________________________________________________________________________________________________________________________________________" #else #define PREFIX "________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________" #endif #define PRINT_STEP 1000 #define N_FILES 65536 #define DEFAULT_PATH "." static unsigned long n_files = N_FILES; static char *path = DEFAULT_PATH; static unsigned long n_loops = -1; static bool *map; static bool dir = false; static bool lnk = false; static char *file_name(unsigned long i) { static char fn[8192]; snprintf(fn, sizeof(fn), "%s/" PREFIX "%ld", path, i); return fn; } static char link_file[8192]; static void test_flip(void) { int r; unsigned long i = random() % n_files; if (map[i]) { if (!dir) r = unlink(file_name(i)); else r = rmdir(file_name(i)); if (r) fprintf(stderr, "\nfile %lu can't be unlinked: %s\n", i, strerror(errno)), exit(1); map[i] = false; } else { if (lnk) { r = link(link_file, file_name(i)); if (r < 0) fprintf(stderr, "\nfile %lu can't be linked: %s\n", i, strerror(errno)), exit(1); } else if (!dir) { r = open(file_name(i), O_RDONLY | O_CREAT | O_EXCL, 0644); if (r < 0) fprintf(stderr, "\nfile %lu can't be created: %s\n", i, strerror(errno)), exit(1); r = close(r); if (r) fprintf(stderr, "\nfile %lu can't be closed: %s\n", i, strerror(errno)), exit(1); } else { r = mkdir(file_name(i), 0755); if (r < 0) fprintf(stderr, "\nfile %lu can't be created: %s\n", i, strerror(errno)), exit(1); } map[i] = true; } } static void test_access(void) { int r; unsigned long i = random() % n_files; r = open(file_name(i), O_RDONLY); if (!map[i]) { if (r >= 0) fprintf(stderr, "\nfile %lu was incorrectly opened\n", i), exit(1); if (errno != ENOENT) fprintf(stderr, "\nnon-existing file %lu can't be open: %s\n", i, strerror(errno)), exit(1); } else { if (r < 0) fprintf(stderr, "\nfile %lu can't be open: %s\n", i, strerror(errno)), exit(1); r = close(r); if (r) fprintf(stderr, "\nfile %lu can't be closed: %s\n", i, strerror(errno)), exit(1); } } int main(int argc, char *argv[]) { unsigned long i; if (argc >= 2) path = argv[1]; if (argc >= 3) n_files = strtoul(argv[2], NULL, 10); if (argc >= 4) n_loops = strtol(argv[3], NULL, 10); if (argc >= 5) { if (!strcmp(argv[4], "dir")) dir = true; if (!strcmp(argv[4], "link")) lnk = true; } if (!n_files) fprintf(stderr, "\nzero files\n"), exit(1); map = calloc(n_files, sizeof(bool)); if (!map) perror("calloc"), exit(1); for (i = 0; i < n_files; i++) { if (!(i % PRINT_STEP)) fprintf(stderr, "deleting: %lu\r", i); unlink(file_name(i)); rmdir(file_name(i)); } fprintf(stderr, "\n"); if (argc >= 4 && !strcmp(argv[3], "d")) return 0; if (lnk) { int r = open(strcpy(link_file, file_name(i)), O_RDONLY | O_CREAT, 0644); if (r < 0) fprintf(stderr, "\nfile can't be created: %s\n", strerror(errno)), exit(1); r = close(r); if (r) fprintf(stderr, "\nfile can't be closed: %s\n", strerror(errno)), exit(1); } i = 0; while (i < n_loops) { test_flip(); test_access(); if (!(i % PRINT_STEP)) fprintf(stderr, "%lu\r", i); i++; } return 0; }