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      struct 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