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