1 /* 2 * Automated Testing Framework (atf) 3 * 4 * Copyright (c) 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/types.h> 31 #include <sys/stat.h> 32 33 #include <errno.h> 34 #include <fcntl.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <unistd.h> 39 40 #include <atf-c.h> 41 42 #include "fs.h" 43 #include "test_helpers.h" 44 #include "user.h" 45 46 /* --------------------------------------------------------------------- 47 * Auxiliary functions. 48 * --------------------------------------------------------------------- */ 49 50 static 51 void 52 create_dir(const char *p, int mode) 53 { 54 int ret; 55 56 ret = mkdir(p, mode); 57 if (ret == -1) 58 atf_tc_fail("Could not create helper directory %s", p); 59 } 60 61 static 62 void 63 create_file(const char *p, int mode) 64 { 65 int fd; 66 67 fd = open(p, O_CREAT | O_WRONLY | O_TRUNC, mode); 68 if (fd == -1) 69 atf_tc_fail("Could not create helper file %s", p); 70 close(fd); 71 } 72 73 static 74 bool 75 exists(const atf_fs_path_t *p) 76 { 77 return access(atf_fs_path_cstring(p), F_OK) == 0; 78 } 79 80 static 81 atf_error_t 82 mkstemp_discard_fd(atf_fs_path_t *p) 83 { 84 int fd; 85 atf_error_t err = atf_fs_mkstemp(p, &fd); 86 if (!atf_is_error(err)) 87 close(fd); 88 return err; 89 } 90 91 /* --------------------------------------------------------------------- 92 * Test cases for the "atf_fs_path" type. 93 * --------------------------------------------------------------------- */ 94 95 ATF_TC(path_normalize); 96 ATF_TC_HEAD(path_normalize, tc) 97 { 98 atf_tc_set_md_var(tc, "descr", "Tests the path's normalization"); 99 } 100 ATF_TC_BODY(path_normalize, tc) 101 { 102 struct test { 103 const char *in; 104 const char *out; 105 } tests[] = { 106 { ".", ".", }, 107 { "..", "..", }, 108 109 { "/", "/", }, 110 { "//", "/", }, /* NO_CHECK_STYLE */ 111 { "///", "/", }, /* NO_CHECK_STYLE */ 112 113 { "foo", "foo", }, 114 { "foo/", "foo", }, 115 { "foo/bar", "foo/bar", }, 116 { "foo/bar/", "foo/bar", }, 117 118 { "/foo", "/foo", }, 119 { "/foo/bar", "/foo/bar", }, 120 { "/foo/bar/", "/foo/bar", }, 121 122 { "///foo", "/foo", }, /* NO_CHECK_STYLE */ 123 { "///foo///bar", "/foo/bar", }, /* NO_CHECK_STYLE */ 124 { "///foo///bar///", "/foo/bar", }, /* NO_CHECK_STYLE */ 125 126 { NULL, NULL } 127 }; 128 struct test *t; 129 130 for (t = &tests[0]; t->in != NULL; t++) { 131 atf_fs_path_t p; 132 133 printf("Input : >%s<\n", t->in); 134 printf("Expected output: >%s<\n", t->out); 135 136 RE(atf_fs_path_init_fmt(&p, "%s", t->in)); 137 printf("Output : >%s<\n", atf_fs_path_cstring(&p)); 138 ATF_REQUIRE(strcmp(atf_fs_path_cstring(&p), t->out) == 0); 139 atf_fs_path_fini(&p); 140 141 printf("\n"); 142 } 143 } 144 145 ATF_TC(path_copy); 146 ATF_TC_HEAD(path_copy, tc) 147 { 148 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_copy constructor"); 149 } 150 ATF_TC_BODY(path_copy, tc) 151 { 152 atf_fs_path_t str, str2; 153 154 RE(atf_fs_path_init_fmt(&str, "foo")); 155 RE(atf_fs_path_copy(&str2, &str)); 156 157 ATF_REQUIRE(atf_equal_fs_path_fs_path(&str, &str2)); 158 159 RE(atf_fs_path_append_fmt(&str2, "bar")); 160 161 ATF_REQUIRE(!atf_equal_fs_path_fs_path(&str, &str2)); 162 163 atf_fs_path_fini(&str2); 164 atf_fs_path_fini(&str); 165 } 166 167 ATF_TC(path_is_absolute); 168 ATF_TC_HEAD(path_is_absolute, tc) 169 { 170 atf_tc_set_md_var(tc, "descr", "Tests the path::is_absolute function"); 171 } 172 ATF_TC_BODY(path_is_absolute, tc) 173 { 174 struct test { 175 const char *in; 176 bool abs; 177 } tests[] = { 178 { "/", true }, 179 { "////", true }, /* NO_CHECK_STYLE */ 180 { "////a", true }, /* NO_CHECK_STYLE */ 181 { "//a//", true }, /* NO_CHECK_STYLE */ 182 { "a////", false }, /* NO_CHECK_STYLE */ 183 { "../foo", false }, 184 { NULL, false }, 185 }; 186 struct test *t; 187 188 for (t = &tests[0]; t->in != NULL; t++) { 189 atf_fs_path_t p; 190 191 printf("Input : %s\n", t->in); 192 printf("Expected result: %s\n", t->abs ? "true" : "false"); 193 194 RE(atf_fs_path_init_fmt(&p, "%s", t->in)); 195 printf("Result : %s\n", 196 atf_fs_path_is_absolute(&p) ? "true" : "false"); 197 if (t->abs) 198 ATF_REQUIRE(atf_fs_path_is_absolute(&p)); 199 else 200 ATF_REQUIRE(!atf_fs_path_is_absolute(&p)); 201 atf_fs_path_fini(&p); 202 203 printf("\n"); 204 } 205 } 206 207 ATF_TC(path_is_root); 208 ATF_TC_HEAD(path_is_root, tc) 209 { 210 atf_tc_set_md_var(tc, "descr", "Tests the path::is_root function"); 211 } 212 ATF_TC_BODY(path_is_root, tc) 213 { 214 struct test { 215 const char *in; 216 bool root; 217 } tests[] = { 218 { "/", true }, 219 { "////", true }, /* NO_CHECK_STYLE */ 220 { "////a", false }, /* NO_CHECK_STYLE */ 221 { "//a//", false }, /* NO_CHECK_STYLE */ 222 { "a////", false }, /* NO_CHECK_STYLE */ 223 { "../foo", false }, 224 { NULL, false }, 225 }; 226 struct test *t; 227 228 for (t = &tests[0]; t->in != NULL; t++) { 229 atf_fs_path_t p; 230 231 printf("Input : %s\n", t->in); 232 printf("Expected result: %s\n", t->root ? "true" : "false"); 233 234 RE(atf_fs_path_init_fmt(&p, "%s", t->in)); 235 printf("Result : %s\n", 236 atf_fs_path_is_root(&p) ? "true" : "false"); 237 if (t->root) 238 ATF_REQUIRE(atf_fs_path_is_root(&p)); 239 else 240 ATF_REQUIRE(!atf_fs_path_is_root(&p)); 241 atf_fs_path_fini(&p); 242 243 printf("\n"); 244 } 245 } 246 247 ATF_TC(path_branch_path); 248 ATF_TC_HEAD(path_branch_path, tc) 249 { 250 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_branch_path " 251 "function"); 252 } 253 ATF_TC_BODY(path_branch_path, tc) 254 { 255 struct test { 256 const char *in; 257 const char *branch; 258 } tests[] = { 259 { ".", "." }, 260 { "foo", "." }, 261 { "foo/bar", "foo" }, 262 { "/foo", "/" }, 263 { "/foo/bar", "/foo" }, 264 { NULL, NULL }, 265 }; 266 struct test *t; 267 268 for (t = &tests[0]; t->in != NULL; t++) { 269 atf_fs_path_t p, bp; 270 271 printf("Input : %s\n", t->in); 272 printf("Expected output: %s\n", t->branch); 273 274 RE(atf_fs_path_init_fmt(&p, "%s", t->in)); 275 RE(atf_fs_path_branch_path(&p, &bp)); 276 printf("Output : %s\n", atf_fs_path_cstring(&bp)); 277 ATF_REQUIRE(strcmp(atf_fs_path_cstring(&bp), t->branch) == 0); 278 atf_fs_path_fini(&bp); 279 atf_fs_path_fini(&p); 280 281 printf("\n"); 282 } 283 } 284 285 ATF_TC(path_leaf_name); 286 ATF_TC_HEAD(path_leaf_name, tc) 287 { 288 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_leaf_name " 289 "function"); 290 } 291 ATF_TC_BODY(path_leaf_name, tc) 292 { 293 struct test { 294 const char *in; 295 const char *leaf; 296 } tests[] = { 297 { ".", "." }, 298 { "foo", "foo" }, 299 { "foo/bar", "bar" }, 300 { "/foo", "foo" }, 301 { "/foo/bar", "bar" }, 302 { NULL, NULL }, 303 }; 304 struct test *t; 305 306 for (t = &tests[0]; t->in != NULL; t++) { 307 atf_fs_path_t p; 308 atf_dynstr_t ln; 309 310 printf("Input : %s\n", t->in); 311 printf("Expected output: %s\n", t->leaf); 312 313 RE(atf_fs_path_init_fmt(&p, "%s", t->in)); 314 RE(atf_fs_path_leaf_name(&p, &ln)); 315 printf("Output : %s\n", atf_dynstr_cstring(&ln)); 316 ATF_REQUIRE(atf_equal_dynstr_cstring(&ln, t->leaf)); 317 atf_dynstr_fini(&ln); 318 atf_fs_path_fini(&p); 319 320 printf("\n"); 321 } 322 } 323 324 ATF_TC(path_append); 325 ATF_TC_HEAD(path_append, tc) 326 { 327 atf_tc_set_md_var(tc, "descr", "Tests the concatenation of multiple " 328 "paths"); 329 } 330 ATF_TC_BODY(path_append, tc) 331 { 332 struct test { 333 const char *in; 334 const char *ap; 335 const char *out; 336 } tests[] = { 337 { "foo", "bar", "foo/bar" }, 338 { "foo/", "/bar", "foo/bar" }, 339 { "foo/", "/bar/baz", "foo/bar/baz" }, 340 { "foo/", "///bar///baz", "foo/bar/baz" }, /* NO_CHECK_STYLE */ 341 342 { NULL, NULL, NULL } 343 }; 344 struct test *t; 345 346 for (t = &tests[0]; t->in != NULL; t++) { 347 atf_fs_path_t p; 348 349 printf("Input : >%s<\n", t->in); 350 printf("Append : >%s<\n", t->ap); 351 printf("Expected output: >%s<\n", t->out); 352 353 RE(atf_fs_path_init_fmt(&p, "%s", t->in)); 354 355 RE(atf_fs_path_append_fmt(&p, "%s", t->ap)); 356 357 printf("Output : >%s<\n", atf_fs_path_cstring(&p)); 358 ATF_REQUIRE(strcmp(atf_fs_path_cstring(&p), t->out) == 0); 359 360 atf_fs_path_fini(&p); 361 362 printf("\n"); 363 } 364 } 365 366 ATF_TC(path_to_absolute); 367 ATF_TC_HEAD(path_to_absolute, tc) 368 { 369 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_to_absolute " 370 "function"); 371 } 372 ATF_TC_BODY(path_to_absolute, tc) 373 { 374 const char *names[] = { ".", "dir", NULL }; 375 const char **n; 376 377 ATF_REQUIRE(mkdir("dir", 0755) != -1); 378 379 for (n = names; *n != NULL; n++) { 380 atf_fs_path_t p, p2; 381 atf_fs_stat_t st1, st2; 382 383 RE(atf_fs_path_init_fmt(&p, "%s", *n)); 384 RE(atf_fs_stat_init(&st1, &p)); 385 printf("Relative path: %s\n", atf_fs_path_cstring(&p)); 386 387 RE(atf_fs_path_to_absolute(&p, &p2)); 388 printf("Absolute path: %s\n", atf_fs_path_cstring(&p2)); 389 390 ATF_REQUIRE(atf_fs_path_is_absolute(&p2)); 391 RE(atf_fs_stat_init(&st2, &p2)); 392 393 ATF_REQUIRE_EQ(atf_fs_stat_get_device(&st1), 394 atf_fs_stat_get_device(&st2)); 395 ATF_REQUIRE_EQ(atf_fs_stat_get_inode(&st1), 396 atf_fs_stat_get_inode(&st2)); 397 398 atf_fs_stat_fini(&st2); 399 atf_fs_stat_fini(&st1); 400 atf_fs_path_fini(&p2); 401 atf_fs_path_fini(&p); 402 403 printf("\n"); 404 } 405 } 406 407 ATF_TC(path_equal); 408 ATF_TC_HEAD(path_equal, tc) 409 { 410 atf_tc_set_md_var(tc, "descr", "Tests the equality operators for paths"); 411 } 412 ATF_TC_BODY(path_equal, tc) 413 { 414 atf_fs_path_t p1, p2; 415 416 RE(atf_fs_path_init_fmt(&p1, "foo")); 417 418 RE(atf_fs_path_init_fmt(&p2, "foo")); 419 ATF_REQUIRE(atf_equal_fs_path_fs_path(&p1, &p2)); 420 atf_fs_path_fini(&p2); 421 422 RE(atf_fs_path_init_fmt(&p2, "bar")); 423 ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2)); 424 atf_fs_path_fini(&p2); 425 426 atf_fs_path_fini(&p1); 427 } 428 429 /* --------------------------------------------------------------------- 430 * Test cases for the "atf_fs_stat" type. 431 * --------------------------------------------------------------------- */ 432 433 ATF_TC(stat_mode); 434 ATF_TC_HEAD(stat_mode, tc) 435 { 436 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_get_mode function " 437 "and, indirectly, the constructor"); 438 } 439 ATF_TC_BODY(stat_mode, tc) 440 { 441 atf_fs_path_t p; 442 atf_fs_stat_t st; 443 444 create_file("f1", 0400); 445 create_file("f2", 0644); 446 447 RE(atf_fs_path_init_fmt(&p, "f1")); 448 RE(atf_fs_stat_init(&st, &p)); 449 ATF_CHECK_EQ(0400, atf_fs_stat_get_mode(&st)); 450 atf_fs_stat_fini(&st); 451 atf_fs_path_fini(&p); 452 453 RE(atf_fs_path_init_fmt(&p, "f2")); 454 RE(atf_fs_stat_init(&st, &p)); 455 ATF_CHECK_EQ(0644, atf_fs_stat_get_mode(&st)); 456 atf_fs_stat_fini(&st); 457 atf_fs_path_fini(&p); 458 } 459 460 ATF_TC(stat_type); 461 ATF_TC_HEAD(stat_type, tc) 462 { 463 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_get_type function " 464 "and, indirectly, the constructor"); 465 } 466 ATF_TC_BODY(stat_type, tc) 467 { 468 atf_fs_path_t p; 469 atf_fs_stat_t st; 470 471 create_dir("dir", 0755); 472 create_file("reg", 0644); 473 474 RE(atf_fs_path_init_fmt(&p, "dir")); 475 RE(atf_fs_stat_init(&st, &p)); 476 ATF_REQUIRE_EQ(atf_fs_stat_get_type(&st), atf_fs_stat_dir_type); 477 atf_fs_stat_fini(&st); 478 atf_fs_path_fini(&p); 479 480 RE(atf_fs_path_init_fmt(&p, "reg")); 481 RE(atf_fs_stat_init(&st, &p)); 482 ATF_REQUIRE_EQ(atf_fs_stat_get_type(&st), atf_fs_stat_reg_type); 483 atf_fs_stat_fini(&st); 484 atf_fs_path_fini(&p); 485 } 486 487 ATF_TC(stat_perms); 488 ATF_TC_HEAD(stat_perms, tc) 489 { 490 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_is_* functions"); 491 } 492 ATF_TC_BODY(stat_perms, tc) 493 { 494 atf_fs_path_t p; 495 atf_fs_stat_t st; 496 497 create_file("reg", 0); 498 499 RE(atf_fs_path_init_fmt(&p, "reg")); 500 501 #define perms(ur, uw, ux, gr, gw, gx, othr, othw, othx) \ 502 { \ 503 RE(atf_fs_stat_init(&st, &p)); \ 504 ATF_REQUIRE(atf_fs_stat_is_owner_readable(&st) == ur); \ 505 ATF_REQUIRE(atf_fs_stat_is_owner_writable(&st) == uw); \ 506 ATF_REQUIRE(atf_fs_stat_is_owner_executable(&st) == ux); \ 507 ATF_REQUIRE(atf_fs_stat_is_group_readable(&st) == gr); \ 508 ATF_REQUIRE(atf_fs_stat_is_group_writable(&st) == gw); \ 509 ATF_REQUIRE(atf_fs_stat_is_group_executable(&st) == gx); \ 510 ATF_REQUIRE(atf_fs_stat_is_other_readable(&st) == othr); \ 511 ATF_REQUIRE(atf_fs_stat_is_other_writable(&st) == othw); \ 512 ATF_REQUIRE(atf_fs_stat_is_other_executable(&st) == othx); \ 513 atf_fs_stat_fini(&st); \ 514 } 515 516 chmod("reg", 0000); 517 perms(false, false, false, false, false, false, false, false, false); 518 519 chmod("reg", 0001); 520 perms(false, false, false, false, false, false, false, false, true); 521 522 chmod("reg", 0010); 523 perms(false, false, false, false, false, true, false, false, false); 524 525 chmod("reg", 0100); 526 perms(false, false, true, false, false, false, false, false, false); 527 528 chmod("reg", 0002); 529 perms(false, false, false, false, false, false, false, true, false); 530 531 chmod("reg", 0020); 532 perms(false, false, false, false, true, false, false, false, false); 533 534 chmod("reg", 0200); 535 perms(false, true, false, false, false, false, false, false, false); 536 537 chmod("reg", 0004); 538 perms(false, false, false, false, false, false, true, false, false); 539 540 chmod("reg", 0040); 541 perms(false, false, false, true, false, false, false, false, false); 542 543 chmod("reg", 0400); 544 perms(true, false, false, false, false, false, false, false, false); 545 546 chmod("reg", 0644); 547 perms(true, true, false, true, false, false, true, false, false); 548 549 chmod("reg", 0755); 550 perms(true, true, true, true, false, true, true, false, true); 551 552 chmod("reg", 0777); 553 perms(true, true, true, true, true, true, true, true, true); 554 555 #undef perms 556 557 atf_fs_path_fini(&p); 558 } 559 560 /* --------------------------------------------------------------------- 561 * Test cases for the free functions. 562 * --------------------------------------------------------------------- */ 563 564 ATF_TC(exists); 565 ATF_TC_HEAD(exists, tc) 566 { 567 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_exists function"); 568 } 569 ATF_TC_BODY(exists, tc) 570 { 571 atf_error_t err; 572 atf_fs_path_t pdir, pfile; 573 bool b; 574 575 RE(atf_fs_path_init_fmt(&pdir, "dir")); 576 RE(atf_fs_path_init_fmt(&pfile, "dir/file")); 577 578 create_dir(atf_fs_path_cstring(&pdir), 0755); 579 create_file(atf_fs_path_cstring(&pfile), 0644); 580 581 printf("Checking existence of a directory\n"); 582 RE(atf_fs_exists(&pdir, &b)); 583 ATF_REQUIRE(b); 584 585 printf("Checking existence of a file\n"); 586 RE(atf_fs_exists(&pfile, &b)); 587 ATF_REQUIRE(b); 588 589 /* XXX: This should probably be a separate test case to let the user 590 * be aware that some tests were skipped because privileges were not 591 * correct. */ 592 if (!atf_user_is_root()) { 593 printf("Checking existence of a file inside a directory without " 594 "permissions\n"); 595 ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0000) != -1); 596 err = atf_fs_exists(&pfile, &b); 597 ATF_REQUIRE(atf_is_error(err)); 598 ATF_REQUIRE(atf_error_is(err, "libc")); 599 ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0755) != -1); 600 atf_error_free(err); 601 } 602 603 printf("Checking existence of a non-existent file\n"); 604 ATF_REQUIRE(unlink(atf_fs_path_cstring(&pfile)) != -1); 605 RE(atf_fs_exists(&pfile, &b)); 606 ATF_REQUIRE(!b); 607 608 atf_fs_path_fini(&pfile); 609 atf_fs_path_fini(&pdir); 610 } 611 612 ATF_TC(eaccess); 613 ATF_TC_HEAD(eaccess, tc) 614 { 615 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_eaccess function"); 616 } 617 ATF_TC_BODY(eaccess, tc) 618 { 619 const int modes[] = { atf_fs_access_f, atf_fs_access_r, atf_fs_access_w, 620 atf_fs_access_x, 0 }; 621 const int *m; 622 struct tests { 623 mode_t fmode; 624 int amode; 625 int uerror; 626 int rerror; 627 } tests[] = { 628 { 0000, atf_fs_access_r, EACCES, 0 }, 629 { 0000, atf_fs_access_w, EACCES, 0 }, 630 { 0000, atf_fs_access_x, EACCES, EACCES }, 631 632 { 0001, atf_fs_access_r, EACCES, 0 }, 633 { 0001, atf_fs_access_w, EACCES, 0 }, 634 { 0001, atf_fs_access_x, EACCES, 0 }, 635 { 0002, atf_fs_access_r, EACCES, 0 }, 636 { 0002, atf_fs_access_w, EACCES, 0 }, 637 { 0002, atf_fs_access_x, EACCES, EACCES }, 638 { 0004, atf_fs_access_r, EACCES, 0 }, 639 { 0004, atf_fs_access_w, EACCES, 0 }, 640 { 0004, atf_fs_access_x, EACCES, EACCES }, 641 642 { 0010, atf_fs_access_r, EACCES, 0 }, 643 { 0010, atf_fs_access_w, EACCES, 0 }, 644 { 0010, atf_fs_access_x, 0, 0 }, 645 { 0020, atf_fs_access_r, EACCES, 0 }, 646 { 0020, atf_fs_access_w, 0, 0 }, 647 { 0020, atf_fs_access_x, EACCES, EACCES }, 648 { 0040, atf_fs_access_r, 0, 0 }, 649 { 0040, atf_fs_access_w, EACCES, 0 }, 650 { 0040, atf_fs_access_x, EACCES, EACCES }, 651 652 { 0100, atf_fs_access_r, EACCES, 0 }, 653 { 0100, atf_fs_access_w, EACCES, 0 }, 654 { 0100, atf_fs_access_x, 0, 0 }, 655 { 0200, atf_fs_access_r, EACCES, 0 }, 656 { 0200, atf_fs_access_w, 0, 0 }, 657 { 0200, atf_fs_access_x, EACCES, EACCES }, 658 { 0400, atf_fs_access_r, 0, 0 }, 659 { 0400, atf_fs_access_w, EACCES, 0 }, 660 { 0400, atf_fs_access_x, EACCES, EACCES }, 661 662 { 0, 0, 0, 0 } 663 }; 664 struct tests *t; 665 atf_fs_path_t p; 666 atf_error_t err; 667 668 RE(atf_fs_path_init_fmt(&p, "the-file")); 669 670 printf("Non-existent file checks\n"); 671 for (m = &modes[0]; *m != 0; m++) { 672 err = atf_fs_eaccess(&p, *m); 673 ATF_REQUIRE(atf_is_error(err)); 674 ATF_REQUIRE(atf_error_is(err, "libc")); 675 ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOENT); 676 atf_error_free(err); 677 } 678 679 create_file(atf_fs_path_cstring(&p), 0000); 680 ATF_REQUIRE(chown(atf_fs_path_cstring(&p), geteuid(), getegid()) != -1); 681 682 for (t = &tests[0]; t->amode != 0; t++) { 683 const int experr = atf_user_is_root() ? t->rerror : t->uerror; 684 685 printf("\n"); 686 printf("File mode : %04o\n", (unsigned int)t->fmode); 687 printf("Access mode : 0x%02x\n", t->amode); 688 689 ATF_REQUIRE(chmod(atf_fs_path_cstring(&p), t->fmode) != -1); 690 691 /* First, existence check. */ 692 err = atf_fs_eaccess(&p, atf_fs_access_f); 693 ATF_REQUIRE(!atf_is_error(err)); 694 695 /* Now do the specific test case. */ 696 printf("Expected error: %d\n", experr); 697 err = atf_fs_eaccess(&p, t->amode); 698 if (atf_is_error(err)) { 699 if (atf_error_is(err, "libc")) 700 printf("Error : %d\n", atf_libc_error_code(err)); 701 else 702 printf("Error : Non-libc error\n"); 703 } else 704 printf("Error : None\n"); 705 if (experr == 0) { 706 ATF_REQUIRE(!atf_is_error(err)); 707 } else { 708 ATF_REQUIRE(atf_is_error(err)); 709 ATF_REQUIRE(atf_error_is(err, "libc")); 710 ATF_REQUIRE_EQ(atf_libc_error_code(err), experr); 711 atf_error_free(err); 712 } 713 } 714 715 atf_fs_path_fini(&p); 716 } 717 718 ATF_TC(getcwd); 719 ATF_TC_HEAD(getcwd, tc) 720 { 721 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_getcwd function"); 722 } 723 ATF_TC_BODY(getcwd, tc) 724 { 725 atf_fs_path_t cwd1, cwd2; 726 727 create_dir ("root", 0755); 728 729 RE(atf_fs_getcwd(&cwd1)); 730 ATF_REQUIRE(chdir("root") != -1); 731 RE(atf_fs_getcwd(&cwd2)); 732 733 RE(atf_fs_path_append_fmt(&cwd1, "root")); 734 735 ATF_REQUIRE(atf_equal_fs_path_fs_path(&cwd1, &cwd2)); 736 737 atf_fs_path_fini(&cwd2); 738 atf_fs_path_fini(&cwd1); 739 } 740 741 ATF_TC(rmdir_empty); 742 ATF_TC_HEAD(rmdir_empty, tc) 743 { 744 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function"); 745 } 746 ATF_TC_BODY(rmdir_empty, tc) 747 { 748 atf_fs_path_t p; 749 750 RE(atf_fs_path_init_fmt(&p, "test-dir")); 751 752 ATF_REQUIRE(mkdir("test-dir", 0755) != -1); 753 ATF_REQUIRE(exists(&p)); 754 RE(atf_fs_rmdir(&p)); 755 ATF_REQUIRE(!exists(&p)); 756 757 atf_fs_path_fini(&p); 758 } 759 760 ATF_TC(rmdir_enotempty); 761 ATF_TC_HEAD(rmdir_enotempty, tc) 762 { 763 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function"); 764 } 765 ATF_TC_BODY(rmdir_enotempty, tc) 766 { 767 atf_fs_path_t p; 768 atf_error_t err; 769 770 RE(atf_fs_path_init_fmt(&p, "test-dir")); 771 772 ATF_REQUIRE(mkdir("test-dir", 0755) != -1); 773 ATF_REQUIRE(exists(&p)); 774 create_file("test-dir/foo", 0644); 775 776 err = atf_fs_rmdir(&p); 777 ATF_REQUIRE(atf_is_error(err)); 778 ATF_REQUIRE(atf_error_is(err, "libc")); 779 ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOTEMPTY); 780 atf_error_free(err); 781 782 atf_fs_path_fini(&p); 783 } 784 785 ATF_TC(rmdir_eperm); 786 ATF_TC_HEAD(rmdir_eperm, tc) 787 { 788 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function"); 789 } 790 ATF_TC_BODY(rmdir_eperm, tc) 791 { 792 atf_fs_path_t p; 793 atf_error_t err; 794 795 RE(atf_fs_path_init_fmt(&p, "test-dir/foo")); 796 797 ATF_REQUIRE(mkdir("test-dir", 0755) != -1); 798 ATF_REQUIRE(mkdir("test-dir/foo", 0755) != -1); 799 ATF_REQUIRE(chmod("test-dir", 0555) != -1); 800 ATF_REQUIRE(exists(&p)); 801 802 err = atf_fs_rmdir(&p); 803 if (atf_user_is_root()) { 804 ATF_REQUIRE(!atf_is_error(err)); 805 } else { 806 ATF_REQUIRE(atf_is_error(err)); 807 ATF_REQUIRE(atf_error_is(err, "libc")); 808 ATF_REQUIRE_EQ(atf_libc_error_code(err), EACCES); 809 atf_error_free(err); 810 } 811 812 atf_fs_path_fini(&p); 813 } 814 815 ATF_TC(mkdtemp_ok); 816 ATF_TC_HEAD(mkdtemp_ok, tc) 817 { 818 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function, " 819 "successful execution"); 820 } 821 ATF_TC_BODY(mkdtemp_ok, tc) 822 { 823 atf_fs_path_t p1, p2; 824 atf_fs_stat_t s1, s2; 825 826 RE(atf_fs_path_init_fmt(&p1, "testdir.XXXXXX")); 827 RE(atf_fs_path_init_fmt(&p2, "testdir.XXXXXX")); 828 RE(atf_fs_mkdtemp(&p1)); 829 RE(atf_fs_mkdtemp(&p2)); 830 ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2)); 831 ATF_REQUIRE(exists(&p1)); 832 ATF_REQUIRE(exists(&p2)); 833 834 RE(atf_fs_stat_init(&s1, &p1)); 835 ATF_REQUIRE_EQ(atf_fs_stat_get_type(&s1), atf_fs_stat_dir_type); 836 ATF_REQUIRE( atf_fs_stat_is_owner_readable(&s1)); 837 ATF_REQUIRE( atf_fs_stat_is_owner_writable(&s1)); 838 ATF_REQUIRE( atf_fs_stat_is_owner_executable(&s1)); 839 ATF_REQUIRE(!atf_fs_stat_is_group_readable(&s1)); 840 ATF_REQUIRE(!atf_fs_stat_is_group_writable(&s1)); 841 ATF_REQUIRE(!atf_fs_stat_is_group_executable(&s1)); 842 ATF_REQUIRE(!atf_fs_stat_is_other_readable(&s1)); 843 ATF_REQUIRE(!atf_fs_stat_is_other_writable(&s1)); 844 ATF_REQUIRE(!atf_fs_stat_is_other_executable(&s1)); 845 846 RE(atf_fs_stat_init(&s2, &p2)); 847 ATF_REQUIRE_EQ(atf_fs_stat_get_type(&s2), atf_fs_stat_dir_type); 848 ATF_REQUIRE( atf_fs_stat_is_owner_readable(&s2)); 849 ATF_REQUIRE( atf_fs_stat_is_owner_writable(&s2)); 850 ATF_REQUIRE( atf_fs_stat_is_owner_executable(&s2)); 851 ATF_REQUIRE(!atf_fs_stat_is_group_readable(&s2)); 852 ATF_REQUIRE(!atf_fs_stat_is_group_writable(&s2)); 853 ATF_REQUIRE(!atf_fs_stat_is_group_executable(&s2)); 854 ATF_REQUIRE(!atf_fs_stat_is_other_readable(&s2)); 855 ATF_REQUIRE(!atf_fs_stat_is_other_writable(&s2)); 856 ATF_REQUIRE(!atf_fs_stat_is_other_executable(&s2)); 857 858 atf_fs_stat_fini(&s2); 859 atf_fs_stat_fini(&s1); 860 atf_fs_path_fini(&p2); 861 atf_fs_path_fini(&p1); 862 } 863 864 ATF_TC(mkdtemp_err); 865 ATF_TC_HEAD(mkdtemp_err, tc) 866 { 867 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function, " 868 "error conditions"); 869 atf_tc_set_md_var(tc, "require.user", "unprivileged"); 870 } 871 ATF_TC_BODY(mkdtemp_err, tc) 872 { 873 atf_error_t err; 874 atf_fs_path_t p; 875 876 ATF_REQUIRE(mkdir("dir", 0555) != -1); 877 878 RE(atf_fs_path_init_fmt(&p, "dir/testdir.XXXXXX")); 879 880 err = atf_fs_mkdtemp(&p); 881 ATF_REQUIRE(atf_is_error(err)); 882 ATF_REQUIRE(atf_error_is(err, "libc")); 883 ATF_CHECK_EQ(atf_libc_error_code(err), EACCES); 884 atf_error_free(err); 885 886 ATF_CHECK(!exists(&p)); 887 ATF_CHECK(strcmp(atf_fs_path_cstring(&p), "dir/testdir.XXXXXX") == 0); 888 889 atf_fs_path_fini(&p); 890 } 891 892 static 893 void 894 do_umask_check(atf_error_t (*const mk_func)(atf_fs_path_t *), 895 atf_fs_path_t *path, const mode_t test_mask, 896 const char *str_mask, const char *exp_name) 897 { 898 char buf[1024]; 899 int old_umask; 900 atf_error_t err; 901 902 printf("Creating temporary %s with umask %s\n", exp_name, str_mask); 903 904 old_umask = umask(test_mask); 905 err = mk_func(path); 906 (void)umask(old_umask); 907 908 ATF_REQUIRE(atf_is_error(err)); 909 ATF_REQUIRE(atf_error_is(err, "invalid_umask")); 910 atf_error_format(err, buf, sizeof(buf)); 911 ATF_CHECK(strstr(buf, exp_name) != NULL); 912 ATF_CHECK(strstr(buf, str_mask) != NULL); 913 atf_error_free(err); 914 } 915 916 ATF_TC(mkdtemp_umask); 917 ATF_TC_HEAD(mkdtemp_umask, tc) 918 { 919 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function " 920 "causing an error due to a too strict umask"); 921 } 922 ATF_TC_BODY(mkdtemp_umask, tc) 923 { 924 atf_fs_path_t p; 925 926 RE(atf_fs_path_init_fmt(&p, "testdir.XXXXXX")); 927 928 do_umask_check(atf_fs_mkdtemp, &p, 00100, "00100", "directory"); 929 do_umask_check(atf_fs_mkdtemp, &p, 00200, "00200", "directory"); 930 do_umask_check(atf_fs_mkdtemp, &p, 00400, "00400", "directory"); 931 do_umask_check(atf_fs_mkdtemp, &p, 00500, "00500", "directory"); 932 do_umask_check(atf_fs_mkdtemp, &p, 00600, "00600", "directory"); 933 934 atf_fs_path_fini(&p); 935 } 936 937 ATF_TC(mkstemp_ok); 938 ATF_TC_HEAD(mkstemp_ok, tc) 939 { 940 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function, " 941 "successful execution"); 942 } 943 ATF_TC_BODY(mkstemp_ok, tc) 944 { 945 int fd1, fd2; 946 atf_fs_path_t p1, p2; 947 atf_fs_stat_t s1, s2; 948 949 RE(atf_fs_path_init_fmt(&p1, "testfile.XXXXXX")); 950 RE(atf_fs_path_init_fmt(&p2, "testfile.XXXXXX")); 951 fd1 = fd2 = -1; 952 RE(atf_fs_mkstemp(&p1, &fd1)); 953 RE(atf_fs_mkstemp(&p2, &fd2)); 954 ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2)); 955 ATF_REQUIRE(exists(&p1)); 956 ATF_REQUIRE(exists(&p2)); 957 958 ATF_CHECK(fd1 != -1); 959 ATF_CHECK(fd2 != -1); 960 ATF_CHECK(write(fd1, "foo", 3) == 3); 961 ATF_CHECK(write(fd2, "bar", 3) == 3); 962 close(fd1); 963 close(fd2); 964 965 RE(atf_fs_stat_init(&s1, &p1)); 966 ATF_CHECK_EQ(atf_fs_stat_get_type(&s1), atf_fs_stat_reg_type); 967 ATF_CHECK( atf_fs_stat_is_owner_readable(&s1)); 968 ATF_CHECK( atf_fs_stat_is_owner_writable(&s1)); 969 ATF_CHECK(!atf_fs_stat_is_owner_executable(&s1)); 970 ATF_CHECK(!atf_fs_stat_is_group_readable(&s1)); 971 ATF_CHECK(!atf_fs_stat_is_group_writable(&s1)); 972 ATF_CHECK(!atf_fs_stat_is_group_executable(&s1)); 973 ATF_CHECK(!atf_fs_stat_is_other_readable(&s1)); 974 ATF_CHECK(!atf_fs_stat_is_other_writable(&s1)); 975 ATF_CHECK(!atf_fs_stat_is_other_executable(&s1)); 976 977 RE(atf_fs_stat_init(&s2, &p2)); 978 ATF_CHECK_EQ(atf_fs_stat_get_type(&s2), atf_fs_stat_reg_type); 979 ATF_CHECK( atf_fs_stat_is_owner_readable(&s2)); 980 ATF_CHECK( atf_fs_stat_is_owner_writable(&s2)); 981 ATF_CHECK(!atf_fs_stat_is_owner_executable(&s2)); 982 ATF_CHECK(!atf_fs_stat_is_group_readable(&s2)); 983 ATF_CHECK(!atf_fs_stat_is_group_writable(&s2)); 984 ATF_CHECK(!atf_fs_stat_is_group_executable(&s2)); 985 ATF_CHECK(!atf_fs_stat_is_other_readable(&s2)); 986 ATF_CHECK(!atf_fs_stat_is_other_writable(&s2)); 987 ATF_CHECK(!atf_fs_stat_is_other_executable(&s2)); 988 989 atf_fs_stat_fini(&s2); 990 atf_fs_stat_fini(&s1); 991 atf_fs_path_fini(&p2); 992 atf_fs_path_fini(&p1); 993 } 994 995 ATF_TC(mkstemp_err); 996 ATF_TC_HEAD(mkstemp_err, tc) 997 { 998 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function, " 999 "error conditions"); 1000 atf_tc_set_md_var(tc, "require.user", "unprivileged"); 1001 } 1002 ATF_TC_BODY(mkstemp_err, tc) 1003 { 1004 int fd; 1005 atf_error_t err; 1006 atf_fs_path_t p; 1007 1008 ATF_REQUIRE(mkdir("dir", 0555) != -1); 1009 1010 RE(atf_fs_path_init_fmt(&p, "dir/testfile.XXXXXX")); 1011 fd = 1234; 1012 1013 err = atf_fs_mkstemp(&p, &fd); 1014 ATF_REQUIRE(atf_is_error(err)); 1015 ATF_REQUIRE(atf_error_is(err, "libc")); 1016 ATF_CHECK_EQ(atf_libc_error_code(err), EACCES); 1017 atf_error_free(err); 1018 1019 ATF_CHECK(!exists(&p)); 1020 ATF_CHECK(strcmp(atf_fs_path_cstring(&p), "dir/testfile.XXXXXX") == 0); 1021 ATF_CHECK_EQ(fd, 1234); 1022 1023 atf_fs_path_fini(&p); 1024 } 1025 1026 ATF_TC(mkstemp_umask); 1027 ATF_TC_HEAD(mkstemp_umask, tc) 1028 { 1029 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function " 1030 "causing an error due to a too strict umask"); 1031 } 1032 ATF_TC_BODY(mkstemp_umask, tc) 1033 { 1034 atf_fs_path_t p; 1035 1036 RE(atf_fs_path_init_fmt(&p, "testfile.XXXXXX")); 1037 1038 do_umask_check(mkstemp_discard_fd, &p, 00100, "00100", "regular file"); 1039 do_umask_check(mkstemp_discard_fd, &p, 00200, "00200", "regular file"); 1040 do_umask_check(mkstemp_discard_fd, &p, 00400, "00400", "regular file"); 1041 1042 atf_fs_path_fini(&p); 1043 } 1044 1045 /* --------------------------------------------------------------------- 1046 * Main. 1047 * --------------------------------------------------------------------- */ 1048 1049 ATF_TP_ADD_TCS(tp) 1050 { 1051 /* Add the tests for the "atf_fs_path" type. */ 1052 ATF_TP_ADD_TC(tp, path_normalize); 1053 ATF_TP_ADD_TC(tp, path_copy); 1054 ATF_TP_ADD_TC(tp, path_is_absolute); 1055 ATF_TP_ADD_TC(tp, path_is_root); 1056 ATF_TP_ADD_TC(tp, path_branch_path); 1057 ATF_TP_ADD_TC(tp, path_leaf_name); 1058 ATF_TP_ADD_TC(tp, path_append); 1059 ATF_TP_ADD_TC(tp, path_to_absolute); 1060 ATF_TP_ADD_TC(tp, path_equal); 1061 1062 /* Add the tests for the "atf_fs_stat" type. */ 1063 ATF_TP_ADD_TC(tp, stat_mode); 1064 ATF_TP_ADD_TC(tp, stat_type); 1065 ATF_TP_ADD_TC(tp, stat_perms); 1066 1067 /* Add the tests for the free functions. */ 1068 ATF_TP_ADD_TC(tp, eaccess); 1069 ATF_TP_ADD_TC(tp, exists); 1070 ATF_TP_ADD_TC(tp, getcwd); 1071 ATF_TP_ADD_TC(tp, rmdir_empty); 1072 ATF_TP_ADD_TC(tp, rmdir_enotempty); 1073 ATF_TP_ADD_TC(tp, rmdir_eperm); 1074 ATF_TP_ADD_TC(tp, mkdtemp_ok); 1075 ATF_TP_ADD_TC(tp, mkdtemp_err); 1076 ATF_TP_ADD_TC(tp, mkdtemp_umask); 1077 ATF_TP_ADD_TC(tp, mkstemp_ok); 1078 ATF_TP_ADD_TC(tp, mkstemp_err); 1079 ATF_TP_ADD_TC(tp, mkstemp_umask); 1080 1081 return atf_no_error(); 1082 } 1083