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