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