1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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
215