UNIXworkcode

1 /* 2 * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 3 * Version 2, December 2004 4 * 5 * Copyright (C) 2016 Olaf Wintermann <olaf.wintermann@gmail.com> 6 * 7 * Everyone is permitted to copy and distribute verbatim or modified 8 * copies of this license document, and changing it is allowed as long 9 * as the name is changed. 10 * 11 * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 12 * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 13 * 14 * 0. You just DO WHAT THE FUCK YOU WANT TO. 15 */ 16 17 #define _GNU_SOURCE 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <sys/types.h> 22 #include <dirent.h> 23 #include <sys/stat.h> 24 #include <unistd.h> 25 #include <fcntl.h> 26 #include <time.h> 27 28 typedef struct FileList FileList; 29 30 struct FileList { 31 char *name; 32 char *path; 33 FileList *next; 34 }; 35 36 void test_stat(FileList *files); 37 void test_open_fstat(FileList *files); 38 void test_open_stat(FileList *files); 39 void test_fstatat(int dirfd, FileList *files); 40 41 int main(int argc, char** argv) { 42 if(argc < 2) { 43 fprintf(stderr, "Usage: %s <dir>\n", argv[0]); 44 return EXIT_FAILURE; 45 } 46 47 char *path = argv[1]; 48 size_t pathlen = strlen(path); 49 DIR *dir = opendir(path); 50 if(!dir) { 51 fprintf(stderr, "Cannot open directory: %s\n", path); 52 return EXIT_FAILURE; 53 } 54 55 FileList *files = NULL; 56 FileList *last = NULL; 57 size_t count = 0; 58 59 struct dirent *entry; 60 while((entry = readdir(dir)) != NULL) { 61 if(!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) { 62 continue; 63 } 64 65 FileList *file = calloc(1, sizeof(FileList)); 66 file->name = strdup(entry->d_name); 67 68 if(path[pathlen - 1] == '/') { 69 asprintf(&file->path, "%s%s", path, entry->d_name); 70 } else { 71 asprintf(&file->path, "%s/%s", path, entry->d_name); 72 } 73 74 if(!files) { 75 files = file; 76 } else { 77 last->next = file; 78 } 79 last = file; 80 count++; 81 } 82 83 if(files) { 84 printf("test %zu files:\n\n", count); 85 86 test_stat(files); 87 88 test_fstatat(dirfd(dir), files); 89 90 printf("----------------------------------------\n\n"); 91 92 test_open_stat(files); 93 94 test_open_fstat(files); 95 } else { 96 fprintf(stderr, "No files in %s\n", path); 97 } 98 99 // cleanup 100 FileList *elm = files; 101 while(elm) { 102 free(elm->name); 103 free(elm->path); 104 FileList *next = elm->next; 105 free(elm); 106 elm = next; 107 } 108 closedir(dir); 109 110 return EXIT_SUCCESS; 111 } 112 113 void test_stat(FileList *files) { 114 printf("test_stat\n"); 115 struct timespec begin; 116 clock_gettime(CLOCK_REALTIME, &begin); 117 118 FileList *elm = files; 119 while(elm) { 120 struct stat s; 121 if(stat(elm->path, &s)) { 122 perror("stat"); 123 fprintf(stderr, "file: %s\n", elm->path); 124 } 125 elm = elm->next; 126 } 127 128 struct timespec end; 129 clock_gettime(CLOCK_REALTIME, &end); 130 printf("time: %ld ns\n\n", end.tv_nsec - begin.tv_nsec); 131 } 132 133 void test_fstatat(int dirfd, FileList *files) { 134 printf("test_fstatat\n"); 135 struct timespec begin; 136 clock_gettime(CLOCK_REALTIME, &begin); 137 138 FileList *elm = files; 139 while(elm) { 140 struct stat s; 141 if(fstatat(dirfd, elm->name, &s, 0)) { 142 perror("stat"); 143 fprintf(stderr, "file: %s\n", elm->path); 144 } 145 elm = elm->next; 146 } 147 148 timespec end; 149 clock_gettime(CLOCK_REALTIME, &end); 150 printf("time: %ld ns\n\n", end.tv_nsec - begin.tv_nsec); 151 } 152 153 void test_open_fstat(FileList *files) { 154 printf("test_open_fstat\n"); 155 struct timespec begin; 156 clock_gettime(CLOCK_REALTIME, &begin); 157 158 FileList *elm = files; 159 while(elm) { 160 int fd = open(elm->path, O_RDONLY); 161 if(fd == -1) { 162 perror("open"); 163 fprintf(stderr, "file: %s\n", elm->path); 164 elm = elm->next; 165 continue; 166 } 167 168 struct stat s; 169 if(fstat(fd, &s)) { 170 perror("fstat"); 171 fprintf(stderr, "file: %s\n", elm->path); 172 } 173 174 close(fd); 175 176 elm = elm->next; 177 } 178 179 struct timespec end; 180 clock_gettime(CLOCK_REALTIME, &end); 181 printf("time: %ld ns\n\n", end.tv_nsec - begin.tv_nsec); 182 } 183 184 void test_open_stat(FileList *files) { 185 printf("test_open_stat\n"); 186 struct timespec begin; 187 clock_gettime(CLOCK_REALTIME, &begin); 188 189 FileList *elm = files; 190 while(elm) { 191 int fd = open(elm->path, O_RDONLY); 192 if(fd == -1) { 193 perror("open"); 194 fprintf(stderr, "file: %s\n", elm->path); 195 elm = elm->next; 196 continue; 197 } 198 199 struct stat s; 200 if(stat(elm->path, &s)) { 201 perror("stat"); 202 fprintf(stderr, "file: %s\n", elm->path); 203 } 204 205 close(fd); 206 207 elm = elm->next; 208 } 209 210 struct timespec end; 211 clock_gettime(CLOCK_REALTIME, &end); 212 printf("time: %ld ns\n\n", end.tv_nsec - begin.tv_nsec); 213 } 214 215