libfuse
test_syscalls.c
1 #define _GNU_SOURCE
2 #include "config.h"
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdarg.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <fcntl.h>
10 #include <dirent.h>
11 #include <utime.h>
12 #include <errno.h>
13 #include <assert.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 
17 
18 static char testfile[1024];
19 static char testfile2[1024];
20 static char testdir[1024];
21 static char testdir2[1024];
22 static char subfile[1024];
23 
24 static char testfile_r[1024];
25 static char testfile2_r[1024];
26 static char testdir_r[1024];
27 static char testdir2_r[1024];
28 static char subfile_r[1024];
29 
30 static char testname[256];
31 static char testdata[] = "abcdefghijklmnopqrstuvwxyz";
32 static char testdata2[] = "1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./";
33 static const char *testdir_files[] = { "f1", "f2", NULL};
34 static long seekdir_offsets[4];
35 static char zerodata[4096];
36 static int testdatalen = sizeof(testdata) - 1;
37 static int testdata2len = sizeof(testdata2) - 1;
38 static unsigned int testnum = 1;
39 static unsigned int select_test = 0;
40 static unsigned int skip_test = 0;
41 
42 #define MAX_ENTRIES 1024
43 
44 static void test_perror(const char *func, const char *msg)
45 {
46  fprintf(stderr, "%s %s() - %s: %s\n", testname, func, msg,
47  strerror(errno));
48 }
49 
50 static void test_error(const char *func, const char *msg, ...)
51  __attribute__ ((format (printf, 2, 3)));
52 
53 static void __start_test(const char *fmt, ...)
54  __attribute__ ((format (printf, 1, 2)));
55 
56 static void test_error(const char *func, const char *msg, ...)
57 {
58  va_list ap;
59  fprintf(stderr, "%s %s() - ", testname, func);
60  va_start(ap, msg);
61  vfprintf(stderr, msg, ap);
62  va_end(ap);
63  fprintf(stderr, "\n");
64 }
65 
66 static void success(void)
67 {
68  fprintf(stderr, "%s OK\n", testname);
69 }
70 
71 static void __start_test(const char *fmt, ...)
72 {
73  unsigned int n;
74  va_list ap;
75  n = sprintf(testname, "%3i [", testnum++);
76  va_start(ap, fmt);
77  n += vsprintf(testname + n, fmt, ap);
78  va_end(ap);
79  sprintf(testname + n, "]");
80 }
81 
82 #define start_test(msg, args...) { \
83  if ((select_test && testnum != select_test) || \
84  (testnum == skip_test)) { \
85  testnum++; \
86  return 0; \
87  } \
88  __start_test(msg, ##args); \
89 }
90 
91 #define PERROR(msg) test_perror(__FUNCTION__, msg)
92 #define ERROR(msg, args...) test_error(__FUNCTION__, msg, ##args)
93 
94 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
95 
96 static int check_size(const char *path, int len)
97 {
98  struct stat stbuf;
99  int res = stat(path, &stbuf);
100  if (res == -1) {
101  PERROR("stat");
102  return -1;
103  }
104  if (stbuf.st_size != len) {
105  ERROR("length %u instead of %u", (int) stbuf.st_size,
106  (int) len);
107  return -1;
108  }
109  return 0;
110 }
111 
112 static int fcheck_size(int fd, int len)
113 {
114  struct stat stbuf;
115  int res = fstat(fd, &stbuf);
116  if (res == -1) {
117  PERROR("fstat");
118  return -1;
119  }
120  if (stbuf.st_size != len) {
121  ERROR("length %u instead of %u", (int) stbuf.st_size,
122  (int) len);
123  return -1;
124  }
125  return 0;
126 }
127 
128 static int check_type(const char *path, mode_t type)
129 {
130  struct stat stbuf;
131  int res = lstat(path, &stbuf);
132  if (res == -1) {
133  PERROR("lstat");
134  return -1;
135  }
136  if ((stbuf.st_mode & S_IFMT) != type) {
137  ERROR("type 0%o instead of 0%o", stbuf.st_mode & S_IFMT, type);
138  return -1;
139  }
140  return 0;
141 }
142 
143 static int fcheck_type(int fd, mode_t type)
144 {
145  struct stat stbuf;
146  int res = fstat(fd, &stbuf);
147  if (res == -1) {
148  PERROR("fstat");
149  return -1;
150  }
151  if ((stbuf.st_mode & S_IFMT) != type) {
152  ERROR("type 0%o instead of 0%o", stbuf.st_mode & S_IFMT, type);
153  return -1;
154  }
155  return 0;
156 }
157 
158 static int check_mode(const char *path, mode_t mode)
159 {
160  struct stat stbuf;
161  int res = lstat(path, &stbuf);
162  if (res == -1) {
163  PERROR("lstat");
164  return -1;
165  }
166  if ((stbuf.st_mode & 07777) != mode) {
167  ERROR("mode 0%o instead of 0%o", stbuf.st_mode & 07777, mode);
168  return -1;
169  }
170  return 0;
171 }
172 
173 static int fcheck_mode(int fd, mode_t mode)
174 {
175  struct stat stbuf;
176  int res = fstat(fd, &stbuf);
177  if (res == -1) {
178  PERROR("fstat");
179  return -1;
180  }
181  if ((stbuf.st_mode & 07777) != mode) {
182  ERROR("mode 0%o instead of 0%o", stbuf.st_mode & 07777, mode);
183  return -1;
184  }
185  return 0;
186 }
187 
188 static int check_times(const char *path, time_t atime, time_t mtime)
189 {
190  int err = 0;
191  struct stat stbuf;
192  int res = lstat(path, &stbuf);
193  if (res == -1) {
194  PERROR("lstat");
195  return -1;
196  }
197  if (stbuf.st_atime != atime) {
198  ERROR("atime %li instead of %li", stbuf.st_atime, atime);
199  err--;
200  }
201  if (stbuf.st_mtime != mtime) {
202  ERROR("mtime %li instead of %li", stbuf.st_mtime, mtime);
203  err--;
204  }
205  if (err)
206  return -1;
207 
208  return 0;
209 }
210 
211 #if 0
212 static int fcheck_times(int fd, time_t atime, time_t mtime)
213 {
214  int err = 0;
215  struct stat stbuf;
216  int res = fstat(fd, &stbuf);
217  if (res == -1) {
218  PERROR("fstat");
219  return -1;
220  }
221  if (stbuf.st_atime != atime) {
222  ERROR("atime %li instead of %li", stbuf.st_atime, atime);
223  err--;
224  }
225  if (stbuf.st_mtime != mtime) {
226  ERROR("mtime %li instead of %li", stbuf.st_mtime, mtime);
227  err--;
228  }
229  if (err)
230  return -1;
231 
232  return 0;
233 }
234 #endif
235 
236 static int check_nlink(const char *path, nlink_t nlink)
237 {
238  struct stat stbuf;
239  int res = lstat(path, &stbuf);
240  if (res == -1) {
241  PERROR("lstat");
242  return -1;
243  }
244  if (stbuf.st_nlink != nlink) {
245  ERROR("nlink %li instead of %li", (long) stbuf.st_nlink,
246  (long) nlink);
247  return -1;
248  }
249  return 0;
250 }
251 
252 static int fcheck_nlink(int fd, nlink_t nlink)
253 {
254  struct stat stbuf;
255  int res = fstat(fd, &stbuf);
256  if (res == -1) {
257  PERROR("fstat");
258  return -1;
259  }
260  if (stbuf.st_nlink != nlink) {
261  ERROR("nlink %li instead of %li", (long) stbuf.st_nlink,
262  (long) nlink);
263  return -1;
264  }
265  return 0;
266 }
267 
268 static int check_nonexist(const char *path)
269 {
270  struct stat stbuf;
271  int res = lstat(path, &stbuf);
272  if (res == 0) {
273  ERROR("file should not exist");
274  return -1;
275  }
276  if (errno != ENOENT) {
277  ERROR("file should not exist: %s", strerror(errno));
278  return -1;
279  }
280  return 0;
281 }
282 
283 static int check_buffer(const char *buf, const char *data, unsigned len)
284 {
285  if (memcmp(buf, data, len) != 0) {
286  ERROR("data mismatch");
287  return -1;
288  }
289  return 0;
290 }
291 
292 static int check_data(const char *path, const char *data, int offset,
293  unsigned len)
294 {
295  char buf[4096];
296  int res;
297  int fd = open(path, O_RDONLY);
298  if (fd == -1) {
299  PERROR("open");
300  return -1;
301  }
302  if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
303  PERROR("lseek");
304  close(fd);
305  return -1;
306  }
307  while (len) {
308  int rdlen = len < sizeof(buf) ? len : sizeof(buf);
309  res = read(fd, buf, rdlen);
310  if (res == -1) {
311  PERROR("read");
312  close(fd);
313  return -1;
314  }
315  if (res != rdlen) {
316  ERROR("short read: %u instead of %u", res, rdlen);
317  close(fd);
318  return -1;
319  }
320  if (check_buffer(buf, data, rdlen) != 0) {
321  close(fd);
322  return -1;
323  }
324  data += rdlen;
325  len -= rdlen;
326  }
327  res = close(fd);
328  if (res == -1) {
329  PERROR("close");
330  return -1;
331  }
332  return 0;
333 }
334 
335 static int fcheck_data(int fd, const char *data, int offset,
336  unsigned len)
337 {
338  char buf[4096];
339  int res;
340  if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
341  PERROR("lseek");
342  return -1;
343  }
344  while (len) {
345  int rdlen = len < sizeof(buf) ? len : sizeof(buf);
346  res = read(fd, buf, rdlen);
347  if (res == -1) {
348  PERROR("read");
349  return -1;
350  }
351  if (res != rdlen) {
352  ERROR("short read: %u instead of %u", res, rdlen);
353  return -1;
354  }
355  if (check_buffer(buf, data, rdlen) != 0) {
356  return -1;
357  }
358  data += rdlen;
359  len -= rdlen;
360  }
361  return 0;
362 }
363 
364 static int check_dir_contents(const char *path, const char **contents)
365 {
366  int i;
367  int res;
368  int err = 0;
369  int found[MAX_ENTRIES];
370  const char *cont[MAX_ENTRIES];
371  DIR *dp;
372 
373  for (i = 0; contents[i]; i++) {
374  assert(i < MAX_ENTRIES - 3);
375  found[i] = 0;
376  cont[i] = contents[i];
377  }
378  found[i] = 0;
379  cont[i++] = ".";
380  found[i] = 0;
381  cont[i++] = "..";
382  cont[i] = NULL;
383 
384  dp = opendir(path);
385  if (dp == NULL) {
386  PERROR("opendir");
387  return -1;
388  }
389  memset(found, 0, sizeof(found));
390  while(1) {
391  struct dirent *de;
392  errno = 0;
393  de = readdir(dp);
394  if (de == NULL) {
395  if (errno) {
396  PERROR("readdir");
397  closedir(dp);
398  return -1;
399  }
400  break;
401  }
402  for (i = 0; cont[i] != NULL; i++) {
403  assert(i < MAX_ENTRIES);
404  if (strcmp(cont[i], de->d_name) == 0) {
405  if (found[i]) {
406  ERROR("duplicate entry <%s>",
407  de->d_name);
408  err--;
409  } else
410  found[i] = 1;
411  break;
412  }
413  }
414  if (!cont[i]) {
415  ERROR("unexpected entry <%s>", de->d_name);
416  err --;
417  }
418  }
419  for (i = 0; cont[i] != NULL; i++) {
420  if (!found[i]) {
421  ERROR("missing entry <%s>", cont[i]);
422  err--;
423  }
424  }
425  res = closedir(dp);
426  if (res == -1) {
427  PERROR("closedir");
428  return -1;
429  }
430  if (err)
431  return -1;
432 
433  return 0;
434 }
435 
436 static int create_file(const char *path, const char *data, int len)
437 {
438  int res;
439  int fd;
440 
441  unlink(path);
442  fd = creat(path, 0644);
443  if (fd == -1) {
444  PERROR("creat");
445  return -1;
446  }
447  if (len) {
448  res = write(fd, data, len);
449  if (res == -1) {
450  PERROR("write");
451  close(fd);
452  return -1;
453  }
454  if (res != len) {
455  ERROR("write is short: %u instead of %u", res, len);
456  close(fd);
457  return -1;
458  }
459  }
460  res = close(fd);
461  if (res == -1) {
462  PERROR("close");
463  return -1;
464  }
465  res = check_type(path, S_IFREG);
466  if (res == -1)
467  return -1;
468  res = check_mode(path, 0644);
469  if (res == -1)
470  return -1;
471  res = check_nlink(path, 1);
472  if (res == -1)
473  return -1;
474  res = check_size(path, len);
475  if (res == -1)
476  return -1;
477 
478  if (len) {
479  res = check_data(path, data, 0, len);
480  if (res == -1)
481  return -1;
482  }
483 
484  return 0;
485 }
486 
487 static int cleanup_dir(const char *path, const char **dir_files, int quiet)
488 {
489  int i;
490  int err = 0;
491 
492  for (i = 0; dir_files[i]; i++) {
493  int res;
494  char fpath[1024];
495  sprintf(fpath, "%s/%s", path, dir_files[i]);
496  res = unlink(fpath);
497  if (res == -1 && !quiet) {
498  PERROR("unlink");
499  err --;
500  }
501  }
502  if (err)
503  return -1;
504 
505  return 0;
506 }
507 
508 static int create_dir(const char *path, const char **dir_files)
509 {
510  int res;
511  int i;
512 
513  rmdir(path);
514  res = mkdir(path, 0755);
515  if (res == -1) {
516  PERROR("mkdir");
517  return -1;
518  }
519  res = check_type(path, S_IFDIR);
520  if (res == -1)
521  return -1;
522  res = check_mode(path, 0755);
523  if (res == -1)
524  return -1;
525 
526  for (i = 0; dir_files[i]; i++) {
527  char fpath[1024];
528  sprintf(fpath, "%s/%s", path, dir_files[i]);
529  res = create_file(fpath, "", 0);
530  if (res == -1) {
531  cleanup_dir(path, dir_files, 1);
532  return -1;
533  }
534  }
535  res = check_dir_contents(path, dir_files);
536  if (res == -1) {
537  cleanup_dir(path, dir_files, 1);
538  return -1;
539  }
540 
541  return 0;
542 }
543 
544 static int test_truncate(int len)
545 {
546  const char *data = testdata;
547  int datalen = testdatalen;
548  int res;
549 
550  start_test("truncate(%u)", (int) len);
551  res = create_file(testfile, data, datalen);
552  if (res == -1)
553  return -1;
554 
555  res = truncate(testfile, len);
556  if (res == -1) {
557  PERROR("truncate");
558  return -1;
559  }
560  res = check_size(testfile, len);
561  if (res == -1)
562  return -1;
563 
564  if (len > 0) {
565  if (len <= datalen) {
566  res = check_data(testfile, data, 0, len);
567  if (res == -1)
568  return -1;
569  } else {
570  res = check_data(testfile, data, 0, datalen);
571  if (res == -1)
572  return -1;
573  res = check_data(testfile, zerodata, datalen,
574  len - datalen);
575  if (res == -1)
576  return -1;
577  }
578  }
579  res = unlink(testfile);
580  if (res == -1) {
581  PERROR("unlink");
582  return -1;
583  }
584  res = check_nonexist(testfile);
585  if (res == -1)
586  return -1;
587 
588  success();
589  return 0;
590 }
591 
592 static int test_ftruncate(int len, int mode)
593 {
594  const char *data = testdata;
595  int datalen = testdatalen;
596  int res;
597  int fd;
598 
599  start_test("ftruncate(%u) mode: 0%03o", len, mode);
600  res = create_file(testfile, data, datalen);
601  if (res == -1)
602  return -1;
603 
604  fd = open(testfile, O_WRONLY);
605  if (fd == -1) {
606  PERROR("open");
607  return -1;
608  }
609 
610  res = fchmod(fd, mode);
611  if (res == -1) {
612  PERROR("fchmod");
613  close(fd);
614  return -1;
615  }
616  res = check_mode(testfile, mode);
617  if (res == -1) {
618  close(fd);
619  return -1;
620  }
621  res = ftruncate(fd, len);
622  if (res == -1) {
623  PERROR("ftruncate");
624  close(fd);
625  return -1;
626  }
627  close(fd);
628  res = check_size(testfile, len);
629  if (res == -1)
630  return -1;
631 
632  if (len > 0) {
633  if (len <= datalen) {
634  res = check_data(testfile, data, 0, len);
635  if (res == -1)
636  return -1;
637  } else {
638  res = check_data(testfile, data, 0, datalen);
639  if (res == -1)
640  return -1;
641  res = check_data(testfile, zerodata, datalen,
642  len - datalen);
643  if (res == -1)
644  return -1;
645  }
646  }
647  res = unlink(testfile);
648  if (res == -1) {
649  PERROR("unlink");
650  return -1;
651  }
652  res = check_nonexist(testfile);
653  if (res == -1)
654  return -1;
655 
656  success();
657  return 0;
658 }
659 
660 static int test_seekdir(void)
661 {
662  int i;
663  int res;
664  DIR *dp;
665  struct dirent *de;
666 
667  start_test("seekdir");
668  res = create_dir(testdir, testdir_files);
669  if (res == -1)
670  return res;
671 
672  dp = opendir(testdir);
673  if (dp == NULL) {
674  PERROR("opendir");
675  return -1;
676  }
677 
678  /* Remember dir offsets */
679  for (i = 0; i < ARRAY_SIZE(seekdir_offsets); i++) {
680  seekdir_offsets[i] = telldir(dp);
681  errno = 0;
682  de = readdir(dp);
683  if (de == NULL) {
684  if (errno) {
685  PERROR("readdir");
686  goto fail;
687  }
688  break;
689  }
690  }
691 
692  /* Walk until the end of directory */
693  while (de)
694  de = readdir(dp);
695 
696  /* Start from the last valid dir offset and seek backwards */
697  for (i--; i >= 0; i--) {
698  seekdir(dp, seekdir_offsets[i]);
699  de = readdir(dp);
700  if (de == NULL) {
701  ERROR("Unexpected end of directory after seekdir()");
702  goto fail;
703  }
704  }
705 
706  closedir(dp);
707  res = cleanup_dir(testdir, testdir_files, 0);
708  if (!res)
709  success();
710  return res;
711 fail:
712  closedir(dp);
713  cleanup_dir(testdir, testdir_files, 1);
714  return -1;
715 }
716 
717 #ifdef HAVE_COPY_FILE_RANGE
718 static int test_copy_file_range(void)
719 {
720  const char *data = testdata;
721  int datalen = testdatalen;
722  int err = 0;
723  int res;
724  int fd_in, fd_out;
725  off_t pos_in = 0, pos_out = 0;
726 
727  start_test("copy_file_range");
728  unlink(testfile);
729  fd_in = open(testfile, O_CREAT | O_RDWR, 0644);
730  if (fd_in == -1) {
731  PERROR("creat");
732  return -1;
733  }
734  res = write(fd_in, data, datalen);
735  if (res == -1) {
736  PERROR("write");
737  close(fd_in);
738  return -1;
739  }
740  if (res != datalen) {
741  ERROR("write is short: %u instead of %u", res, datalen);
742  close(fd_in);
743  return -1;
744  }
745 
746  unlink(testfile2);
747  fd_out = creat(testfile2, 0644);
748  if (fd_out == -1) {
749  PERROR("creat");
750  close(fd_in);
751  return -1;
752  }
753  res = copy_file_range(fd_in, &pos_in, fd_out, &pos_out, datalen, 0);
754  if (res == -1) {
755  PERROR("copy_file_range");
756  close(fd_in);
757  close(fd_out);
758  return -1;
759  }
760  if (res != datalen) {
761  ERROR("copy is short: %u instead of %u", res, datalen);
762  close(fd_in);
763  close(fd_out);
764  return -1;
765  }
766 
767  res = close(fd_in);
768  if (res == -1) {
769  PERROR("close");
770  return -1;
771  }
772  res = close(fd_out);
773  if (res == -1) {
774  PERROR("close");
775  return -1;
776  }
777 
778  err = check_data(testfile2, data, 0, datalen);
779 
780  res = unlink(testfile);
781  if (res == -1) {
782  PERROR("unlink");
783  return -1;
784  }
785  res = check_nonexist(testfile);
786  if (res == -1)
787  return -1;
788  if (err)
789  return -1;
790 
791  res = unlink(testfile2);
792  if (res == -1) {
793  PERROR("unlink");
794  return -1;
795  }
796  res = check_nonexist(testfile2);
797  if (res == -1)
798  return -1;
799  if (err)
800  return -1;
801 
802  success();
803  return 0;
804 }
805 #else
806 static int test_copy_file_range(void)
807 {
808  return 0;
809 }
810 #endif
811 
812 static int test_utime(void)
813 {
814  struct utimbuf utm;
815  time_t atime = 987631200;
816  time_t mtime = 123116400;
817  int res;
818 
819  start_test("utime");
820  res = create_file(testfile, NULL, 0);
821  if (res == -1)
822  return -1;
823 
824  utm.actime = atime;
825  utm.modtime = mtime;
826  res = utime(testfile, &utm);
827  if (res == -1) {
828  PERROR("utime");
829  return -1;
830  }
831  res = check_times(testfile, atime, mtime);
832  if (res == -1) {
833  return -1;
834  }
835  res = unlink(testfile);
836  if (res == -1) {
837  PERROR("unlink");
838  return -1;
839  }
840  res = check_nonexist(testfile);
841  if (res == -1)
842  return -1;
843 
844  success();
845  return 0;
846 }
847 
848 static int test_create(void)
849 {
850  const char *data = testdata;
851  int datalen = testdatalen;
852  int err = 0;
853  int res;
854  int fd;
855 
856  start_test("create");
857  unlink(testfile);
858  fd = creat(testfile, 0644);
859  if (fd == -1) {
860  PERROR("creat");
861  return -1;
862  }
863  res = write(fd, data, datalen);
864  if (res == -1) {
865  PERROR("write");
866  close(fd);
867  return -1;
868  }
869  if (res != datalen) {
870  ERROR("write is short: %u instead of %u", res, datalen);
871  close(fd);
872  return -1;
873  }
874  res = close(fd);
875  if (res == -1) {
876  PERROR("close");
877  return -1;
878  }
879  res = check_type(testfile, S_IFREG);
880  if (res == -1)
881  return -1;
882  err += check_mode(testfile, 0644);
883  err += check_nlink(testfile, 1);
884  err += check_size(testfile, datalen);
885  err += check_data(testfile, data, 0, datalen);
886  res = unlink(testfile);
887  if (res == -1) {
888  PERROR("unlink");
889  return -1;
890  }
891  res = check_nonexist(testfile);
892  if (res == -1)
893  return -1;
894  if (err)
895  return -1;
896 
897  success();
898  return 0;
899 }
900 
901 static int test_create_unlink(void)
902 {
903  const char *data = testdata;
904  int datalen = testdatalen;
905  int err = 0;
906  int res;
907  int fd;
908 
909  start_test("create+unlink");
910  unlink(testfile);
911  fd = open(testfile, O_CREAT | O_RDWR | O_TRUNC, 0644);
912  if (fd == -1) {
913  PERROR("creat");
914  return -1;
915  }
916  res = unlink(testfile);
917  if (res == -1) {
918  PERROR("unlink");
919  close(fd);
920  return -1;
921  }
922  res = check_nonexist(testfile);
923  if (res == -1)
924  return -1;
925  res = write(fd, data, datalen);
926  if (res == -1) {
927  PERROR("write");
928  close(fd);
929  return -1;
930  }
931  if (res != datalen) {
932  ERROR("write is short: %u instead of %u", res, datalen);
933  close(fd);
934  return -1;
935  }
936  err += fcheck_type(fd, S_IFREG);
937  err += fcheck_mode(fd, 0644);
938  err += fcheck_nlink(fd, 0);
939  err += fcheck_size(fd, datalen);
940  err += fcheck_data(fd, data, 0, datalen);
941  res = close(fd);
942  if (res == -1) {
943  PERROR("close");
944  err--;
945  }
946  if (err)
947  return -1;
948 
949  success();
950  return 0;
951 }
952 
953 #ifndef __FreeBSD__
954 static int test_mknod(void)
955 {
956  int err = 0;
957  int res;
958 
959  start_test("mknod");
960  unlink(testfile);
961  res = mknod(testfile, 0644, 0);
962  if (res == -1) {
963  PERROR("mknod");
964  return -1;
965  }
966  res = check_type(testfile, S_IFREG);
967  if (res == -1)
968  return -1;
969  err += check_mode(testfile, 0644);
970  err += check_nlink(testfile, 1);
971  err += check_size(testfile, 0);
972  res = unlink(testfile);
973  if (res == -1) {
974  PERROR("unlink");
975  return -1;
976  }
977  res = check_nonexist(testfile);
978  if (res == -1)
979  return -1;
980  if (err)
981  return -1;
982 
983  success();
984  return 0;
985 }
986 #endif
987 
988 #define test_open(exist, flags, mode) do_test_open(exist, flags, #flags, mode)
989 
990 static int do_test_open(int exist, int flags, const char *flags_str, int mode)
991 {
992  char buf[4096];
993  const char *data = testdata;
994  int datalen = testdatalen;
995  unsigned currlen = 0;
996  int err = 0;
997  int res;
998  int fd;
999  off_t off;
1000 
1001  start_test("open(%s, %s, 0%03o)", exist ? "+" : "-", flags_str, mode);
1002  unlink(testfile);
1003  if (exist) {
1004  res = create_file(testfile_r, testdata2, testdata2len);
1005  if (res == -1)
1006  return -1;
1007 
1008  currlen = testdata2len;
1009  }
1010 
1011  fd = open(testfile, flags, mode);
1012  if ((flags & O_CREAT) && (flags & O_EXCL) && exist) {
1013  if (fd != -1) {
1014  ERROR("open should have failed");
1015  close(fd);
1016  return -1;
1017  } else if (errno == EEXIST)
1018  goto succ;
1019  }
1020  if (!(flags & O_CREAT) && !exist) {
1021  if (fd != -1) {
1022  ERROR("open should have failed");
1023  close(fd);
1024  return -1;
1025  } else if (errno == ENOENT)
1026  goto succ;
1027  }
1028  if (fd == -1) {
1029  PERROR("open");
1030  return -1;
1031  }
1032 
1033  if (flags & O_TRUNC)
1034  currlen = 0;
1035 
1036  err += check_type(testfile, S_IFREG);
1037  if (exist)
1038  err += check_mode(testfile, 0644);
1039  else
1040  err += check_mode(testfile, mode);
1041  err += check_nlink(testfile, 1);
1042  err += check_size(testfile, currlen);
1043  if (exist && !(flags & O_TRUNC) && (mode & 0400))
1044  err += check_data(testfile, testdata2, 0, testdata2len);
1045 
1046  res = write(fd, data, datalen);
1047  if ((flags & O_ACCMODE) != O_RDONLY) {
1048  if (res == -1) {
1049  PERROR("write");
1050  err --;
1051  } else if (res != datalen) {
1052  ERROR("write is short: %u instead of %u", res, datalen);
1053  err --;
1054  } else {
1055  if (datalen > (int) currlen)
1056  currlen = datalen;
1057 
1058  err += check_size(testfile, currlen);
1059 
1060  if (mode & 0400) {
1061  err += check_data(testfile, data, 0, datalen);
1062  if (exist && !(flags & O_TRUNC) &&
1063  testdata2len > datalen)
1064  err += check_data(testfile,
1065  testdata2 + datalen,
1066  datalen,
1067  testdata2len - datalen);
1068  }
1069  }
1070  } else {
1071  if (res != -1) {
1072  ERROR("write should have failed");
1073  err --;
1074  } else if (errno != EBADF) {
1075  PERROR("write");
1076  err --;
1077  }
1078  }
1079  off = lseek(fd, SEEK_SET, 0);
1080  if (off == (off_t) -1) {
1081  PERROR("lseek");
1082  err--;
1083  } else if (off != 0) {
1084  ERROR("offset should have returned 0");
1085  err --;
1086  }
1087  res = read(fd, buf, sizeof(buf));
1088  if ((flags & O_ACCMODE) != O_WRONLY) {
1089  if (res == -1) {
1090  PERROR("read");
1091  err--;
1092  } else {
1093  int readsize =
1094  currlen < sizeof(buf) ? currlen : sizeof(buf);
1095  if (res != readsize) {
1096  ERROR("read is short: %i instead of %u",
1097  res, readsize);
1098  err--;
1099  } else {
1100  if ((flags & O_ACCMODE) != O_RDONLY) {
1101  err += check_buffer(buf, data, datalen);
1102  if (exist && !(flags & O_TRUNC) &&
1103  testdata2len > datalen)
1104  err += check_buffer(buf + datalen,
1105  testdata2 + datalen,
1106  testdata2len - datalen);
1107  } else if (exist)
1108  err += check_buffer(buf, testdata2,
1109  testdata2len);
1110  }
1111  }
1112  } else {
1113  if (res != -1) {
1114  ERROR("read should have failed");
1115  err --;
1116  } else if (errno != EBADF) {
1117  PERROR("read");
1118  err --;
1119  }
1120  }
1121 
1122  res = close(fd);
1123  if (res == -1) {
1124  PERROR("close");
1125  return -1;
1126  }
1127  res = unlink(testfile);
1128  if (res == -1) {
1129  PERROR("unlink");
1130  return -1;
1131  }
1132  res = check_nonexist(testfile);
1133  if (res == -1)
1134  return -1;
1135  res = check_nonexist(testfile_r);
1136  if (res == -1)
1137  return -1;
1138  if (err)
1139  return -1;
1140 
1141 succ:
1142  success();
1143  return 0;
1144 }
1145 
1146 #define test_open_acc(flags, mode, err) \
1147  do_test_open_acc(flags, #flags, mode, err)
1148 
1149 static int do_test_open_acc(int flags, const char *flags_str, int mode, int err)
1150 {
1151  const char *data = testdata;
1152  int datalen = testdatalen;
1153  int res;
1154  int fd;
1155 
1156  start_test("open_acc(%s) mode: 0%03o message: '%s'", flags_str, mode,
1157  strerror(err));
1158  unlink(testfile);
1159  res = create_file(testfile, data, datalen);
1160  if (res == -1)
1161  return -1;
1162 
1163  res = chmod(testfile, mode);
1164  if (res == -1) {
1165  PERROR("chmod");
1166  return -1;
1167  }
1168 
1169  res = check_mode(testfile, mode);
1170  if (res == -1)
1171  return -1;
1172 
1173  fd = open(testfile, flags);
1174  if (fd == -1) {
1175  if (err != errno) {
1176  PERROR("open");
1177  return -1;
1178  }
1179  } else {
1180  if (err) {
1181  ERROR("open should have failed");
1182  close(fd);
1183  return -1;
1184  }
1185  close(fd);
1186  }
1187  success();
1188  return 0;
1189 }
1190 
1191 static int test_symlink(void)
1192 {
1193  char buf[1024];
1194  const char *data = testdata;
1195  int datalen = testdatalen;
1196  int linklen = strlen(testfile);
1197  int err = 0;
1198  int res;
1199 
1200  start_test("symlink");
1201  res = create_file(testfile, data, datalen);
1202  if (res == -1)
1203  return -1;
1204 
1205  unlink(testfile2);
1206  res = symlink(testfile, testfile2);
1207  if (res == -1) {
1208  PERROR("symlink");
1209  return -1;
1210  }
1211  res = check_type(testfile2, S_IFLNK);
1212  if (res == -1)
1213  return -1;
1214  err += check_mode(testfile2, 0777);
1215  err += check_nlink(testfile2, 1);
1216  res = readlink(testfile2, buf, sizeof(buf));
1217  if (res == -1) {
1218  PERROR("readlink");
1219  err--;
1220  }
1221  if (res != linklen) {
1222  ERROR("short readlink: %u instead of %u", res, linklen);
1223  err--;
1224  }
1225  if (memcmp(buf, testfile, linklen) != 0) {
1226  ERROR("link mismatch");
1227  err--;
1228  }
1229  err += check_size(testfile2, datalen);
1230  err += check_data(testfile2, data, 0, datalen);
1231  res = unlink(testfile2);
1232  if (res == -1) {
1233  PERROR("unlink");
1234  return -1;
1235  }
1236  res = check_nonexist(testfile2);
1237  if (res == -1)
1238  return -1;
1239  if (err)
1240  return -1;
1241 
1242  success();
1243  return 0;
1244 }
1245 
1246 static int test_link(void)
1247 {
1248  const char *data = testdata;
1249  int datalen = testdatalen;
1250  int err = 0;
1251  int res;
1252 
1253  start_test("link");
1254  res = create_file(testfile, data, datalen);
1255  if (res == -1)
1256  return -1;
1257 
1258  unlink(testfile2);
1259  res = link(testfile, testfile2);
1260  if (res == -1) {
1261  PERROR("link");
1262  return -1;
1263  }
1264  res = check_type(testfile2, S_IFREG);
1265  if (res == -1)
1266  return -1;
1267  err += check_mode(testfile2, 0644);
1268  err += check_nlink(testfile2, 2);
1269  err += check_size(testfile2, datalen);
1270  err += check_data(testfile2, data, 0, datalen);
1271  res = unlink(testfile);
1272  if (res == -1) {
1273  PERROR("unlink");
1274  return -1;
1275  }
1276  res = check_nonexist(testfile);
1277  if (res == -1)
1278  return -1;
1279 
1280  err += check_nlink(testfile2, 1);
1281  res = unlink(testfile2);
1282  if (res == -1) {
1283  PERROR("unlink");
1284  return -1;
1285  }
1286  res = check_nonexist(testfile2);
1287  if (res == -1)
1288  return -1;
1289  if (err)
1290  return -1;
1291 
1292  success();
1293  return 0;
1294 }
1295 
1296 static int test_link2(void)
1297 {
1298  const char *data = testdata;
1299  int datalen = testdatalen;
1300  int err = 0;
1301  int res;
1302 
1303  start_test("link-unlink-link");
1304  res = create_file(testfile, data, datalen);
1305  if (res == -1)
1306  return -1;
1307 
1308  unlink(testfile2);
1309  res = link(testfile, testfile2);
1310  if (res == -1) {
1311  PERROR("link");
1312  return -1;
1313  }
1314  res = unlink(testfile);
1315  if (res == -1) {
1316  PERROR("unlink");
1317  return -1;
1318  }
1319  res = check_nonexist(testfile);
1320  if (res == -1)
1321  return -1;
1322  res = link(testfile2, testfile);
1323  if (res == -1) {
1324  PERROR("link");
1325  }
1326  res = check_type(testfile, S_IFREG);
1327  if (res == -1)
1328  return -1;
1329  err += check_mode(testfile, 0644);
1330  err += check_nlink(testfile, 2);
1331  err += check_size(testfile, datalen);
1332  err += check_data(testfile, data, 0, datalen);
1333 
1334  res = unlink(testfile2);
1335  if (res == -1) {
1336  PERROR("unlink");
1337  return -1;
1338  }
1339  err += check_nlink(testfile, 1);
1340  res = unlink(testfile);
1341  if (res == -1) {
1342  PERROR("unlink");
1343  return -1;
1344  }
1345  res = check_nonexist(testfile);
1346  if (res == -1)
1347  return -1;
1348  if (err)
1349  return -1;
1350 
1351  success();
1352  return 0;
1353 }
1354 
1355 static int test_rename_file(void)
1356 {
1357  const char *data = testdata;
1358  int datalen = testdatalen;
1359  int err = 0;
1360  int res;
1361 
1362  start_test("rename file");
1363  res = create_file(testfile, data, datalen);
1364  if (res == -1)
1365  return -1;
1366 
1367  unlink(testfile2);
1368  res = rename(testfile, testfile2);
1369  if (res == -1) {
1370  PERROR("rename");
1371  return -1;
1372  }
1373  res = check_nonexist(testfile);
1374  if (res == -1)
1375  return -1;
1376  res = check_type(testfile2, S_IFREG);
1377  if (res == -1)
1378  return -1;
1379  err += check_mode(testfile2, 0644);
1380  err += check_nlink(testfile2, 1);
1381  err += check_size(testfile2, datalen);
1382  err += check_data(testfile2, data, 0, datalen);
1383  res = unlink(testfile2);
1384  if (res == -1) {
1385  PERROR("unlink");
1386  return -1;
1387  }
1388  res = check_nonexist(testfile2);
1389  if (res == -1)
1390  return -1;
1391  if (err)
1392  return -1;
1393 
1394  success();
1395  return 0;
1396 }
1397 
1398 static int test_rename_dir(void)
1399 {
1400  int err = 0;
1401  int res;
1402 
1403  start_test("rename dir");
1404  res = create_dir(testdir, testdir_files);
1405  if (res == -1)
1406  return -1;
1407 
1408  rmdir(testdir2);
1409  res = rename(testdir, testdir2);
1410  if (res == -1) {
1411  PERROR("rename");
1412  cleanup_dir(testdir, testdir_files, 1);
1413  return -1;
1414  }
1415  res = check_nonexist(testdir);
1416  if (res == -1) {
1417  cleanup_dir(testdir, testdir_files, 1);
1418  return -1;
1419  }
1420  res = check_type(testdir2, S_IFDIR);
1421  if (res == -1) {
1422  cleanup_dir(testdir2, testdir_files, 1);
1423  return -1;
1424  }
1425  err += check_mode(testdir2, 0755);
1426  err += check_dir_contents(testdir2, testdir_files);
1427  err += cleanup_dir(testdir2, testdir_files, 0);
1428  res = rmdir(testdir2);
1429  if (res == -1) {
1430  PERROR("rmdir");
1431  return -1;
1432  }
1433  res = check_nonexist(testdir2);
1434  if (res == -1)
1435  return -1;
1436  if (err)
1437  return -1;
1438 
1439  success();
1440  return 0;
1441 }
1442 
1443 static int test_rename_dir_loop(void)
1444 {
1445 #define PATH(p) (snprintf(path, sizeof path, "%s/%s", testdir, p), path)
1446 #define PATH2(p) (snprintf(path2, sizeof path2, "%s/%s", testdir, p), path2)
1447 
1448  char path[1024], path2[1024];
1449  int err = 0;
1450  int res;
1451 
1452  start_test("rename dir loop");
1453 
1454  res = create_dir(testdir, testdir_files);
1455  if (res == -1)
1456  return -1;
1457 
1458  res = mkdir(PATH("a"), 0755);
1459  if (res == -1) {
1460  PERROR("mkdir");
1461  goto fail;
1462  }
1463 
1464  res = rename(PATH("a"), PATH2("a"));
1465  if (res == -1) {
1466  PERROR("rename");
1467  goto fail;
1468  }
1469 
1470  errno = 0;
1471  res = rename(PATH("a"), PATH2("a/b"));
1472  if (res == 0 || errno != EINVAL) {
1473  PERROR("rename");
1474  goto fail;
1475  }
1476 
1477  res = mkdir(PATH("a/b"), 0755);
1478  if (res == -1) {
1479  PERROR("mkdir");
1480  goto fail;
1481  }
1482 
1483  res = mkdir(PATH("a/b/c"), 0755);
1484  if (res == -1) {
1485  PERROR("mkdir");
1486  goto fail;
1487  }
1488 
1489  errno = 0;
1490  res = rename(PATH("a"), PATH2("a/b/c"));
1491  if (res == 0 || errno != EINVAL) {
1492  PERROR("rename");
1493  goto fail;
1494  }
1495 
1496  errno = 0;
1497  res = rename(PATH("a"), PATH2("a/b/c/a"));
1498  if (res == 0 || errno != EINVAL) {
1499  PERROR("rename");
1500  goto fail;
1501  }
1502 
1503  errno = 0;
1504  res = rename(PATH("a/b/c"), PATH2("a"));
1505  if (res == 0 || errno != ENOTEMPTY) {
1506  PERROR("rename");
1507  goto fail;
1508  }
1509 
1510  res = open(PATH("a/foo"), O_CREAT, 0644);
1511  if (res == -1) {
1512  PERROR("open");
1513  goto fail;
1514  }
1515  close(res);
1516 
1517  res = rename(PATH("a/foo"), PATH2("a/bar"));
1518  if (res == -1) {
1519  PERROR("rename");
1520  goto fail;
1521  }
1522 
1523  res = rename(PATH("a/bar"), PATH2("a/foo"));
1524  if (res == -1) {
1525  PERROR("rename");
1526  goto fail;
1527  }
1528 
1529  res = rename(PATH("a/foo"), PATH2("a/b/bar"));
1530  if (res == -1) {
1531  PERROR("rename");
1532  goto fail;
1533  }
1534 
1535  res = rename(PATH("a/b/bar"), PATH2("a/foo"));
1536  if (res == -1) {
1537  PERROR("rename");
1538  goto fail;
1539  }
1540 
1541  res = rename(PATH("a/foo"), PATH2("a/b/c/bar"));
1542  if (res == -1) {
1543  PERROR("rename");
1544  goto fail;
1545  }
1546 
1547  res = rename(PATH("a/b/c/bar"), PATH2("a/foo"));
1548  if (res == -1) {
1549  PERROR("rename");
1550  goto fail;
1551  }
1552 
1553  res = open(PATH("a/bar"), O_CREAT, 0644);
1554  if (res == -1) {
1555  PERROR("open");
1556  goto fail;
1557  }
1558  close(res);
1559 
1560  res = rename(PATH("a/foo"), PATH2("a/bar"));
1561  if (res == -1) {
1562  PERROR("rename");
1563  goto fail;
1564  }
1565 
1566  unlink(PATH("a/bar"));
1567 
1568  res = rename(PATH("a/b"), PATH2("a/d"));
1569  if (res == -1) {
1570  PERROR("rename");
1571  goto fail;
1572  }
1573 
1574  res = rename(PATH("a/d"), PATH2("a/b"));
1575  if (res == -1) {
1576  PERROR("rename");
1577  goto fail;
1578  }
1579 
1580  res = mkdir(PATH("a/d"), 0755);
1581  if (res == -1) {
1582  PERROR("mkdir");
1583  goto fail;
1584  }
1585 
1586  res = rename(PATH("a/b"), PATH2("a/d"));
1587  if (res == -1) {
1588  PERROR("rename");
1589  goto fail;
1590  }
1591 
1592  res = rename(PATH("a/d"), PATH2("a/b"));
1593  if (res == -1) {
1594  PERROR("rename");
1595  goto fail;
1596  }
1597 
1598  res = mkdir(PATH("a/d"), 0755);
1599  if (res == -1) {
1600  PERROR("mkdir");
1601  goto fail;
1602  }
1603 
1604  res = mkdir(PATH("a/d/e"), 0755);
1605  if (res == -1) {
1606  PERROR("mkdir");
1607  goto fail;
1608  }
1609 
1610  errno = 0;
1611  res = rename(PATH("a/b"), PATH2("a/d"));
1612  if (res == 0 || errno != ENOTEMPTY) {
1613  PERROR("rename");
1614  goto fail;
1615  }
1616 
1617  rmdir(PATH("a/d/e"));
1618  rmdir(PATH("a/d"));
1619 
1620  rmdir(PATH("a/b/c"));
1621  rmdir(PATH("a/b"));
1622  rmdir(PATH("a"));
1623 
1624  err += cleanup_dir(testdir, testdir_files, 0);
1625  res = rmdir(testdir);
1626  if (res == -1) {
1627  PERROR("rmdir");
1628  goto fail;
1629  }
1630  res = check_nonexist(testdir);
1631  if (res == -1)
1632  return -1;
1633  if (err)
1634  return -1;
1635 
1636  success();
1637  return 0;
1638 
1639 fail:
1640  unlink(PATH("a/bar"));
1641 
1642  rmdir(PATH("a/d/e"));
1643  rmdir(PATH("a/d"));
1644 
1645  rmdir(PATH("a/b/c"));
1646  rmdir(PATH("a/b"));
1647  rmdir(PATH("a"));
1648 
1649  cleanup_dir(testdir, testdir_files, 1);
1650  rmdir(testdir);
1651 
1652  return -1;
1653 
1654 #undef PATH2
1655 #undef PATH
1656 }
1657 
1658 #ifndef __FreeBSD__
1659 static int test_mkfifo(void)
1660 {
1661  int res;
1662  int err = 0;
1663 
1664  start_test("mkfifo");
1665  unlink(testfile);
1666  res = mkfifo(testfile, 0644);
1667  if (res == -1) {
1668  PERROR("mkfifo");
1669  return -1;
1670  }
1671  res = check_type(testfile, S_IFIFO);
1672  if (res == -1)
1673  return -1;
1674  err += check_mode(testfile, 0644);
1675  err += check_nlink(testfile, 1);
1676  res = unlink(testfile);
1677  if (res == -1) {
1678  PERROR("unlink");
1679  return -1;
1680  }
1681  res = check_nonexist(testfile);
1682  if (res == -1)
1683  return -1;
1684  if (err)
1685  return -1;
1686 
1687  success();
1688  return 0;
1689 }
1690 #endif
1691 
1692 static int test_mkdir(void)
1693 {
1694  int res;
1695  int err = 0;
1696  const char *dir_contents[] = {NULL};
1697 
1698  start_test("mkdir");
1699  rmdir(testdir);
1700  res = mkdir(testdir, 0755);
1701  if (res == -1) {
1702  PERROR("mkdir");
1703  return -1;
1704  }
1705  res = check_type(testdir, S_IFDIR);
1706  if (res == -1)
1707  return -1;
1708  err += check_mode(testdir, 0755);
1709  /* Some file systems (like btrfs) don't track link
1710  count for directories */
1711  //err += check_nlink(testdir, 2);
1712  err += check_dir_contents(testdir, dir_contents);
1713  res = rmdir(testdir);
1714  if (res == -1) {
1715  PERROR("rmdir");
1716  return -1;
1717  }
1718  res = check_nonexist(testdir);
1719  if (res == -1)
1720  return -1;
1721  if (err)
1722  return -1;
1723 
1724  success();
1725  return 0;
1726 }
1727 
1728 #define test_create_ro_dir(flags) \
1729  do_test_create_ro_dir(flags, #flags)
1730 
1731 static int do_test_create_ro_dir(int flags, const char *flags_str)
1732 {
1733  int res;
1734  int err = 0;
1735  int fd;
1736 
1737  start_test("open(%s) in read-only directory", flags_str);
1738  rmdir(testdir);
1739  res = mkdir(testdir, 0555);
1740  if (res == -1) {
1741  PERROR("mkdir");
1742  return -1;
1743  }
1744  fd = open(subfile, flags, 0644);
1745  if (fd != -1) {
1746  close(fd);
1747  unlink(subfile);
1748  ERROR("open should have failed");
1749  err--;
1750  } else {
1751  res = check_nonexist(subfile);
1752  if (res == -1)
1753  err--;
1754  }
1755  unlink(subfile);
1756  res = rmdir(testdir);
1757  if (res == -1) {
1758  PERROR("rmdir");
1759  return -1;
1760  }
1761  res = check_nonexist(testdir);
1762  if (res == -1)
1763  return -1;
1764  if (err)
1765  return -1;
1766 
1767  success();
1768  return 0;
1769 }
1770 
1771 int main(int argc, char *argv[])
1772 {
1773  const char *basepath;
1774  const char *realpath;
1775  int err = 0;
1776  int a;
1777  int is_root;
1778 
1779  umask(0);
1780  if (argc < 2 || argc > 4) {
1781  fprintf(stderr, "usage: %s testdir [:realdir] [[-]test#]\n", argv[0]);
1782  return 1;
1783  }
1784  basepath = argv[1];
1785  realpath = basepath;
1786  for (a = 2; a < argc; a++) {
1787  char *endptr;
1788  char *arg = argv[a];
1789  if (arg[0] == ':') {
1790  realpath = arg + 1;
1791  } else {
1792  if (arg[0] == '-') {
1793  arg++;
1794  skip_test = strtoul(arg, &endptr, 10);
1795  } else {
1796  select_test = strtoul(arg, &endptr, 10);
1797  }
1798  if (arg[0] == '\0' || *endptr != '\0') {
1799  fprintf(stderr, "invalid number: '%s'\n", arg);
1800  return 1;
1801  }
1802  }
1803  }
1804  assert(strlen(basepath) < 512);
1805  assert(strlen(realpath) < 512);
1806  if (basepath[0] != '/') {
1807  fprintf(stderr, "testdir must be an absolute path\n");
1808  return 1;
1809  }
1810 
1811  sprintf(testfile, "%s/testfile", basepath);
1812  sprintf(testfile2, "%s/testfile2", basepath);
1813  sprintf(testdir, "%s/testdir", basepath);
1814  sprintf(testdir2, "%s/testdir2", basepath);
1815  sprintf(subfile, "%s/subfile", testdir2);
1816 
1817  sprintf(testfile_r, "%s/testfile", realpath);
1818  sprintf(testfile2_r, "%s/testfile2", realpath);
1819  sprintf(testdir_r, "%s/testdir", realpath);
1820  sprintf(testdir2_r, "%s/testdir2", realpath);
1821  sprintf(subfile_r, "%s/subfile", testdir2_r);
1822 
1823  is_root = (geteuid() == 0);
1824 
1825  err += test_create();
1826  err += test_create_unlink();
1827  err += test_symlink();
1828  err += test_link();
1829  err += test_link2();
1830 #ifndef __FreeBSD__
1831  err += test_mknod();
1832  err += test_mkfifo();
1833 #endif
1834  err += test_mkdir();
1835  err += test_rename_file();
1836  err += test_rename_dir();
1837  err += test_rename_dir_loop();
1838  err += test_seekdir();
1839  err += test_utime();
1840  err += test_truncate(0);
1841  err += test_truncate(testdatalen / 2);
1842  err += test_truncate(testdatalen);
1843  err += test_truncate(testdatalen + 100);
1844  err += test_ftruncate(0, 0600);
1845  err += test_ftruncate(testdatalen / 2, 0600);
1846  err += test_ftruncate(testdatalen, 0600);
1847  err += test_ftruncate(testdatalen + 100, 0600);
1848  err += test_ftruncate(0, 0400);
1849  err += test_ftruncate(0, 0200);
1850  err += test_ftruncate(0, 0000);
1851  err += test_open(0, O_RDONLY, 0);
1852  err += test_open(1, O_RDONLY, 0);
1853  err += test_open(1, O_RDWR, 0);
1854  err += test_open(1, O_WRONLY, 0);
1855  err += test_open(0, O_RDWR | O_CREAT, 0600);
1856  err += test_open(1, O_RDWR | O_CREAT, 0600);
1857  err += test_open(0, O_RDWR | O_CREAT | O_TRUNC, 0600);
1858  err += test_open(1, O_RDWR | O_CREAT | O_TRUNC, 0600);
1859  err += test_open(0, O_RDONLY | O_CREAT, 0600);
1860  err += test_open(0, O_RDONLY | O_CREAT, 0400);
1861  err += test_open(0, O_RDONLY | O_CREAT, 0200);
1862  err += test_open(0, O_RDONLY | O_CREAT, 0000);
1863  err += test_open(0, O_WRONLY | O_CREAT, 0600);
1864  err += test_open(0, O_WRONLY | O_CREAT, 0400);
1865  err += test_open(0, O_WRONLY | O_CREAT, 0200);
1866  err += test_open(0, O_WRONLY | O_CREAT, 0000);
1867  err += test_open(0, O_RDWR | O_CREAT, 0400);
1868  err += test_open(0, O_RDWR | O_CREAT, 0200);
1869  err += test_open(0, O_RDWR | O_CREAT, 0000);
1870  err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0600);
1871  err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0600);
1872  err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0000);
1873  err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0000);
1874  err += test_open_acc(O_RDONLY, 0600, 0);
1875  err += test_open_acc(O_WRONLY, 0600, 0);
1876  err += test_open_acc(O_RDWR, 0600, 0);
1877  err += test_open_acc(O_RDONLY, 0400, 0);
1878  err += test_open_acc(O_WRONLY, 0200, 0);
1879  if(!is_root) {
1880  err += test_open_acc(O_RDONLY | O_TRUNC, 0400, EACCES);
1881  err += test_open_acc(O_WRONLY, 0400, EACCES);
1882  err += test_open_acc(O_RDWR, 0400, EACCES);
1883  err += test_open_acc(O_RDONLY, 0200, EACCES);
1884  err += test_open_acc(O_RDWR, 0200, EACCES);
1885  err += test_open_acc(O_RDONLY, 0000, EACCES);
1886  err += test_open_acc(O_WRONLY, 0000, EACCES);
1887  err += test_open_acc(O_RDWR, 0000, EACCES);
1888  }
1889  err += test_create_ro_dir(O_CREAT);
1890  err += test_create_ro_dir(O_CREAT | O_EXCL);
1891  err += test_create_ro_dir(O_CREAT | O_WRONLY);
1892  err += test_create_ro_dir(O_CREAT | O_TRUNC);
1893  err += test_copy_file_range();
1894 
1895  unlink(testfile);
1896  unlink(testfile2);
1897  rmdir(testdir);
1898  rmdir(testdir2);
1899 
1900  if (err) {
1901  fprintf(stderr, "%i tests failed\n", -err);
1902  return 1;
1903  }
1904 
1905  return 0;
1906 }