libfuse: fuse-3.2.5/test/test_syscalls.c Source File

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 }