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