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