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