#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include static unsigned int FILES_NO = 10000; static int is_dot_or_dotdot(const char* name) { return (name[0] == '.' && !name[1]) || (name[0] == '.' && name[1] == '.' && !name[2]); } int main(int argc, char* argv[]) { int fd = 0, ret = 1; char name[21] = {0}; DIR* dir = NULL; struct dirent* dent = NULL; unsigned long i = 0; char* tmp_name = NULL; char* old_wd = NULL; unsigned char* seen = NULL; setbuf(stdout, NULL); setbuf(stderr, NULL); if (argc != 2 && argc != 3) { fprintf(stderr, "Usage: %s tmp_folder_name [files_count]\n", argv[0]); return 1; } tmp_name = argv[1]; if (argc > 2) { FILES_NO = atol(argv[2]); } if (!(seen = calloc(FILES_NO, sizeof *seen))) { err(1, "calloc"); } if ((old_wd = get_current_dir_name()) == NULL) { err(1, "getcwd"); } if (mkdir(tmp_name, S_IRWXU | S_IRWXG | S_IRWXO) < 0 || chdir(tmp_name) < 0) { err(1, "mkdir & chdir"); } for (i = 0; i < FILES_NO; i++) { snprintf(name, sizeof(name), "%010lu", i); fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); if (fd < 0) { fprintf(stderr, "error: cannot create file %lu: %s\n", i, strerror(errno)); goto cleanup; } if (close(fd) < 0) { fprintf(stderr, "error: close failed with: %s\n", strerror(errno)); goto cleanup; } } dir = opendir("."); if (!dir) { fprintf(stderr, "error: cannot open \".\": %s\n", strerror(errno)); goto cleanup; } while (1) { errno = 0; dent = readdir(dir); if (!dent) { if (errno != 0) { fprintf(stderr, "error: readdir: %s\n", strerror(errno)); goto cleanup; } else { break; } } if (is_dot_or_dotdot(dent->d_name)) { continue; } i = atol(dent->d_name); if (i >= FILES_NO) { fprintf(stderr, "error: weird file found: \"%s\"\n", dent->d_name); goto cleanup; } if (seen[i]) { fprintf(stderr, "error: file \"%s\" seen multiple times\n", dent->d_name); goto cleanup; } seen[i] = 1; } for (i = 0; i < FILES_NO; i++) { if (!seen[i]) { fprintf(stderr, "error: file %lu not seen!\n", i); goto cleanup; } } puts("Success!"); ret = 0; cleanup: if (dir) { closedir(dir); } for (i = 0; i < FILES_NO; i++) { sprintf(name, "%010lu", i); if (unlink(name)) { ret = 1; fprintf(stderr, "error: could not remove file %s: %s\n", name, strerror(errno)); } } if (chdir(old_wd) < 0) { ret = 1; fprintf(stderr, "error: could not change directory to original (%s): %s\n", old_wd, strerror(errno)); } free(old_wd); if (rmdir(tmp_name) < 0) { ret = 1; fprintf(stderr, "error: could not remove tmp directory (%s): %s\n", tmp_name, strerror(errno)); } return ret; }