UNIXworkcode

/* * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE * Version 2, December 2004 * * Copyright (C) 2016 Olaf Wintermann <olaf.wintermann@gmail.com> * * Everyone is permitted to copy and distribute verbatim or modified * copies of this license document, and changing it is allowed as long * as the name is changed. * * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION * * 0. You just DO WHAT THE FUCK YOU WANT TO. */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <time.h> typedef struct FileList FileList; struct FileList { char *name; char *path; FileList *next; }; void test_stat(FileList *files); void test_open_fstat(FileList *files); void test_open_stat(FileList *files); void test_fstatat(int dirfd, FileList *files); int main(int argc, char** argv) { if(argc < 2) { fprintf(stderr, "Usage: %s <dir>\n", argv[0]); return EXIT_FAILURE; } char *path = argv[1]; size_t pathlen = strlen(path); DIR *dir = opendir(path); if(!dir) { fprintf(stderr, "Cannot open directory: %s\n", path); return EXIT_FAILURE; } FileList *files = NULL; FileList *last = NULL; size_t count = 0; struct dirent *entry; while((entry = readdir(dir)) != NULL) { if(!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) { continue; } FileList *file = calloc(1, sizeof(FileList)); file->name = strdup(entry->d_name); if(path[pathlen - 1] == '/') { asprintf(&file->path, "%s%s", path, entry->d_name); } else { asprintf(&file->path, "%s/%s", path, entry->d_name); } if(!files) { files = file; } else { last->next = file; } last = file; count++; } if(files) { printf("test %zu files:\n\n", count); test_stat(files); test_fstatat(dirfd(dir), files); printf("----------------------------------------\n\n"); test_open_stat(files); test_open_fstat(files); } else { fprintf(stderr, "No files in %s\n", path); } // cleanup FileList *elm = files; while(elm) { free(elm->name); free(elm->path); FileList *next = elm->next; free(elm); elm = next; } closedir(dir); return EXIT_SUCCESS; } void test_stat(FileList *files) { printf("test_stat\n"); struct timespec begin; clock_gettime(CLOCK_REALTIME, &begin); FileList *elm = files; while(elm) { struct stat s; if(stat(elm->path, &s)) { perror("stat"); fprintf(stderr, "file: %s\n", elm->path); } elm = elm->next; } struct timespec end; clock_gettime(CLOCK_REALTIME, &end); printf("time: %ld ns\n\n", end.tv_nsec - begin.tv_nsec); } void test_fstatat(int dirfd, FileList *files) { printf("test_fstatat\n"); struct timespec begin; clock_gettime(CLOCK_REALTIME, &begin); FileList *elm = files; while(elm) { struct stat s; if(fstatat(dirfd, elm->name, &s, 0)) { perror("stat"); fprintf(stderr, "file: %s\n", elm->path); } elm = elm->next; } struct timespec end; clock_gettime(CLOCK_REALTIME, &end); printf("time: %ld ns\n\n", end.tv_nsec - begin.tv_nsec); } void test_open_fstat(FileList *files) { printf("test_open_fstat\n"); struct timespec begin; clock_gettime(CLOCK_REALTIME, &begin); FileList *elm = files; while(elm) { int fd = open(elm->path, O_RDONLY); if(fd == -1) { perror("open"); fprintf(stderr, "file: %s\n", elm->path); elm = elm->next; continue; } struct stat s; if(fstat(fd, &s)) { perror("fstat"); fprintf(stderr, "file: %s\n", elm->path); } close(fd); elm = elm->next; } struct timespec end; clock_gettime(CLOCK_REALTIME, &end); printf("time: %ld ns\n\n", end.tv_nsec - begin.tv_nsec); } void test_open_stat(FileList *files) { printf("test_open_stat\n"); struct timespec begin; clock_gettime(CLOCK_REALTIME, &begin); FileList *elm = files; while(elm) { int fd = open(elm->path, O_RDONLY); if(fd == -1) { perror("open"); fprintf(stderr, "file: %s\n", elm->path); elm = elm->next; continue; } struct stat s; if(stat(elm->path, &s)) { perror("stat"); fprintf(stderr, "file: %s\n", elm->path); } close(fd); elm = elm->next; } struct timespec end; clock_gettime(CLOCK_REALTIME, &end); printf("time: %ld ns\n\n", end.tv_nsec - begin.tv_nsec); }