"Fossies" - the Fresh Open Source Software Archive

Member "fuse-3.10.4/doc/html/test_2test__syscalls_8c_source.html" (9 Jun 2021, 267234 Bytes) of package /linux/misc/fuse-3.10.4.tar.xz:


Caution: In this restricted "Fossies" environment the current HTML page may not be correctly presentated and may have some non-functional links. You can here alternatively try to browse the pure source code or just view or download the uninterpreted raw source code. If the rendering is insufficient you may try to find and view the page on the project site itself.

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