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 24static const char *basepath; 25static const char *basepath_r; 26static char testfile[1024]; 27static char testfile2[1024]; 28static char testdir[1024]; 29static char testdir2[1024]; 30static char testsock[1024]; 31static char subfile[1280]; 32 33static char testfile_r[1024]; 34static char testfile2_r[1024]; 35static char testdir_r[1024]; 36static char testdir2_r[1024]; 37static char subfile_r[1280]; 38 39static char testname[256]; 40static char testdata[] = "abcdefghijklmnopqrstuvwxyz"; 41static char testdata2[] = "1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./"; 42static const char *testdir_files[] = { "f1", "f2", NULL}; 43static long seekdir_offsets[4]; 44static char zerodata[4096]; 45static int testdatalen = sizeof(testdata) - 1; 46static int testdata2len = sizeof(testdata2) - 1; 47static unsigned int testnum = 0; 48static unsigned int select_test = 0; 49static unsigned int skip_test = 0; 50static unsigned int unlinked_test = 0; 51 52#define MAX_ENTRIES 1024 53#define MAX_TESTS 100 54 55static struct test { 56 int fd; 57 struct stat stat; 58} tests[MAX_TESTS]; 59 60static 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 66static void test_error(const char *func, const char *msg, ...) 67 __attribute__ ((format (printf, 2, 3))); 68 69static void __start_test(const char *fmt, ...) 70 __attribute__ ((format (printf, 1, 2))); 71 72static 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 82static int is_dot_or_dotdot(const char *name) { 83 return name[0] == '.' && 84 (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')); 85} 86 87static 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 95static 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 128static 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 138static 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 149static 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 155static 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 164static 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 175static 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 185static 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 196static 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 203static 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 227static 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 251static 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 261static 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 272static 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 297static 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 312static 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 321static 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 364static 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 393static 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 463static 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 514static 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 531static 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 557static 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 566static 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 598static 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 619static 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 655static 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 703static 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 771static 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; 822fail: 823 closedir(dp); 824 cleanup_dir(testdir, testdir_files, 1); 825 return -1; 826} 827 828#ifdef HAVE_COPY_FILE_RANGE 829static 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 918static int test_copy_file_range(void) 919{ 920 return 0; 921} 922#endif 923 924static 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 960static 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 1013static 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__ 1069static 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 1105static 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 1256succ: 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 1264static 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 1319static 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 1383static 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 1433static 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 1492static 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 1535static 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 1580static 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 1776fail: 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__ 1796static 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 1829static 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 1865static 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 1920static 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 1960int 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