1 /*- 2 * Copyright (c) 2006 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/param.h> 31 #include <sys/mman.h> 32 #include <sys/resource.h> 33 #include <sys/stat.h> 34 #include <sys/syscall.h> 35 #include <sys/wait.h> 36 37 #include <errno.h> 38 #include <fcntl.h> 39 #include <signal.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <unistd.h> 44 45 #include <atf-c.h> 46 47 #define TEST_PATH_LEN 256 48 static char test_path[TEST_PATH_LEN]; 49 50 static void 51 gen_test_path(void) 52 { 53 54 snprintf(test_path, sizeof(test_path), "%s/tmp.XXXXXX", 55 getenv("TMPDIR") == NULL ? "/tmp" : getenv("TMPDIR")); 56 test_path[sizeof(test_path) - 1] = '\0'; 57 ATF_REQUIRE_MSG(mkstemp(test_path) != -1, 58 "mkstemp failed; errno=%d", errno); 59 ATF_REQUIRE_MSG(unlink(test_path) == 0, 60 "unlink failed; errno=%d", errno); 61 } 62 63 /* 64 * Attempt a shm_open() that should fail with an expected error of 'error'. 65 */ 66 static void 67 shm_open_should_fail(const char *path, int flags, mode_t mode, int error) 68 { 69 int fd; 70 71 fd = shm_open(path, flags, mode); 72 ATF_CHECK_MSG(fd == -1, "shm_open didn't fail"); 73 ATF_CHECK_MSG(error == errno, 74 "shm_open didn't fail with expected errno; errno=%d; expected " 75 "errno=%d", errno, error); 76 } 77 78 /* 79 * Attempt a shm_unlink() that should fail with an expected error of 'error'. 80 */ 81 static void 82 shm_unlink_should_fail(const char *path, int error) 83 { 84 85 ATF_CHECK_MSG(shm_unlink(path) == -1, "shm_unlink didn't fail"); 86 ATF_CHECK_MSG(error == errno, 87 "shm_unlink didn't fail with expected errno; errno=%d; expected " 88 "errno=%d", errno, error); 89 } 90 91 /* 92 * Open the test object and write '1' to the first byte. Returns valid fd 93 * on success and -1 on failure. 94 */ 95 static int 96 scribble_object(void) 97 { 98 char *page; 99 int fd, pagesize; 100 101 gen_test_path(); 102 103 ATF_REQUIRE(0 < (pagesize = getpagesize())); 104 105 fd = shm_open(test_path, O_CREAT|O_EXCL|O_RDWR, 0777); 106 if (fd < 0 && errno == EEXIST) { 107 if (shm_unlink(test_path) < 0) 108 atf_tc_fail("shm_unlink"); 109 fd = shm_open(test_path, O_CREAT | O_EXCL | O_RDWR, 0777); 110 } 111 if (fd < 0) 112 atf_tc_fail("shm_open failed; errno=%d", errno); 113 if (ftruncate(fd, pagesize) < 0) 114 atf_tc_fail("ftruncate failed; errno=%d", errno); 115 116 page = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 117 if (page == MAP_FAILED) 118 atf_tc_fail("mmap failed; errno=%d", errno); 119 120 page[0] = '1'; 121 ATF_REQUIRE_MSG(munmap(page, pagesize) == 0, "munmap failed; errno=%d", 122 errno); 123 124 return (fd); 125 } 126 127 ATF_TC_WITHOUT_HEAD(remap_object); 128 ATF_TC_BODY(remap_object, tc) 129 { 130 char *page; 131 int fd, pagesize; 132 133 ATF_REQUIRE(0 < (pagesize = getpagesize())); 134 135 fd = scribble_object(); 136 137 page = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 138 if (page == MAP_FAILED) 139 atf_tc_fail("mmap(2) failed; errno=%d", errno); 140 141 if (page[0] != '1') 142 atf_tc_fail("missing data ('%c' != '1')", page[0]); 143 144 close(fd); 145 ATF_REQUIRE_MSG(munmap(page, pagesize) == 0, "munmap failed; errno=%d", 146 errno); 147 148 ATF_REQUIRE_MSG(shm_unlink(test_path) != -1, 149 "shm_unlink failed; errno=%d", errno); 150 } 151 152 ATF_TC_WITHOUT_HEAD(reopen_object); 153 ATF_TC_BODY(reopen_object, tc) 154 { 155 char *page; 156 int fd, pagesize; 157 158 ATF_REQUIRE(0 < (pagesize = getpagesize())); 159 160 fd = scribble_object(); 161 close(fd); 162 163 fd = shm_open(test_path, O_RDONLY, 0777); 164 if (fd < 0) 165 atf_tc_fail("shm_open(2) failed; errno=%d", errno); 166 167 page = mmap(0, pagesize, PROT_READ, MAP_SHARED, fd, 0); 168 if (page == MAP_FAILED) 169 atf_tc_fail("mmap(2) failed; errno=%d", errno); 170 171 if (page[0] != '1') 172 atf_tc_fail("missing data ('%c' != '1')", page[0]); 173 174 ATF_REQUIRE_MSG(munmap(page, pagesize) == 0, "munmap failed; errno=%d", 175 errno); 176 close(fd); 177 ATF_REQUIRE_MSG(shm_unlink(test_path) != -1, 178 "shm_unlink failed; errno=%d", errno); 179 } 180 181 ATF_TC_WITHOUT_HEAD(readonly_mmap_write); 182 ATF_TC_BODY(readonly_mmap_write, tc) 183 { 184 char *page; 185 int fd, pagesize; 186 187 ATF_REQUIRE(0 < (pagesize = getpagesize())); 188 189 gen_test_path(); 190 191 fd = shm_open(test_path, O_RDONLY | O_CREAT, 0777); 192 ATF_REQUIRE_MSG(fd >= 0, "shm_open failed; errno=%d", errno); 193 194 /* PROT_WRITE should fail with EACCES. */ 195 page = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 196 if (page != MAP_FAILED) 197 atf_tc_fail("mmap(PROT_WRITE) succeeded unexpectedly"); 198 199 if (errno != EACCES) 200 atf_tc_fail("mmap(PROT_WRITE) didn't fail with EACCES; " 201 "errno=%d", errno); 202 203 close(fd); 204 ATF_REQUIRE_MSG(shm_unlink(test_path) != -1, 205 "shm_unlink failed; errno=%d", errno); 206 } 207 208 ATF_TC_WITHOUT_HEAD(open_after_link); 209 ATF_TC_BODY(open_after_link, tc) 210 { 211 int fd; 212 213 gen_test_path(); 214 215 fd = shm_open(test_path, O_RDONLY | O_CREAT, 0777); 216 ATF_REQUIRE_MSG(fd >= 0, "shm_open(1) failed; errno=%d", errno); 217 close(fd); 218 219 ATF_REQUIRE_MSG(shm_unlink(test_path) != -1, "shm_unlink failed: %d", 220 errno); 221 222 shm_open_should_fail(test_path, O_RDONLY, 0777, ENOENT); 223 } 224 225 ATF_TC_WITHOUT_HEAD(open_invalid_path); 226 ATF_TC_BODY(open_invalid_path, tc) 227 { 228 229 shm_open_should_fail("blah", O_RDONLY, 0777, EINVAL); 230 } 231 232 ATF_TC_WITHOUT_HEAD(open_write_only); 233 ATF_TC_BODY(open_write_only, tc) 234 { 235 236 gen_test_path(); 237 238 shm_open_should_fail(test_path, O_WRONLY, 0777, EINVAL); 239 } 240 241 ATF_TC_WITHOUT_HEAD(open_extra_flags); 242 ATF_TC_BODY(open_extra_flags, tc) 243 { 244 245 gen_test_path(); 246 247 shm_open_should_fail(test_path, O_RDONLY | O_DIRECT, 0777, EINVAL); 248 } 249 250 ATF_TC_WITHOUT_HEAD(open_anon); 251 ATF_TC_BODY(open_anon, tc) 252 { 253 int fd; 254 255 fd = shm_open(SHM_ANON, O_RDWR, 0777); 256 ATF_REQUIRE_MSG(fd >= 0, "shm_open failed; errno=%d", errno); 257 close(fd); 258 } 259 260 ATF_TC_WITHOUT_HEAD(open_anon_readonly); 261 ATF_TC_BODY(open_anon_readonly, tc) 262 { 263 264 shm_open_should_fail(SHM_ANON, O_RDONLY, 0777, EINVAL); 265 } 266 267 ATF_TC_WITHOUT_HEAD(open_bad_path_pointer); 268 ATF_TC_BODY(open_bad_path_pointer, tc) 269 { 270 271 shm_open_should_fail((char *)1024, O_RDONLY, 0777, EFAULT); 272 } 273 274 ATF_TC_WITHOUT_HEAD(open_path_too_long); 275 ATF_TC_BODY(open_path_too_long, tc) 276 { 277 char *page; 278 279 page = malloc(MAXPATHLEN + 1); 280 memset(page, 'a', MAXPATHLEN); 281 page[MAXPATHLEN] = '\0'; 282 shm_open_should_fail(page, O_RDONLY, 0777, ENAMETOOLONG); 283 free(page); 284 } 285 286 ATF_TC_WITHOUT_HEAD(open_nonexisting_object); 287 ATF_TC_BODY(open_nonexisting_object, tc) 288 { 289 290 shm_open_should_fail("/notreallythere", O_RDONLY, 0777, ENOENT); 291 } 292 293 ATF_TC_WITHOUT_HEAD(open_create_existing_object); 294 ATF_TC_BODY(open_create_existing_object, tc) 295 { 296 int fd; 297 298 gen_test_path(); 299 300 fd = shm_open(test_path, O_RDONLY|O_CREAT, 0777); 301 ATF_REQUIRE_MSG(fd >= 0, "shm_open failed; errno=%d", errno); 302 close(fd); 303 304 shm_open_should_fail(test_path, O_RDONLY|O_CREAT|O_EXCL, 305 0777, EEXIST); 306 307 ATF_REQUIRE_MSG(shm_unlink(test_path) != -1, 308 "shm_unlink failed; errno=%d", errno); 309 } 310 311 ATF_TC_WITHOUT_HEAD(trunc_resets_object); 312 ATF_TC_BODY(trunc_resets_object, tc) 313 { 314 struct stat sb; 315 int fd; 316 317 gen_test_path(); 318 319 /* Create object and set size to 1024. */ 320 fd = shm_open(test_path, O_RDWR | O_CREAT, 0777); 321 ATF_REQUIRE_MSG(fd >= 0, "shm_open(1) failed; errno=%d", errno); 322 ATF_REQUIRE_MSG(ftruncate(fd, 1024) != -1, 323 "ftruncate failed; errno=%d", errno); 324 ATF_REQUIRE_MSG(fstat(fd, &sb) != -1, 325 "fstat(1) failed; errno=%d", errno); 326 ATF_REQUIRE_MSG(sb.st_size == 1024, "size %d != 1024", (int)sb.st_size); 327 close(fd); 328 329 /* Open with O_TRUNC which should reset size to 0. */ 330 fd = shm_open(test_path, O_RDWR | O_TRUNC, 0777); 331 ATF_REQUIRE_MSG(fd >= 0, "shm_open(2) failed; errno=%d", errno); 332 ATF_REQUIRE_MSG(fstat(fd, &sb) != -1, 333 "fstat(2) failed; errno=%d", errno); 334 ATF_REQUIRE_MSG(sb.st_size == 0, 335 "size was not 0 after truncation: %d", (int)sb.st_size); 336 close(fd); 337 ATF_REQUIRE_MSG(shm_unlink(test_path) != -1, 338 "shm_unlink failed; errno=%d", errno); 339 } 340 341 ATF_TC_WITHOUT_HEAD(unlink_bad_path_pointer); 342 ATF_TC_BODY(unlink_bad_path_pointer, tc) 343 { 344 345 shm_unlink_should_fail((char *)1024, EFAULT); 346 } 347 348 ATF_TC_WITHOUT_HEAD(unlink_path_too_long); 349 ATF_TC_BODY(unlink_path_too_long, tc) 350 { 351 char *page; 352 353 page = malloc(MAXPATHLEN + 1); 354 memset(page, 'a', MAXPATHLEN); 355 page[MAXPATHLEN] = '\0'; 356 shm_unlink_should_fail(page, ENAMETOOLONG); 357 free(page); 358 } 359 360 ATF_TC_WITHOUT_HEAD(object_resize); 361 ATF_TC_BODY(object_resize, tc) 362 { 363 pid_t pid; 364 struct stat sb; 365 char *page; 366 int fd, pagesize, status; 367 368 ATF_REQUIRE(0 < (pagesize = getpagesize())); 369 370 /* Start off with a size of a single page. */ 371 fd = shm_open(SHM_ANON, O_CREAT|O_RDWR, 0777); 372 if (fd < 0) 373 atf_tc_fail("shm_open failed; errno=%d", errno); 374 375 if (ftruncate(fd, pagesize) < 0) 376 atf_tc_fail("ftruncate(1) failed; errno=%d", errno); 377 378 if (fstat(fd, &sb) < 0) 379 atf_tc_fail("fstat(1) failed; errno=%d", errno); 380 381 if (sb.st_size != pagesize) 382 atf_tc_fail("first resize failed (%d != %d)", 383 (int)sb.st_size, pagesize); 384 385 /* Write a '1' to the first byte. */ 386 page = mmap(0, pagesize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 387 if (page == MAP_FAILED) 388 atf_tc_fail("mmap(1)"); 389 390 page[0] = '1'; 391 392 ATF_REQUIRE_MSG(munmap(page, pagesize) == 0, "munmap failed; errno=%d", 393 errno); 394 395 /* Grow the object to 2 pages. */ 396 if (ftruncate(fd, pagesize * 2) < 0) 397 atf_tc_fail("ftruncate(2) failed; errno=%d", errno); 398 399 if (fstat(fd, &sb) < 0) 400 atf_tc_fail("fstat(2) failed; errno=%d", errno); 401 402 if (sb.st_size != pagesize * 2) 403 atf_tc_fail("second resize failed (%d != %d)", 404 (int)sb.st_size, pagesize * 2); 405 406 /* Check for '1' at the first byte. */ 407 page = mmap(0, pagesize * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 408 if (page == MAP_FAILED) 409 atf_tc_fail("mmap(2) failed; errno=%d", errno); 410 411 if (page[0] != '1') 412 atf_tc_fail("'%c' != '1'", page[0]); 413 414 /* Write a '2' at the start of the second page. */ 415 page[pagesize] = '2'; 416 417 /* Shrink the object back to 1 page. */ 418 if (ftruncate(fd, pagesize) < 0) 419 atf_tc_fail("ftruncate(3) failed; errno=%d", errno); 420 421 if (fstat(fd, &sb) < 0) 422 atf_tc_fail("fstat(3) failed; errno=%d", errno); 423 424 if (sb.st_size != pagesize) 425 atf_tc_fail("third resize failed (%d != %d)", 426 (int)sb.st_size, pagesize); 427 428 /* 429 * Fork a child process to make sure the second page is no 430 * longer valid. 431 */ 432 pid = fork(); 433 if (pid == -1) 434 atf_tc_fail("fork failed; errno=%d", errno); 435 436 if (pid == 0) { 437 struct rlimit lim; 438 char c; 439 440 /* Don't generate a core dump. */ 441 ATF_REQUIRE(getrlimit(RLIMIT_CORE, &lim) == 0); 442 lim.rlim_cur = 0; 443 ATF_REQUIRE(setrlimit(RLIMIT_CORE, &lim) == 0); 444 445 /* 446 * The previous ftruncate(2) shrunk the backing object 447 * so that this address is no longer valid, so reading 448 * from it should trigger a SIGSEGV. 449 */ 450 c = page[pagesize]; 451 fprintf(stderr, "child: page 1: '%c'\n", c); 452 exit(0); 453 } 454 455 if (wait(&status) < 0) 456 atf_tc_fail("wait failed; errno=%d", errno); 457 458 if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGSEGV) 459 atf_tc_fail("child terminated with status %x", status); 460 461 /* Grow the object back to 2 pages. */ 462 if (ftruncate(fd, pagesize * 2) < 0) 463 atf_tc_fail("ftruncate(2) failed; errno=%d", errno); 464 465 if (fstat(fd, &sb) < 0) 466 atf_tc_fail("fstat(2) failed; errno=%d", errno); 467 468 if (sb.st_size != pagesize * 2) 469 atf_tc_fail("fourth resize failed (%d != %d)", 470 (int)sb.st_size, pagesize); 471 472 /* 473 * Note that the mapping at 'page' for the second page is 474 * still valid, and now that the shm object has been grown 475 * back up to 2 pages, there is now memory backing this page 476 * so the read will work. However, the data should be zero 477 * rather than '2' as the old data was thrown away when the 478 * object was shrunk and the new pages when an object are 479 * grown are zero-filled. 480 */ 481 if (page[pagesize] != 0) 482 atf_tc_fail("invalid data at %d: %x != 0", 483 pagesize, (int)page[pagesize]); 484 485 close(fd); 486 } 487 488 /* Signal handler which does nothing. */ 489 static void 490 ignoreit(int sig __unused) 491 { 492 ; 493 } 494 495 ATF_TC_WITHOUT_HEAD(shm_functionality_across_fork); 496 ATF_TC_BODY(shm_functionality_across_fork, tc) 497 { 498 char *cp, c; 499 int error, desc, rv; 500 long scval; 501 sigset_t ss; 502 struct sigaction sa; 503 void *region; 504 size_t i, psize; 505 506 #ifndef _POSIX_SHARED_MEMORY_OBJECTS 507 printf("_POSIX_SHARED_MEMORY_OBJECTS is undefined\n"); 508 #else 509 printf("_POSIX_SHARED_MEMORY_OBJECTS is defined as %ld\n", 510 (long)_POSIX_SHARED_MEMORY_OBJECTS - 0); 511 if (_POSIX_SHARED_MEMORY_OBJECTS - 0 == -1) 512 printf("***Indicates this feature may be unsupported!\n"); 513 #endif 514 errno = 0; 515 scval = sysconf(_SC_SHARED_MEMORY_OBJECTS); 516 if (scval == -1 && errno != 0) { 517 atf_tc_fail("sysconf(_SC_SHARED_MEMORY_OBJECTS) failed; " 518 "errno=%d", errno); 519 } else { 520 printf("sysconf(_SC_SHARED_MEMORY_OBJECTS) returns %ld\n", 521 scval); 522 if (scval == -1) 523 printf("***Indicates this feature is unsupported!\n"); 524 } 525 526 errno = 0; 527 scval = sysconf(_SC_PAGESIZE); 528 if (scval == -1 && errno != 0) { 529 atf_tc_fail("sysconf(_SC_PAGESIZE) failed; errno=%d", errno); 530 } else if (scval <= 0) { 531 fprintf(stderr, "bogus return from sysconf(_SC_PAGESIZE): %ld", 532 scval); 533 psize = 4096; 534 } else { 535 printf("sysconf(_SC_PAGESIZE) returns %ld\n", scval); 536 psize = scval; 537 } 538 539 gen_test_path(); 540 desc = shm_open(test_path, O_EXCL | O_CREAT | O_RDWR, 0600); 541 542 ATF_REQUIRE_MSG(desc >= 0, "shm_open failed; errno=%d", errno); 543 ATF_REQUIRE_MSG(shm_unlink(test_path) == 0, 544 "shm_unlink failed; errno=%d", errno); 545 ATF_REQUIRE_MSG(ftruncate(desc, (off_t)psize) != -1, 546 "ftruncate failed; errno=%d", errno); 547 548 region = mmap(NULL, psize, PROT_READ | PROT_WRITE, MAP_SHARED, desc, 0); 549 ATF_REQUIRE_MSG(region != MAP_FAILED, "mmap failed; errno=%d", errno); 550 memset(region, '\377', psize); 551 552 sa.sa_flags = 0; 553 sa.sa_handler = ignoreit; 554 sigemptyset(&sa.sa_mask); 555 ATF_REQUIRE_MSG(sigaction(SIGUSR1, &sa, (struct sigaction *)0) == 0, 556 "sigaction failed; errno=%d", errno); 557 558 sigemptyset(&ss); 559 sigaddset(&ss, SIGUSR1); 560 ATF_REQUIRE_MSG(sigprocmask(SIG_BLOCK, &ss, (sigset_t *)0) == 0, 561 "sigprocmask failed; errno=%d", errno); 562 563 rv = fork(); 564 ATF_REQUIRE_MSG(rv != -1, "fork failed; errno=%d", errno); 565 if (rv == 0) { 566 sigemptyset(&ss); 567 sigsuspend(&ss); 568 569 for (cp = region; cp < (char *)region + psize; cp++) { 570 if (*cp != '\151') 571 _exit(1); 572 } 573 if (lseek(desc, 0, SEEK_SET) == -1) 574 _exit(1); 575 for (i = 0; i < psize; i++) { 576 error = read(desc, &c, 1); 577 if (c != '\151') 578 _exit(1); 579 } 580 _exit(0); 581 } else { 582 int status; 583 584 memset(region, '\151', psize - 2); 585 error = pwrite(desc, region, 2, psize - 2); 586 if (error != 2) { 587 if (error >= 0) 588 atf_tc_fail("short write; %d bytes written", 589 error); 590 else 591 atf_tc_fail("shmfd write"); 592 } 593 kill(rv, SIGUSR1); 594 waitpid(rv, &status, 0); 595 596 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { 597 printf("Functionality test successful\n"); 598 } else if (WIFEXITED(status)) { 599 atf_tc_fail("Child process exited with status %d", 600 WEXITSTATUS(status)); 601 } else { 602 atf_tc_fail("Child process terminated with %s", 603 strsignal(WTERMSIG(status))); 604 } 605 } 606 607 ATF_REQUIRE_MSG(munmap(region, psize) == 0, "munmap failed; errno=%d", 608 errno); 609 shm_unlink(test_path); 610 } 611 612 ATF_TP_ADD_TCS(tp) 613 { 614 615 ATF_TP_ADD_TC(tp, remap_object); 616 ATF_TP_ADD_TC(tp, reopen_object); 617 ATF_TP_ADD_TC(tp, readonly_mmap_write); 618 ATF_TP_ADD_TC(tp, open_after_link); 619 ATF_TP_ADD_TC(tp, open_invalid_path); 620 ATF_TP_ADD_TC(tp, open_write_only); 621 ATF_TP_ADD_TC(tp, open_extra_flags); 622 ATF_TP_ADD_TC(tp, open_anon); 623 ATF_TP_ADD_TC(tp, open_anon_readonly); 624 ATF_TP_ADD_TC(tp, open_bad_path_pointer); 625 ATF_TP_ADD_TC(tp, open_path_too_long); 626 ATF_TP_ADD_TC(tp, open_nonexisting_object); 627 ATF_TP_ADD_TC(tp, open_create_existing_object); 628 ATF_TP_ADD_TC(tp, shm_functionality_across_fork); 629 ATF_TP_ADD_TC(tp, trunc_resets_object); 630 ATF_TP_ADD_TC(tp, unlink_bad_path_pointer); 631 ATF_TP_ADD_TC(tp, unlink_path_too_long); 632 ATF_TP_ADD_TC(tp, object_resize); 633 634 return (atf_no_error()); 635 } 636