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