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