]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - tests/sys/posixshm/posixshm_test.c
MFC r298304:
[FreeBSD/stable/10.git] / tests / sys / posixshm / posixshm_test.c
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 }