libfuse: test/test_syscalls.c Source File

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 }