tools/llvm: Do not build with symbols
[minix3.git] / tests / kernel / t_sysv.c
blob51bd8dd05e12007489eec3ef6c177ca8255aabe6
1 /* $NetBSD: t_sysv.c,v 1.3 2013/07/24 11:44:10 skrll Exp $ */
3 /*-
4 * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center, and by Andrew Doran.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
34 * Test the SVID-compatible Message Queue facility.
37 #include <atf-c.h>
39 #include <err.h>
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <signal.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <time.h>
47 #include <unistd.h>
49 #include <sys/ipc.h>
50 #include <sys/msg.h>
51 #include <sys/param.h>
52 #include <sys/sem.h>
53 #include <sys/shm.h>
54 #include <sys/wait.h>
56 volatile int did_sigsys, did_sigchild;
57 volatile int child_status, child_count;
59 void sigsys_handler(int);
60 void sigchld_handler(int);
62 key_t get_ftok(int);
64 void print_msqid_ds(struct msqid_ds *, mode_t);
65 void receiver(void);
67 void print_semid_ds(struct semid_ds *, mode_t);
68 void waiter(void);
70 void print_shmid_ds(struct shmid_ds *, mode_t);
71 void sharer(void);
73 #define MESSAGE_TEXT_LEN 256
75 struct mymsg {
76 long mtype;
77 char mtext[MESSAGE_TEXT_LEN];
80 const char *m1_str = "California is overrated.";
81 const char *m2_str = "The quick brown fox jumped over the lazy dog.";
83 size_t pgsize;
85 #define MTYPE_1 1
86 #define MTYPE_1_ACK 2
88 #define MTYPE_2 3
89 #define MTYPE_2_ACK 4
91 int sender_msqid = -1;
92 int sender_semid = -1;
93 int sender_shmid = -1;
94 pid_t child_pid;
96 key_t msgkey, semkey, shmkey;
98 int maxloop = 1;
100 union semun {
101 int val; /* value for SETVAL */
102 struct semid_ds *buf; /* buffer for IPC_{STAT,SET} */
103 u_short *array; /* array for GETALL & SETALL */
107 void
108 sigsys_handler(int signo)
111 did_sigsys = 1;
114 void
115 sigchld_handler(int signo)
117 int c_status;
119 did_sigchild = 1;
121 * Reap the child and return its status
123 if (wait(&c_status) == -1)
124 child_status = -errno;
125 else
126 child_status = c_status;
128 child_count--;
131 key_t get_ftok(int id)
133 int fd;
134 char token_key[64], token_dir[64];
135 char *tmpdir;
136 key_t key;
138 strlcpy(token_key, "/tmp/t_sysv.XXXXXX", sizeof(token_key));
139 tmpdir = mkdtemp(token_key);
140 ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp() failed: %d", errno);
142 strlcpy(token_dir, tmpdir, sizeof(token_dir));
143 strlcpy(token_key, tmpdir, sizeof(token_key));
144 strlcat(token_key, "/token_key", sizeof(token_key));
146 /* Create the file, since ftok() requires it to exist! */
148 fd = open(token_key, O_RDWR | O_CREAT | O_EXCL);
149 if (fd == -1) {
150 rmdir(tmpdir);
151 atf_tc_fail("open() of temp file failed: %d", errno);
152 return (key_t)-1;
153 } else
154 close(fd);
156 key = ftok(token_key, id);
158 ATF_REQUIRE_MSG(unlink(token_key) != -1, "unlink() failed: %d", errno);
159 ATF_REQUIRE_MSG(rmdir(token_dir) != -1, "rmdir() failed: %d", errno);
161 return key;
164 ATF_TC_WITH_CLEANUP(msg);
165 ATF_TC_HEAD(msg, tc)
168 atf_tc_set_md_var(tc, "timeout", "3");
169 atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing");
172 ATF_TC_BODY(msg, tc)
174 struct sigaction sa;
175 struct msqid_ds m_ds;
176 struct mymsg m;
177 sigset_t sigmask;
178 int loop;
179 int c_status;
182 * Install a SIGSYS handler so that we can exit gracefully if
183 * System V Message Queue support isn't in the kernel.
185 did_sigsys = 0;
186 sa.sa_handler = sigsys_handler;
187 sigemptyset(&sa.sa_mask);
188 sa.sa_flags = 0;
189 ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1,
190 "sigaction SIGSYS: %d", errno);
193 * Install a SIGCHLD handler to deal with all possible exit
194 * conditions of the receiver.
196 did_sigchild = 0;
197 child_count = 0;
198 sa.sa_handler = sigchld_handler;
199 sigemptyset(&sa.sa_mask);
200 sa.sa_flags = 0;
201 ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1,
202 "sigaction SIGCHLD: %d", errno);
204 msgkey = get_ftok(4160);
205 ATF_REQUIRE_MSG(msgkey != (key_t)-1, "get_ftok failed");
207 sender_msqid = msgget(msgkey, IPC_CREAT | 0640);
208 ATF_REQUIRE_MSG(sender_msqid != -1, "msgget: %d", errno);
210 if (did_sigsys) {
211 atf_tc_skip("SYSV Message Queue not supported");
212 return;
215 ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1,
216 "msgctl IPC_STAT 1: %d", errno);
218 print_msqid_ds(&m_ds, 0640);
220 m_ds.msg_perm.mode = (m_ds.msg_perm.mode & ~0777) | 0600;
222 ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_SET, &m_ds) != -1,
223 "msgctl IPC_SET: %d", errno);
225 memset(&m_ds, 0, sizeof(m_ds));
227 ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1,
228 "msgctl IPC_STAT 2: %d", errno);
230 ATF_REQUIRE_MSG((m_ds.msg_perm.mode & 0777) == 0600,
231 "IPC_SET of mode didn't hold");
233 print_msqid_ds(&m_ds, 0600);
235 switch ((child_pid = fork())) {
236 case -1:
237 atf_tc_fail("fork: %d", errno);
238 return;
240 case 0:
241 child_count++;
242 receiver();
243 break;
245 default:
246 break;
249 for (loop = 0; loop < maxloop; loop++) {
251 * Send the first message to the receiver and wait for the ACK.
253 m.mtype = MTYPE_1;
254 strcpy(m.mtext, m1_str);
255 ATF_REQUIRE_MSG(msgsnd(sender_msqid, &m, MESSAGE_TEXT_LEN,
256 0) != -1, "sender: msgsnd 1: %d", errno);
258 ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, MESSAGE_TEXT_LEN,
259 MTYPE_1_ACK, 0) == MESSAGE_TEXT_LEN,
260 "sender: msgrcv 1 ack: %d", errno);
262 print_msqid_ds(&m_ds, 0600);
265 * Send the second message to the receiver and wait for the ACK.
267 m.mtype = MTYPE_2;
268 strcpy(m.mtext, m2_str);
269 ATF_REQUIRE_MSG(msgsnd(sender_msqid, &m, MESSAGE_TEXT_LEN, 0) != -1,
270 "sender: msgsnd 2: %d", errno);
272 ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, MESSAGE_TEXT_LEN,
273 MTYPE_2_ACK, 0) == MESSAGE_TEXT_LEN,
274 "sender: msgrcv 2 ack: %d", errno);
278 * Wait for child to finish
280 sigemptyset(&sigmask);
281 (void) sigsuspend(&sigmask);
284 * ...and any other signal is an unexpected error.
286 if (did_sigchild) {
287 c_status = child_status;
288 if (c_status < 0)
289 atf_tc_fail("waitpid: %d", -c_status);
290 else if (WIFEXITED(c_status) == 0)
291 atf_tc_fail("child abnormal exit: %d", c_status);
292 else if (WEXITSTATUS(c_status) != 0)
293 atf_tc_fail("c status: %d", WEXITSTATUS(c_status));
294 else {
295 ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds)
296 != -1, "msgctl IPC_STAT: %d", errno);
298 print_msqid_ds(&m_ds, 0600);
299 atf_tc_pass();
301 } else
302 atf_tc_fail("sender: received unexpected signal");
305 ATF_TC_CLEANUP(msg, tc)
309 * Remove the message queue if it exists.
311 if (sender_msqid != -1)
312 ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_RMID, NULL) != -1,
313 "msgctl IPC_RMID: %d", errno);
314 sender_msqid = -1;
317 void
318 print_msqid_ds(mp, mode)
319 struct msqid_ds *mp;
320 mode_t mode;
322 uid_t uid = geteuid();
323 gid_t gid = getegid();
325 printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n",
326 mp->msg_perm.uid, mp->msg_perm.gid,
327 mp->msg_perm.cuid, mp->msg_perm.cgid,
328 mp->msg_perm.mode & 0777);
330 printf("qnum %lu, qbytes %lu, lspid %d, lrpid %d\n",
331 mp->msg_qnum, (u_long)mp->msg_qbytes, mp->msg_lspid,
332 mp->msg_lrpid);
334 printf("stime: %s", ctime(&mp->msg_stime));
335 printf("rtime: %s", ctime(&mp->msg_rtime));
336 printf("ctime: %s", ctime(&mp->msg_ctime));
339 * Sanity check a few things.
342 ATF_REQUIRE_MSG(mp->msg_perm.uid == uid && mp->msg_perm.cuid == uid,
343 "uid mismatch");
345 ATF_REQUIRE_MSG(mp->msg_perm.gid == gid && mp->msg_perm.cgid == gid,
346 "gid mismatch");
348 ATF_REQUIRE_MSG((mp->msg_perm.mode & 0777) == mode, "mode mismatch");
351 void
352 receiver()
354 struct mymsg m;
355 int msqid, loop;
357 if ((msqid = msgget(msgkey, 0)) == -1)
358 err(1, "receiver: msgget");
360 for (loop = 0; loop < maxloop; loop++) {
362 * Receive the first message, print it, and send an ACK.
364 if (msgrcv(msqid, &m, MESSAGE_TEXT_LEN, MTYPE_1, 0) != MESSAGE_TEXT_LEN)
365 err(1, "receiver: msgrcv 1");
367 printf("%s\n", m.mtext);
368 if (strcmp(m.mtext, m1_str) != 0)
369 err(1, "receiver: message 1 data isn't correct");
371 m.mtype = MTYPE_1_ACK;
373 if (msgsnd(msqid, &m, MESSAGE_TEXT_LEN, 0) == -1)
374 err(1, "receiver: msgsnd ack 1");
377 * Receive the second message, print it, and send an ACK.
380 if (msgrcv(msqid, &m, MESSAGE_TEXT_LEN, MTYPE_2, 0) != MESSAGE_TEXT_LEN)
381 err(1, "receiver: msgrcv 2");
383 printf("%s\n", m.mtext);
384 if (strcmp(m.mtext, m2_str) != 0)
385 err(1, "receiver: message 2 data isn't correct");
387 m.mtype = MTYPE_2_ACK;
389 if (msgsnd(msqid, &m, MESSAGE_TEXT_LEN, 0) == -1)
390 err(1, "receiver: msgsnd ack 2");
393 exit(0);
397 * Test the SVID-compatible Semaphore facility.
400 ATF_TC_WITH_CLEANUP(sem);
401 ATF_TC_HEAD(sem, tc)
404 atf_tc_set_md_var(tc, "timeout", "3");
405 atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing");
408 ATF_TC_BODY(sem, tc)
410 struct sigaction sa;
411 union semun sun;
412 struct semid_ds s_ds;
413 sigset_t sigmask;
414 int i;
415 int c_status;
418 * Install a SIGSYS handler so that we can exit gracefully if
419 * System V Semaphore support isn't in the kernel.
421 did_sigsys = 0;
422 sa.sa_handler = sigsys_handler;
423 sigemptyset(&sa.sa_mask);
424 sa.sa_flags = 0;
425 ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1,
426 "sigaction SIGSYS: %d", errno);
429 * Install a SIGCHLD handler to deal with all possible exit
430 * conditions of the receiver.
432 did_sigchild = 0;
433 child_count = 0;
434 sa.sa_handler = sigchld_handler;
435 sigemptyset(&sa.sa_mask);
436 sa.sa_flags = 0;
437 ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1,
438 "sigaction SIGCHLD: %d", errno);
440 semkey = get_ftok(4160);
441 ATF_REQUIRE_MSG(semkey != (key_t)-1, "get_ftok failed");
443 sender_semid = semget(semkey, 1, IPC_CREAT | 0640);
444 ATF_REQUIRE_MSG(sender_semid != -1, "semget: %d", errno);
446 if (did_sigsys) {
447 atf_tc_skip("SYSV Semaphore not supported");
448 return;
451 sun.buf = &s_ds;
452 ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1,
453 "semctl IPC_STAT: %d", errno);
455 print_semid_ds(&s_ds, 0640);
457 s_ds.sem_perm.mode = (s_ds.sem_perm.mode & ~0777) | 0600;
459 sun.buf = &s_ds;
460 ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_SET, sun) != -1,
461 "semctl IPC_SET: %d", errno);
463 memset(&s_ds, 0, sizeof(s_ds));
465 sun.buf = &s_ds;
466 ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1,
467 "semctl IPC_STAT: %d", errno);
469 ATF_REQUIRE_MSG((s_ds.sem_perm.mode & 0777) == 0600,
470 "IPC_SET of mode didn't hold");
472 print_semid_ds(&s_ds, 0600);
474 for (child_count = 0; child_count < 5; child_count++) {
475 switch ((child_pid = fork())) {
476 case -1:
477 atf_tc_fail("fork: %d", errno);
478 return;
480 case 0:
481 waiter();
482 break;
484 default:
485 break;
490 * Wait for all of the waiters to be attempting to acquire the
491 * semaphore.
493 for (;;) {
494 i = semctl(sender_semid, 0, GETNCNT);
495 if (i == -1)
496 atf_tc_fail("semctl GETNCNT: %d", i);
497 if (i == 5)
498 break;
502 * Now set the thundering herd in motion by initializing the
503 * semaphore to the value 1.
505 sun.val = 1;
506 ATF_REQUIRE_MSG(semctl(sender_semid, 0, SETVAL, sun) != -1,
507 "sender: semctl SETVAL to 1: %d", errno);
510 * Wait for all children to finish
512 sigemptyset(&sigmask);
513 for (;;) {
514 (void) sigsuspend(&sigmask);
515 if (did_sigchild) {
516 c_status = child_status;
517 if (c_status < 0)
518 atf_tc_fail("waitpid: %d", -c_status);
519 else if (WIFEXITED(c_status) == 0)
520 atf_tc_fail("c abnormal exit: %d", c_status);
521 else if (WEXITSTATUS(c_status) != 0)
522 atf_tc_fail("c status: %d",
523 WEXITSTATUS(c_status));
524 else {
525 sun.buf = &s_ds;
526 ATF_REQUIRE_MSG(semctl(sender_semid, 0,
527 IPC_STAT, sun) != -1,
528 "semctl IPC_STAT: %d", errno);
530 print_semid_ds(&s_ds, 0600);
531 atf_tc_pass();
533 if (child_count <= 0)
534 break;
535 did_sigchild = 0;
536 } else {
537 atf_tc_fail("sender: received unexpected signal");
538 break;
543 ATF_TC_CLEANUP(sem, tc)
547 * Remove the semaphore if it exists
549 if (sender_semid != -1)
550 ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_RMID) != -1,
551 "semctl IPC_RMID: %d", errno);
552 sender_semid = -1;
555 void
556 print_semid_ds(sp, mode)
557 struct semid_ds *sp;
558 mode_t mode;
560 uid_t uid = geteuid();
561 gid_t gid = getegid();
563 printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n",
564 sp->sem_perm.uid, sp->sem_perm.gid,
565 sp->sem_perm.cuid, sp->sem_perm.cgid,
566 sp->sem_perm.mode & 0777);
568 printf("nsems %u\n", sp->sem_nsems);
570 printf("otime: %s", ctime(&sp->sem_otime));
571 printf("ctime: %s", ctime(&sp->sem_ctime));
574 * Sanity check a few things.
577 ATF_REQUIRE_MSG(sp->sem_perm.uid == uid && sp->sem_perm.cuid == uid,
578 "uid mismatch");
580 ATF_REQUIRE_MSG(sp->sem_perm.gid == gid && sp->sem_perm.cgid == gid,
581 "gid mismatch");
583 ATF_REQUIRE_MSG((sp->sem_perm.mode & 0777) == mode,
584 "mode mismatch %o != %o", (sp->sem_perm.mode & 0777), mode);
587 void
588 waiter()
590 struct sembuf s;
591 int semid;
593 if ((semid = semget(semkey, 1, 0)) == -1)
594 err(1, "waiter: semget");
597 * Attempt to acquire the semaphore.
599 s.sem_num = 0;
600 s.sem_op = -1;
601 s.sem_flg = SEM_UNDO;
603 if (semop(semid, &s, 1) == -1)
604 err(1, "waiter: semop -1");
606 printf("WOO! GOT THE SEMAPHORE!\n");
607 sleep(1);
610 * Release the semaphore and exit.
612 s.sem_num = 0;
613 s.sem_op = 1;
614 s.sem_flg = SEM_UNDO;
616 if (semop(semid, &s, 1) == -1)
617 err(1, "waiter: semop +1");
619 exit(0);
623 * Test the SVID-compatible Shared Memory facility.
626 ATF_TC_WITH_CLEANUP(shm);
627 ATF_TC_HEAD(shm, tc)
630 atf_tc_set_md_var(tc, "timeout", "3");
631 atf_tc_set_md_var(tc, "descr", "Checks sysv shared memory");
634 ATF_TC_BODY(shm, tc)
636 struct sigaction sa;
637 struct shmid_ds s_ds;
638 sigset_t sigmask;
639 char *shm_buf;
640 int c_status;
643 * Install a SIGSYS handler so that we can exit gracefully if
644 * System V Shared Memory support isn't in the kernel.
646 did_sigsys = 0;
647 sa.sa_handler = sigsys_handler;
648 sigemptyset(&sa.sa_mask);
649 sa.sa_flags = 0;
650 ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1,
651 "sigaction SIGSYS: %d", errno);
654 * Install a SIGCHLD handler to deal with all possible exit
655 * conditions of the sharer.
657 did_sigchild = 0;
658 child_count = 0;
659 sa.sa_handler = sigchld_handler;
660 sigemptyset(&sa.sa_mask);
661 sa.sa_flags = 0;
662 ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1,
663 "sigaction SIGCHLD: %d", errno);
665 pgsize = sysconf(_SC_PAGESIZE);
667 shmkey = get_ftok(4160);
668 ATF_REQUIRE_MSG(shmkey != (key_t)-1, "get_ftok failed");
670 ATF_REQUIRE_MSG((sender_shmid = shmget(shmkey, pgsize,
671 IPC_CREAT | 0640)) != -1,
672 "shmget: %d", errno);
674 ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1,
675 "shmctl IPC_STAT: %d", errno);
677 print_shmid_ds(&s_ds, 0640);
679 s_ds.shm_perm.mode = (s_ds.shm_perm.mode & ~0777) | 0600;
681 ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_SET, &s_ds) != -1,
682 "shmctl IPC_SET: %d", errno);
684 memset(&s_ds, 0, sizeof(s_ds));
686 ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1,
687 "shmctl IPC_STAT: %d", errno);
689 ATF_REQUIRE_MSG((s_ds.shm_perm.mode & 0777) == 0600,
690 "IPC_SET of mode didn't hold");
692 print_shmid_ds(&s_ds, 0600);
694 shm_buf = shmat(sender_shmid, NULL, 0);
695 ATF_REQUIRE_MSG(shm_buf != (void *) -1, "sender: shmat: %d", errno);
698 * Write the test pattern into the shared memory buffer.
700 strcpy(shm_buf, m2_str);
702 switch ((child_pid = fork())) {
703 case -1:
704 atf_tc_fail("fork: %d", errno);
705 return;
707 case 0:
708 sharer();
709 break;
711 default:
712 break;
716 * Wait for child to finish
718 sigemptyset(&sigmask);
719 (void) sigsuspend(&sigmask);
721 if (did_sigchild) {
722 c_status = child_status;
723 if (c_status < 0)
724 atf_tc_fail("waitpid: %d", -c_status);
725 else if (WIFEXITED(c_status) == 0)
726 atf_tc_fail("c abnormal exit: %d", c_status);
727 else if (WEXITSTATUS(c_status) != 0)
728 atf_tc_fail("c status: %d", WEXITSTATUS(c_status));
729 else {
730 ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT,
731 &s_ds) != -1,
732 "shmctl IPC_STAT: %d", errno);
734 print_shmid_ds(&s_ds, 0600);
735 atf_tc_pass();
737 } else
738 atf_tc_fail("sender: received unexpected signal");
741 ATF_TC_CLEANUP(shm, tc)
745 * Remove the shared memory area if it exists.
747 if (sender_shmid != -1)
748 ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_RMID, NULL) != -1,
749 "shmctl IPC_RMID: %d", errno);
750 sender_shmid = -1;
753 void
754 print_shmid_ds(sp, mode)
755 struct shmid_ds *sp;
756 mode_t mode;
758 uid_t uid = geteuid();
759 gid_t gid = getegid();
761 printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n",
762 sp->shm_perm.uid, sp->shm_perm.gid,
763 sp->shm_perm.cuid, sp->shm_perm.cgid,
764 sp->shm_perm.mode & 0777);
766 printf("segsz %lu, lpid %d, cpid %d, nattch %u\n",
767 (u_long)sp->shm_segsz, sp->shm_lpid, sp->shm_cpid,
768 sp->shm_nattch);
770 printf("atime: %s", ctime(&sp->shm_atime));
771 printf("dtime: %s", ctime(&sp->shm_dtime));
772 printf("ctime: %s", ctime(&sp->shm_ctime));
775 * Sanity check a few things.
778 ATF_REQUIRE_MSG(sp->shm_perm.uid == uid && sp->shm_perm.cuid == uid,
779 "uid mismatch");
781 ATF_REQUIRE_MSG(sp->shm_perm.gid == gid && sp->shm_perm.cgid == gid,
782 "gid mismatch");
784 ATF_REQUIRE_MSG((sp->shm_perm.mode & 0777) == mode, "mode mismatch");
787 void
788 sharer()
790 int shmid;
791 void *shm_buf;
793 shmid = shmget(shmkey, pgsize, 0);
794 ATF_REQUIRE_MSG(shmid != -1, "receiver: shmget:%d", errno);
796 shm_buf = shmat(shmid, NULL, 0);
797 ATF_REQUIRE_MSG(shm_buf != (void *) -1, "receiver: shmat: %d", errno);
799 printf("%s\n", (const char *)shm_buf);
801 ATF_REQUIRE_MSG(strcmp((const char *)shm_buf, m2_str) == 0,
802 "receiver: data isn't correct");
804 exit(0);
807 ATF_TP_ADD_TCS(tp)
810 ATF_TP_ADD_TC(tp, msg);
811 ATF_TP_ADD_TC(tp, sem);
812 ATF_TP_ADD_TC(tp, shm);
814 return atf_no_error();