t_sysv.c revision 1.2.2.2 1 1.2.2.2 pgoyette /* $NetBSD: t_sysv.c,v 1.2.2.2 2012/11/06 18:31:54 pgoyette Exp $ */
2 1.2.2.2 pgoyette
3 1.2.2.2 pgoyette /*-
4 1.2.2.2 pgoyette * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc.
5 1.2.2.2 pgoyette * All rights reserved.
6 1.2.2.2 pgoyette *
7 1.2.2.2 pgoyette * This code is derived from software contributed to The NetBSD Foundation
8 1.2.2.2 pgoyette * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 1.2.2.2 pgoyette * NASA Ames Research Center, and by Andrew Doran.
10 1.2.2.2 pgoyette *
11 1.2.2.2 pgoyette * Redistribution and use in source and binary forms, with or without
12 1.2.2.2 pgoyette * modification, are permitted provided that the following conditions
13 1.2.2.2 pgoyette * are met:
14 1.2.2.2 pgoyette * 1. Redistributions of source code must retain the above copyright
15 1.2.2.2 pgoyette * notice, this list of conditions and the following disclaimer.
16 1.2.2.2 pgoyette * 2. Redistributions in binary form must reproduce the above copyright
17 1.2.2.2 pgoyette * notice, this list of conditions and the following disclaimer in the
18 1.2.2.2 pgoyette * documentation and/or other materials provided with the distribution.
19 1.2.2.2 pgoyette *
20 1.2.2.2 pgoyette * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 1.2.2.2 pgoyette * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 1.2.2.2 pgoyette * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 1.2.2.2 pgoyette * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 1.2.2.2 pgoyette * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 1.2.2.2 pgoyette * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 1.2.2.2 pgoyette * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 1.2.2.2 pgoyette * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 1.2.2.2 pgoyette * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 1.2.2.2 pgoyette * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 1.2.2.2 pgoyette * POSSIBILITY OF SUCH DAMAGE.
31 1.2.2.2 pgoyette */
32 1.2.2.2 pgoyette
33 1.2.2.2 pgoyette /*
34 1.2.2.2 pgoyette * Test the SVID-compatible Message Queue facility.
35 1.2.2.2 pgoyette */
36 1.2.2.2 pgoyette
37 1.2.2.2 pgoyette #include <atf-c.h>
38 1.2.2.2 pgoyette
39 1.2.2.2 pgoyette #include <err.h>
40 1.2.2.2 pgoyette #include <errno.h>
41 1.2.2.2 pgoyette #include <fcntl.h>
42 1.2.2.2 pgoyette #include <signal.h>
43 1.2.2.2 pgoyette #include <stdio.h>
44 1.2.2.2 pgoyette #include <stdlib.h>
45 1.2.2.2 pgoyette #include <string.h>
46 1.2.2.2 pgoyette #include <time.h>
47 1.2.2.2 pgoyette #include <unistd.h>
48 1.2.2.2 pgoyette
49 1.2.2.2 pgoyette #include <sys/ipc.h>
50 1.2.2.2 pgoyette #include <sys/msg.h>
51 1.2.2.2 pgoyette #include <sys/param.h>
52 1.2.2.2 pgoyette #include <sys/sem.h>
53 1.2.2.2 pgoyette #include <sys/shm.h>
54 1.2.2.2 pgoyette #include <sys/wait.h>
55 1.2.2.2 pgoyette
56 1.2.2.2 pgoyette volatile int did_sigsys, did_sigchild;
57 1.2.2.2 pgoyette volatile int child_status, child_count;
58 1.2.2.2 pgoyette
59 1.2.2.2 pgoyette void sigsys_handler(int);
60 1.2.2.2 pgoyette void sigchld_handler(int);
61 1.2.2.2 pgoyette
62 1.2.2.2 pgoyette key_t get_ftok(int);
63 1.2.2.2 pgoyette
64 1.2.2.2 pgoyette void print_msqid_ds(struct msqid_ds *, mode_t);
65 1.2.2.2 pgoyette void receiver(void);
66 1.2.2.2 pgoyette
67 1.2.2.2 pgoyette void print_semid_ds(struct semid_ds *, mode_t);
68 1.2.2.2 pgoyette void waiter(void);
69 1.2.2.2 pgoyette
70 1.2.2.2 pgoyette void print_shmid_ds(struct shmid_ds *, mode_t);
71 1.2.2.2 pgoyette void sharer(void);
72 1.2.2.2 pgoyette
73 1.2.2.2 pgoyette #define MESSAGE_TEXT_LEN 256
74 1.2.2.2 pgoyette
75 1.2.2.2 pgoyette struct mymsg {
76 1.2.2.2 pgoyette long mtype;
77 1.2.2.2 pgoyette char mtext[MESSAGE_TEXT_LEN];
78 1.2.2.2 pgoyette };
79 1.2.2.2 pgoyette
80 1.2.2.2 pgoyette const char *m1_str = "California is overrated.";
81 1.2.2.2 pgoyette const char *m2_str = "The quick brown fox jumped over the lazy dog.";
82 1.2.2.2 pgoyette
83 1.2.2.2 pgoyette size_t pgsize;
84 1.2.2.2 pgoyette
85 1.2.2.2 pgoyette #define MTYPE_1 1
86 1.2.2.2 pgoyette #define MTYPE_1_ACK 2
87 1.2.2.2 pgoyette
88 1.2.2.2 pgoyette #define MTYPE_2 3
89 1.2.2.2 pgoyette #define MTYPE_2_ACK 4
90 1.2.2.2 pgoyette
91 1.2.2.2 pgoyette int sender_msqid = -1;
92 1.2.2.2 pgoyette int sender_semid = -1;
93 1.2.2.2 pgoyette int sender_shmid = -1;
94 1.2.2.2 pgoyette pid_t child_pid;
95 1.2.2.2 pgoyette
96 1.2.2.2 pgoyette key_t msgkey, semkey, shmkey;
97 1.2.2.2 pgoyette
98 1.2.2.2 pgoyette int maxloop = 1;
99 1.2.2.2 pgoyette
100 1.2.2.2 pgoyette union semun {
101 1.2.2.2 pgoyette int val; /* value for SETVAL */
102 1.2.2.2 pgoyette struct semid_ds *buf; /* buffer for IPC_{STAT,SET} */
103 1.2.2.2 pgoyette u_short *array; /* array for GETALL & SETALL */
104 1.2.2.2 pgoyette };
105 1.2.2.2 pgoyette
106 1.2.2.2 pgoyette
107 1.2.2.2 pgoyette void
108 1.2.2.2 pgoyette sigsys_handler(int signo)
109 1.2.2.2 pgoyette {
110 1.2.2.2 pgoyette
111 1.2.2.2 pgoyette did_sigsys = 1;
112 1.2.2.2 pgoyette }
113 1.2.2.2 pgoyette
114 1.2.2.2 pgoyette void
115 1.2.2.2 pgoyette sigchld_handler(int signo)
116 1.2.2.2 pgoyette {
117 1.2.2.2 pgoyette int c_status;
118 1.2.2.2 pgoyette
119 1.2.2.2 pgoyette did_sigchild = 1;
120 1.2.2.2 pgoyette /*
121 1.2.2.2 pgoyette * Reap the child and return its status
122 1.2.2.2 pgoyette */
123 1.2.2.2 pgoyette if (wait(&c_status) == -1)
124 1.2.2.2 pgoyette child_status = -errno;
125 1.2.2.2 pgoyette else
126 1.2.2.2 pgoyette child_status = c_status;
127 1.2.2.2 pgoyette
128 1.2.2.2 pgoyette child_count--;
129 1.2.2.2 pgoyette }
130 1.2.2.2 pgoyette
131 1.2.2.2 pgoyette key_t get_ftok(int id)
132 1.2.2.2 pgoyette {
133 1.2.2.2 pgoyette int fd;
134 1.2.2.2 pgoyette char token_key[64], token_dir[64];
135 1.2.2.2 pgoyette char *tmpdir;
136 1.2.2.2 pgoyette key_t key;
137 1.2.2.2 pgoyette
138 1.2.2.2 pgoyette strlcpy(token_key, "/tmp/t_sysv.XXXXXX", sizeof(token_key));
139 1.2.2.2 pgoyette tmpdir = mkdtemp(token_key);
140 1.2.2.2 pgoyette ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp() failed: %d", errno);
141 1.2.2.2 pgoyette
142 1.2.2.2 pgoyette strlcpy(token_dir, tmpdir, sizeof(token_dir));
143 1.2.2.2 pgoyette strlcpy(token_key, tmpdir, sizeof(token_key));
144 1.2.2.2 pgoyette strlcat(token_key, "/token_key", sizeof(token_key));
145 1.2.2.2 pgoyette
146 1.2.2.2 pgoyette /* Create the file, since ftok() requires it to exist! */
147 1.2.2.2 pgoyette
148 1.2.2.2 pgoyette fd = open(token_key, O_RDWR | O_CREAT | O_EXCL);
149 1.2.2.2 pgoyette if (fd == -1) {
150 1.2.2.2 pgoyette rmdir(tmpdir);
151 1.2.2.2 pgoyette atf_tc_fail("open() of temp file failed: %d", errno);
152 1.2.2.2 pgoyette return (key_t)-1;
153 1.2.2.2 pgoyette } else
154 1.2.2.2 pgoyette close(fd);
155 1.2.2.2 pgoyette
156 1.2.2.2 pgoyette key = ftok(token_key, id);
157 1.2.2.2 pgoyette
158 1.2.2.2 pgoyette ATF_REQUIRE_MSG(unlink(token_key) != -1, "unlink() failed: %d", errno);
159 1.2.2.2 pgoyette ATF_REQUIRE_MSG(rmdir(token_dir) != -1, "rmdir() failed: %d", errno);
160 1.2.2.2 pgoyette
161 1.2.2.2 pgoyette return key;
162 1.2.2.2 pgoyette }
163 1.2.2.2 pgoyette
164 1.2.2.2 pgoyette ATF_TC_WITH_CLEANUP(msg);
165 1.2.2.2 pgoyette ATF_TC_HEAD(msg, tc)
166 1.2.2.2 pgoyette {
167 1.2.2.2 pgoyette
168 1.2.2.2 pgoyette atf_tc_set_md_var(tc, "timeout", "3");
169 1.2.2.2 pgoyette atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing");
170 1.2.2.2 pgoyette }
171 1.2.2.2 pgoyette
172 1.2.2.2 pgoyette ATF_TC_BODY(msg, tc)
173 1.2.2.2 pgoyette {
174 1.2.2.2 pgoyette struct sigaction sa;
175 1.2.2.2 pgoyette struct msqid_ds m_ds;
176 1.2.2.2 pgoyette struct mymsg m;
177 1.2.2.2 pgoyette sigset_t sigmask;
178 1.2.2.2 pgoyette int loop;
179 1.2.2.2 pgoyette int c_status;
180 1.2.2.2 pgoyette
181 1.2.2.2 pgoyette /*
182 1.2.2.2 pgoyette * Install a SIGSYS handler so that we can exit gracefully if
183 1.2.2.2 pgoyette * System V Message Queue support isn't in the kernel.
184 1.2.2.2 pgoyette */
185 1.2.2.2 pgoyette did_sigsys = 0;
186 1.2.2.2 pgoyette sa.sa_handler = sigsys_handler;
187 1.2.2.2 pgoyette sigemptyset(&sa.sa_mask);
188 1.2.2.2 pgoyette sa.sa_flags = 0;
189 1.2.2.2 pgoyette ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1,
190 1.2.2.2 pgoyette "sigaction SIGSYS: %d", errno);
191 1.2.2.2 pgoyette
192 1.2.2.2 pgoyette /*
193 1.2.2.2 pgoyette * Install a SIGCHLD handler to deal with all possible exit
194 1.2.2.2 pgoyette * conditions of the receiver.
195 1.2.2.2 pgoyette */
196 1.2.2.2 pgoyette did_sigchild = 0;
197 1.2.2.2 pgoyette child_count = 0;
198 1.2.2.2 pgoyette sa.sa_handler = sigchld_handler;
199 1.2.2.2 pgoyette sigemptyset(&sa.sa_mask);
200 1.2.2.2 pgoyette sa.sa_flags = 0;
201 1.2.2.2 pgoyette ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1,
202 1.2.2.2 pgoyette "sigaction SIGCHLD: %d", errno);
203 1.2.2.2 pgoyette
204 1.2.2.2 pgoyette msgkey = get_ftok(4160);
205 1.2.2.2 pgoyette ATF_REQUIRE_MSG(msgkey != (key_t)-1, "get_ftok failed");
206 1.2.2.2 pgoyette
207 1.2.2.2 pgoyette sender_msqid = msgget(msgkey, IPC_CREAT | 0640);
208 1.2.2.2 pgoyette ATF_REQUIRE_MSG(sender_msqid != -1, "msgget: %d", errno);
209 1.2.2.2 pgoyette
210 1.2.2.2 pgoyette if (did_sigsys) {
211 1.2.2.2 pgoyette atf_tc_skip("SYSV Message Queue not supported");
212 1.2.2.2 pgoyette return;
213 1.2.2.2 pgoyette }
214 1.2.2.2 pgoyette
215 1.2.2.2 pgoyette ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1,
216 1.2.2.2 pgoyette "msgctl IPC_STAT 1: %d", errno);
217 1.2.2.2 pgoyette
218 1.2.2.2 pgoyette print_msqid_ds(&m_ds, 0640);
219 1.2.2.2 pgoyette
220 1.2.2.2 pgoyette m_ds.msg_perm.mode = (m_ds.msg_perm.mode & ~0777) | 0600;
221 1.2.2.2 pgoyette
222 1.2.2.2 pgoyette ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_SET, &m_ds) != -1,
223 1.2.2.2 pgoyette "msgctl IPC_SET: %d", errno);
224 1.2.2.2 pgoyette
225 1.2.2.2 pgoyette memset(&m_ds, 0, sizeof(m_ds));
226 1.2.2.2 pgoyette
227 1.2.2.2 pgoyette ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1,
228 1.2.2.2 pgoyette "msgctl IPC_STAT 2: %d", errno);
229 1.2.2.2 pgoyette
230 1.2.2.2 pgoyette ATF_REQUIRE_MSG((m_ds.msg_perm.mode & 0777) == 0600,
231 1.2.2.2 pgoyette "IPC_SET of mode didn't hold");
232 1.2.2.2 pgoyette
233 1.2.2.2 pgoyette print_msqid_ds(&m_ds, 0600);
234 1.2.2.2 pgoyette
235 1.2.2.2 pgoyette switch ((child_pid = fork())) {
236 1.2.2.2 pgoyette case -1:
237 1.2.2.2 pgoyette atf_tc_fail("fork: %d", errno);
238 1.2.2.2 pgoyette return;
239 1.2.2.2 pgoyette
240 1.2.2.2 pgoyette case 0:
241 1.2.2.2 pgoyette child_count++;
242 1.2.2.2 pgoyette receiver();
243 1.2.2.2 pgoyette break;
244 1.2.2.2 pgoyette
245 1.2.2.2 pgoyette default:
246 1.2.2.2 pgoyette break;
247 1.2.2.2 pgoyette }
248 1.2.2.2 pgoyette
249 1.2.2.2 pgoyette for (loop = 0; loop < maxloop; loop++) {
250 1.2.2.2 pgoyette /*
251 1.2.2.2 pgoyette * Send the first message to the receiver and wait for the ACK.
252 1.2.2.2 pgoyette */
253 1.2.2.2 pgoyette m.mtype = MTYPE_1;
254 1.2.2.2 pgoyette strcpy(m.mtext, m1_str);
255 1.2.2.2 pgoyette ATF_REQUIRE_MSG(msgsnd(sender_msqid, &m, sizeof(m), 0) != -1,
256 1.2.2.2 pgoyette "sender: msgsnd 1: %d", errno);
257 1.2.2.2 pgoyette
258 1.2.2.2 pgoyette ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, sizeof(m),
259 1.2.2.2 pgoyette MTYPE_1_ACK, 0) == sizeof(m),
260 1.2.2.2 pgoyette "sender: msgrcv 1 ack: %d", errno);
261 1.2.2.2 pgoyette
262 1.2.2.2 pgoyette print_msqid_ds(&m_ds, 0600);
263 1.2.2.2 pgoyette
264 1.2.2.2 pgoyette /*
265 1.2.2.2 pgoyette * Send the second message to the receiver and wait for the ACK.
266 1.2.2.2 pgoyette */
267 1.2.2.2 pgoyette m.mtype = MTYPE_2;
268 1.2.2.2 pgoyette strcpy(m.mtext, m2_str);
269 1.2.2.2 pgoyette ATF_REQUIRE_MSG(msgsnd(sender_msqid, &m, sizeof(m), 0) != -1,
270 1.2.2.2 pgoyette "sender: msgsnd 2: %d", errno);
271 1.2.2.2 pgoyette
272 1.2.2.2 pgoyette ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, sizeof(m),
273 1.2.2.2 pgoyette MTYPE_2_ACK, 0) == sizeof(m),
274 1.2.2.2 pgoyette "sender: msgrcv 2 ack: %d", errno);
275 1.2.2.2 pgoyette }
276 1.2.2.2 pgoyette
277 1.2.2.2 pgoyette /*
278 1.2.2.2 pgoyette * Wait for child to finish
279 1.2.2.2 pgoyette */
280 1.2.2.2 pgoyette sigemptyset(&sigmask);
281 1.2.2.2 pgoyette (void) sigsuspend(&sigmask);
282 1.2.2.2 pgoyette
283 1.2.2.2 pgoyette /*
284 1.2.2.2 pgoyette * ...and any other signal is an unexpected error.
285 1.2.2.2 pgoyette */
286 1.2.2.2 pgoyette if (did_sigchild) {
287 1.2.2.2 pgoyette c_status = child_status;
288 1.2.2.2 pgoyette if (c_status < 0)
289 1.2.2.2 pgoyette atf_tc_fail("waitpid: %d", -c_status);
290 1.2.2.2 pgoyette else if (WIFEXITED(c_status) == 0)
291 1.2.2.2 pgoyette atf_tc_fail("child abnormal exit: %d", c_status);
292 1.2.2.2 pgoyette else if (WEXITSTATUS(c_status) != 0)
293 1.2.2.2 pgoyette atf_tc_fail("c status: %d", WEXITSTATUS(c_status));
294 1.2.2.2 pgoyette else {
295 1.2.2.2 pgoyette ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds)
296 1.2.2.2 pgoyette != -1, "msgctl IPC_STAT: %d", errno);
297 1.2.2.2 pgoyette
298 1.2.2.2 pgoyette print_msqid_ds(&m_ds, 0600);
299 1.2.2.2 pgoyette atf_tc_pass();
300 1.2.2.2 pgoyette }
301 1.2.2.2 pgoyette } else
302 1.2.2.2 pgoyette atf_tc_fail("sender: received unexpected signal");
303 1.2.2.2 pgoyette }
304 1.2.2.2 pgoyette
305 1.2.2.2 pgoyette ATF_TC_CLEANUP(msg, tc)
306 1.2.2.2 pgoyette {
307 1.2.2.2 pgoyette
308 1.2.2.2 pgoyette /*
309 1.2.2.2 pgoyette * Remove the message queue if it exists.
310 1.2.2.2 pgoyette */
311 1.2.2.2 pgoyette if (sender_msqid != -1)
312 1.2.2.2 pgoyette ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_RMID, NULL) != -1,
313 1.2.2.2 pgoyette "msgctl IPC_RMID: %d", errno);
314 1.2.2.2 pgoyette sender_msqid = -1;
315 1.2.2.2 pgoyette }
316 1.2.2.2 pgoyette
317 1.2.2.2 pgoyette void
318 1.2.2.2 pgoyette print_msqid_ds(mp, mode)
319 1.2.2.2 pgoyette struct msqid_ds *mp;
320 1.2.2.2 pgoyette mode_t mode;
321 1.2.2.2 pgoyette {
322 1.2.2.2 pgoyette uid_t uid = geteuid();
323 1.2.2.2 pgoyette gid_t gid = getegid();
324 1.2.2.2 pgoyette
325 1.2.2.2 pgoyette printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n",
326 1.2.2.2 pgoyette mp->msg_perm.uid, mp->msg_perm.gid,
327 1.2.2.2 pgoyette mp->msg_perm.cuid, mp->msg_perm.cgid,
328 1.2.2.2 pgoyette mp->msg_perm.mode & 0777);
329 1.2.2.2 pgoyette
330 1.2.2.2 pgoyette printf("qnum %lu, qbytes %lu, lspid %d, lrpid %d\n",
331 1.2.2.2 pgoyette mp->msg_qnum, (u_long)mp->msg_qbytes, mp->msg_lspid,
332 1.2.2.2 pgoyette mp->msg_lrpid);
333 1.2.2.2 pgoyette
334 1.2.2.2 pgoyette printf("stime: %s", ctime(&mp->msg_stime));
335 1.2.2.2 pgoyette printf("rtime: %s", ctime(&mp->msg_rtime));
336 1.2.2.2 pgoyette printf("ctime: %s", ctime(&mp->msg_ctime));
337 1.2.2.2 pgoyette
338 1.2.2.2 pgoyette /*
339 1.2.2.2 pgoyette * Sanity check a few things.
340 1.2.2.2 pgoyette */
341 1.2.2.2 pgoyette
342 1.2.2.2 pgoyette ATF_REQUIRE_MSG(mp->msg_perm.uid == uid && mp->msg_perm.cuid == uid,
343 1.2.2.2 pgoyette "uid mismatch");
344 1.2.2.2 pgoyette
345 1.2.2.2 pgoyette ATF_REQUIRE_MSG(mp->msg_perm.gid == gid && mp->msg_perm.cgid == gid,
346 1.2.2.2 pgoyette "gid mismatch");
347 1.2.2.2 pgoyette
348 1.2.2.2 pgoyette ATF_REQUIRE_MSG((mp->msg_perm.mode & 0777) == mode, "mode mismatch");
349 1.2.2.2 pgoyette }
350 1.2.2.2 pgoyette
351 1.2.2.2 pgoyette void
352 1.2.2.2 pgoyette receiver()
353 1.2.2.2 pgoyette {
354 1.2.2.2 pgoyette struct mymsg m;
355 1.2.2.2 pgoyette int msqid, loop;
356 1.2.2.2 pgoyette
357 1.2.2.2 pgoyette if ((msqid = msgget(msgkey, 0)) == -1)
358 1.2.2.2 pgoyette err(1, "receiver: msgget");
359 1.2.2.2 pgoyette
360 1.2.2.2 pgoyette for (loop = 0; loop < maxloop; loop++) {
361 1.2.2.2 pgoyette /*
362 1.2.2.2 pgoyette * Receive the first message, print it, and send an ACK.
363 1.2.2.2 pgoyette */
364 1.2.2.2 pgoyette if (msgrcv(msqid, &m, sizeof(m), MTYPE_1, 0) != sizeof(m))
365 1.2.2.2 pgoyette err(1, "receiver: msgrcv 1");
366 1.2.2.2 pgoyette
367 1.2.2.2 pgoyette printf("%s\n", m.mtext);
368 1.2.2.2 pgoyette if (strcmp(m.mtext, m1_str) != 0)
369 1.2.2.2 pgoyette err(1, "receiver: message 1 data isn't correct");
370 1.2.2.2 pgoyette
371 1.2.2.2 pgoyette m.mtype = MTYPE_1_ACK;
372 1.2.2.2 pgoyette
373 1.2.2.2 pgoyette if (msgsnd(msqid, &m, sizeof(m), 0) == -1)
374 1.2.2.2 pgoyette err(1, "receiver: msgsnd ack 1");
375 1.2.2.2 pgoyette
376 1.2.2.2 pgoyette /*
377 1.2.2.2 pgoyette * Receive the second message, print it, and send an ACK.
378 1.2.2.2 pgoyette */
379 1.2.2.2 pgoyette
380 1.2.2.2 pgoyette if (msgrcv(msqid, &m, sizeof(m), MTYPE_2, 0) != sizeof(m))
381 1.2.2.2 pgoyette err(1, "receiver: msgrcv 2");
382 1.2.2.2 pgoyette
383 1.2.2.2 pgoyette printf("%s\n", m.mtext);
384 1.2.2.2 pgoyette if (strcmp(m.mtext, m2_str) != 0)
385 1.2.2.2 pgoyette err(1, "receiver: message 2 data isn't correct");
386 1.2.2.2 pgoyette
387 1.2.2.2 pgoyette m.mtype = MTYPE_2_ACK;
388 1.2.2.2 pgoyette
389 1.2.2.2 pgoyette if (msgsnd(msqid, &m, sizeof(m), 0) == -1)
390 1.2.2.2 pgoyette err(1, "receiver: msgsnd ack 2");
391 1.2.2.2 pgoyette }
392 1.2.2.2 pgoyette
393 1.2.2.2 pgoyette exit(0);
394 1.2.2.2 pgoyette }
395 1.2.2.2 pgoyette
396 1.2.2.2 pgoyette /*
397 1.2.2.2 pgoyette * Test the SVID-compatible Semaphore facility.
398 1.2.2.2 pgoyette */
399 1.2.2.2 pgoyette
400 1.2.2.2 pgoyette ATF_TC_WITH_CLEANUP(sem);
401 1.2.2.2 pgoyette ATF_TC_HEAD(sem, tc)
402 1.2.2.2 pgoyette {
403 1.2.2.2 pgoyette
404 1.2.2.2 pgoyette atf_tc_set_md_var(tc, "timeout", "3");
405 1.2.2.2 pgoyette atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing");
406 1.2.2.2 pgoyette }
407 1.2.2.2 pgoyette
408 1.2.2.2 pgoyette ATF_TC_BODY(sem, tc)
409 1.2.2.2 pgoyette {
410 1.2.2.2 pgoyette struct sigaction sa;
411 1.2.2.2 pgoyette union semun sun;
412 1.2.2.2 pgoyette struct semid_ds s_ds;
413 1.2.2.2 pgoyette sigset_t sigmask;
414 1.2.2.2 pgoyette int i;
415 1.2.2.2 pgoyette int c_status;
416 1.2.2.2 pgoyette
417 1.2.2.2 pgoyette /*
418 1.2.2.2 pgoyette * Install a SIGSYS handler so that we can exit gracefully if
419 1.2.2.2 pgoyette * System V Semaphore support isn't in the kernel.
420 1.2.2.2 pgoyette */
421 1.2.2.2 pgoyette did_sigsys = 0;
422 1.2.2.2 pgoyette sa.sa_handler = sigsys_handler;
423 1.2.2.2 pgoyette sigemptyset(&sa.sa_mask);
424 1.2.2.2 pgoyette sa.sa_flags = 0;
425 1.2.2.2 pgoyette ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1,
426 1.2.2.2 pgoyette "sigaction SIGSYS: %d", errno);
427 1.2.2.2 pgoyette
428 1.2.2.2 pgoyette /*
429 1.2.2.2 pgoyette * Install a SIGCHLD handler to deal with all possible exit
430 1.2.2.2 pgoyette * conditions of the receiver.
431 1.2.2.2 pgoyette */
432 1.2.2.2 pgoyette did_sigchild = 0;
433 1.2.2.2 pgoyette child_count = 0;
434 1.2.2.2 pgoyette sa.sa_handler = sigchld_handler;
435 1.2.2.2 pgoyette sigemptyset(&sa.sa_mask);
436 1.2.2.2 pgoyette sa.sa_flags = 0;
437 1.2.2.2 pgoyette ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1,
438 1.2.2.2 pgoyette "sigaction SIGCHLD: %d", errno);
439 1.2.2.2 pgoyette
440 1.2.2.2 pgoyette semkey = get_ftok(4160);
441 1.2.2.2 pgoyette ATF_REQUIRE_MSG(semkey != (key_t)-1, "get_ftok failed");
442 1.2.2.2 pgoyette
443 1.2.2.2 pgoyette sender_semid = semget(semkey, 1, IPC_CREAT | 0640);
444 1.2.2.2 pgoyette ATF_REQUIRE_MSG(sender_semid != -1, "semget: %d", errno);
445 1.2.2.2 pgoyette
446 1.2.2.2 pgoyette if (did_sigsys) {
447 1.2.2.2 pgoyette atf_tc_skip("SYSV Semaphore not supported");
448 1.2.2.2 pgoyette return;
449 1.2.2.2 pgoyette }
450 1.2.2.2 pgoyette
451 1.2.2.2 pgoyette sun.buf = &s_ds;
452 1.2.2.2 pgoyette ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1,
453 1.2.2.2 pgoyette "semctl IPC_STAT: %d", errno);
454 1.2.2.2 pgoyette
455 1.2.2.2 pgoyette print_semid_ds(&s_ds, 0640);
456 1.2.2.2 pgoyette
457 1.2.2.2 pgoyette s_ds.sem_perm.mode = (s_ds.sem_perm.mode & ~0777) | 0600;
458 1.2.2.2 pgoyette
459 1.2.2.2 pgoyette sun.buf = &s_ds;
460 1.2.2.2 pgoyette ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_SET, sun) != -1,
461 1.2.2.2 pgoyette "semctl IPC_SET: %d", errno);
462 1.2.2.2 pgoyette
463 1.2.2.2 pgoyette memset(&s_ds, 0, sizeof(s_ds));
464 1.2.2.2 pgoyette
465 1.2.2.2 pgoyette sun.buf = &s_ds;
466 1.2.2.2 pgoyette ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1,
467 1.2.2.2 pgoyette "semctl IPC_STAT: %d", errno);
468 1.2.2.2 pgoyette
469 1.2.2.2 pgoyette ATF_REQUIRE_MSG((s_ds.sem_perm.mode & 0777) == 0600,
470 1.2.2.2 pgoyette "IPC_SET of mode didn't hold");
471 1.2.2.2 pgoyette
472 1.2.2.2 pgoyette print_semid_ds(&s_ds, 0600);
473 1.2.2.2 pgoyette
474 1.2.2.2 pgoyette for (child_count = 0; child_count < 5; child_count++) {
475 1.2.2.2 pgoyette switch ((child_pid = fork())) {
476 1.2.2.2 pgoyette case -1:
477 1.2.2.2 pgoyette atf_tc_fail("fork: %d", errno);
478 1.2.2.2 pgoyette return;
479 1.2.2.2 pgoyette
480 1.2.2.2 pgoyette case 0:
481 1.2.2.2 pgoyette waiter();
482 1.2.2.2 pgoyette break;
483 1.2.2.2 pgoyette
484 1.2.2.2 pgoyette default:
485 1.2.2.2 pgoyette break;
486 1.2.2.2 pgoyette }
487 1.2.2.2 pgoyette }
488 1.2.2.2 pgoyette
489 1.2.2.2 pgoyette /*
490 1.2.2.2 pgoyette * Wait for all of the waiters to be attempting to acquire the
491 1.2.2.2 pgoyette * semaphore.
492 1.2.2.2 pgoyette */
493 1.2.2.2 pgoyette for (;;) {
494 1.2.2.2 pgoyette i = semctl(sender_semid, 0, GETNCNT);
495 1.2.2.2 pgoyette if (i == -1)
496 1.2.2.2 pgoyette atf_tc_fail("semctl GETNCNT: %d", i);
497 1.2.2.2 pgoyette if (i == 5)
498 1.2.2.2 pgoyette break;
499 1.2.2.2 pgoyette }
500 1.2.2.2 pgoyette
501 1.2.2.2 pgoyette /*
502 1.2.2.2 pgoyette * Now set the thundering herd in motion by initializing the
503 1.2.2.2 pgoyette * semaphore to the value 1.
504 1.2.2.2 pgoyette */
505 1.2.2.2 pgoyette sun.val = 1;
506 1.2.2.2 pgoyette ATF_REQUIRE_MSG(semctl(sender_semid, 0, SETVAL, sun) != -1,
507 1.2.2.2 pgoyette "sender: semctl SETVAL to 1: %d", errno);
508 1.2.2.2 pgoyette
509 1.2.2.2 pgoyette /*
510 1.2.2.2 pgoyette * Wait for all children to finish
511 1.2.2.2 pgoyette */
512 1.2.2.2 pgoyette sigemptyset(&sigmask);
513 1.2.2.2 pgoyette for (;;) {
514 1.2.2.2 pgoyette (void) sigsuspend(&sigmask);
515 1.2.2.2 pgoyette if (did_sigchild) {
516 1.2.2.2 pgoyette c_status = child_status;
517 1.2.2.2 pgoyette if (c_status < 0)
518 1.2.2.2 pgoyette atf_tc_fail("waitpid: %d", -c_status);
519 1.2.2.2 pgoyette else if (WIFEXITED(c_status) == 0)
520 1.2.2.2 pgoyette atf_tc_fail("c abnormal exit: %d", c_status);
521 1.2.2.2 pgoyette else if (WEXITSTATUS(c_status) != 0)
522 1.2.2.2 pgoyette atf_tc_fail("c status: %d",
523 1.2.2.2 pgoyette WEXITSTATUS(c_status));
524 1.2.2.2 pgoyette else {
525 1.2.2.2 pgoyette sun.buf = &s_ds;
526 1.2.2.2 pgoyette ATF_REQUIRE_MSG(semctl(sender_semid, 0,
527 1.2.2.2 pgoyette IPC_STAT, sun) != -1,
528 1.2.2.2 pgoyette "semctl IPC_STAT: %d", errno);
529 1.2.2.2 pgoyette
530 1.2.2.2 pgoyette print_semid_ds(&s_ds, 0600);
531 1.2.2.2 pgoyette atf_tc_pass();
532 1.2.2.2 pgoyette }
533 1.2.2.2 pgoyette if (child_count <= 0)
534 1.2.2.2 pgoyette break;
535 1.2.2.2 pgoyette did_sigchild = 0;
536 1.2.2.2 pgoyette } else {
537 1.2.2.2 pgoyette atf_tc_fail("sender: received unexpected signal");
538 1.2.2.2 pgoyette break;
539 1.2.2.2 pgoyette }
540 1.2.2.2 pgoyette }
541 1.2.2.2 pgoyette }
542 1.2.2.2 pgoyette
543 1.2.2.2 pgoyette ATF_TC_CLEANUP(sem, tc)
544 1.2.2.2 pgoyette {
545 1.2.2.2 pgoyette
546 1.2.2.2 pgoyette /*
547 1.2.2.2 pgoyette * Remove the semaphore if it exists
548 1.2.2.2 pgoyette */
549 1.2.2.2 pgoyette if (sender_semid != -1)
550 1.2.2.2 pgoyette ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_RMID) != -1,
551 1.2.2.2 pgoyette "semctl IPC_RMID: %d", errno);
552 1.2.2.2 pgoyette sender_semid = -1;
553 1.2.2.2 pgoyette }
554 1.2.2.2 pgoyette
555 1.2.2.2 pgoyette void
556 1.2.2.2 pgoyette print_semid_ds(sp, mode)
557 1.2.2.2 pgoyette struct semid_ds *sp;
558 1.2.2.2 pgoyette mode_t mode;
559 1.2.2.2 pgoyette {
560 1.2.2.2 pgoyette uid_t uid = geteuid();
561 1.2.2.2 pgoyette gid_t gid = getegid();
562 1.2.2.2 pgoyette
563 1.2.2.2 pgoyette printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n",
564 1.2.2.2 pgoyette sp->sem_perm.uid, sp->sem_perm.gid,
565 1.2.2.2 pgoyette sp->sem_perm.cuid, sp->sem_perm.cgid,
566 1.2.2.2 pgoyette sp->sem_perm.mode & 0777);
567 1.2.2.2 pgoyette
568 1.2.2.2 pgoyette printf("nsems %u\n", sp->sem_nsems);
569 1.2.2.2 pgoyette
570 1.2.2.2 pgoyette printf("otime: %s", ctime(&sp->sem_otime));
571 1.2.2.2 pgoyette printf("ctime: %s", ctime(&sp->sem_ctime));
572 1.2.2.2 pgoyette
573 1.2.2.2 pgoyette /*
574 1.2.2.2 pgoyette * Sanity check a few things.
575 1.2.2.2 pgoyette */
576 1.2.2.2 pgoyette
577 1.2.2.2 pgoyette ATF_REQUIRE_MSG(sp->sem_perm.uid == uid && sp->sem_perm.cuid == uid,
578 1.2.2.2 pgoyette "uid mismatch");
579 1.2.2.2 pgoyette
580 1.2.2.2 pgoyette ATF_REQUIRE_MSG(sp->sem_perm.gid == gid && sp->sem_perm.cgid == gid,
581 1.2.2.2 pgoyette "gid mismatch");
582 1.2.2.2 pgoyette
583 1.2.2.2 pgoyette ATF_REQUIRE_MSG((sp->sem_perm.mode & 0777) == mode,
584 1.2.2.2 pgoyette "mode mismatch %o != %o", (sp->sem_perm.mode & 0777), mode);
585 1.2.2.2 pgoyette }
586 1.2.2.2 pgoyette
587 1.2.2.2 pgoyette void
588 1.2.2.2 pgoyette waiter()
589 1.2.2.2 pgoyette {
590 1.2.2.2 pgoyette struct sembuf s;
591 1.2.2.2 pgoyette int semid;
592 1.2.2.2 pgoyette
593 1.2.2.2 pgoyette if ((semid = semget(semkey, 1, 0)) == -1)
594 1.2.2.2 pgoyette err(1, "waiter: semget");
595 1.2.2.2 pgoyette
596 1.2.2.2 pgoyette /*
597 1.2.2.2 pgoyette * Attempt to acquire the semaphore.
598 1.2.2.2 pgoyette */
599 1.2.2.2 pgoyette s.sem_num = 0;
600 1.2.2.2 pgoyette s.sem_op = -1;
601 1.2.2.2 pgoyette s.sem_flg = SEM_UNDO;
602 1.2.2.2 pgoyette
603 1.2.2.2 pgoyette if (semop(semid, &s, 1) == -1)
604 1.2.2.2 pgoyette err(1, "waiter: semop -1");
605 1.2.2.2 pgoyette
606 1.2.2.2 pgoyette printf("WOO! GOT THE SEMAPHORE!\n");
607 1.2.2.2 pgoyette sleep(1);
608 1.2.2.2 pgoyette
609 1.2.2.2 pgoyette /*
610 1.2.2.2 pgoyette * Release the semaphore and exit.
611 1.2.2.2 pgoyette */
612 1.2.2.2 pgoyette s.sem_num = 0;
613 1.2.2.2 pgoyette s.sem_op = 1;
614 1.2.2.2 pgoyette s.sem_flg = SEM_UNDO;
615 1.2.2.2 pgoyette
616 1.2.2.2 pgoyette if (semop(semid, &s, 1) == -1)
617 1.2.2.2 pgoyette err(1, "waiter: semop +1");
618 1.2.2.2 pgoyette
619 1.2.2.2 pgoyette exit(0);
620 1.2.2.2 pgoyette }
621 1.2.2.2 pgoyette
622 1.2.2.2 pgoyette /*
623 1.2.2.2 pgoyette * Test the SVID-compatible Shared Memory facility.
624 1.2.2.2 pgoyette */
625 1.2.2.2 pgoyette
626 1.2.2.2 pgoyette ATF_TC_WITH_CLEANUP(shm);
627 1.2.2.2 pgoyette ATF_TC_HEAD(shm, tc)
628 1.2.2.2 pgoyette {
629 1.2.2.2 pgoyette
630 1.2.2.2 pgoyette atf_tc_set_md_var(tc, "timeout", "3");
631 1.2.2.2 pgoyette atf_tc_set_md_var(tc, "descr", "Checks sysv shared memory");
632 1.2.2.2 pgoyette }
633 1.2.2.2 pgoyette
634 1.2.2.2 pgoyette ATF_TC_BODY(shm, tc)
635 1.2.2.2 pgoyette {
636 1.2.2.2 pgoyette struct sigaction sa;
637 1.2.2.2 pgoyette struct shmid_ds s_ds;
638 1.2.2.2 pgoyette sigset_t sigmask;
639 1.2.2.2 pgoyette char *shm_buf;
640 1.2.2.2 pgoyette int c_status;
641 1.2.2.2 pgoyette
642 1.2.2.2 pgoyette /*
643 1.2.2.2 pgoyette * Install a SIGSYS handler so that we can exit gracefully if
644 1.2.2.2 pgoyette * System V Shared Memory support isn't in the kernel.
645 1.2.2.2 pgoyette */
646 1.2.2.2 pgoyette did_sigsys = 0;
647 1.2.2.2 pgoyette sa.sa_handler = sigsys_handler;
648 1.2.2.2 pgoyette sigemptyset(&sa.sa_mask);
649 1.2.2.2 pgoyette sa.sa_flags = 0;
650 1.2.2.2 pgoyette ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1,
651 1.2.2.2 pgoyette "sigaction SIGSYS: %d", errno);
652 1.2.2.2 pgoyette
653 1.2.2.2 pgoyette /*
654 1.2.2.2 pgoyette * Install a SIGCHLD handler to deal with all possible exit
655 1.2.2.2 pgoyette * conditions of the sharer.
656 1.2.2.2 pgoyette */
657 1.2.2.2 pgoyette did_sigchild = 0;
658 1.2.2.2 pgoyette child_count = 0;
659 1.2.2.2 pgoyette sa.sa_handler = sigchld_handler;
660 1.2.2.2 pgoyette sigemptyset(&sa.sa_mask);
661 1.2.2.2 pgoyette sa.sa_flags = 0;
662 1.2.2.2 pgoyette ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1,
663 1.2.2.2 pgoyette "sigaction SIGCHLD: %d", errno);
664 1.2.2.2 pgoyette
665 1.2.2.2 pgoyette pgsize = sysconf(_SC_PAGESIZE);
666 1.2.2.2 pgoyette
667 1.2.2.2 pgoyette shmkey = get_ftok(4160);
668 1.2.2.2 pgoyette ATF_REQUIRE_MSG(shmkey != (key_t)-1, "get_ftok failed");
669 1.2.2.2 pgoyette
670 1.2.2.2 pgoyette ATF_REQUIRE_MSG((sender_shmid = shmget(shmkey, pgsize,
671 1.2.2.2 pgoyette IPC_CREAT | 0640)) != -1,
672 1.2.2.2 pgoyette "shmget: %d", errno);
673 1.2.2.2 pgoyette
674 1.2.2.2 pgoyette ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1,
675 1.2.2.2 pgoyette "shmctl IPC_STAT: %d", errno);
676 1.2.2.2 pgoyette
677 1.2.2.2 pgoyette print_shmid_ds(&s_ds, 0640);
678 1.2.2.2 pgoyette
679 1.2.2.2 pgoyette s_ds.shm_perm.mode = (s_ds.shm_perm.mode & ~0777) | 0600;
680 1.2.2.2 pgoyette
681 1.2.2.2 pgoyette ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_SET, &s_ds) != -1,
682 1.2.2.2 pgoyette "shmctl IPC_SET: %d", errno);
683 1.2.2.2 pgoyette
684 1.2.2.2 pgoyette memset(&s_ds, 0, sizeof(s_ds));
685 1.2.2.2 pgoyette
686 1.2.2.2 pgoyette ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1,
687 1.2.2.2 pgoyette "shmctl IPC_STAT: %d", errno);
688 1.2.2.2 pgoyette
689 1.2.2.2 pgoyette ATF_REQUIRE_MSG((s_ds.shm_perm.mode & 0777) == 0600,
690 1.2.2.2 pgoyette "IPC_SET of mode didn't hold");
691 1.2.2.2 pgoyette
692 1.2.2.2 pgoyette print_shmid_ds(&s_ds, 0600);
693 1.2.2.2 pgoyette
694 1.2.2.2 pgoyette shm_buf = shmat(sender_shmid, NULL, 0);
695 1.2.2.2 pgoyette ATF_REQUIRE_MSG(shm_buf != (void *) -1, "sender: shmat: %d", errno);
696 1.2.2.2 pgoyette
697 1.2.2.2 pgoyette /*
698 1.2.2.2 pgoyette * Write the test pattern into the shared memory buffer.
699 1.2.2.2 pgoyette */
700 1.2.2.2 pgoyette strcpy(shm_buf, m2_str);
701 1.2.2.2 pgoyette
702 1.2.2.2 pgoyette switch ((child_pid = fork())) {
703 1.2.2.2 pgoyette case -1:
704 1.2.2.2 pgoyette atf_tc_fail("fork: %d", errno);
705 1.2.2.2 pgoyette return;
706 1.2.2.2 pgoyette
707 1.2.2.2 pgoyette case 0:
708 1.2.2.2 pgoyette sharer();
709 1.2.2.2 pgoyette break;
710 1.2.2.2 pgoyette
711 1.2.2.2 pgoyette default:
712 1.2.2.2 pgoyette break;
713 1.2.2.2 pgoyette }
714 1.2.2.2 pgoyette
715 1.2.2.2 pgoyette /*
716 1.2.2.2 pgoyette * Wait for child to finish
717 1.2.2.2 pgoyette */
718 1.2.2.2 pgoyette sigemptyset(&sigmask);
719 1.2.2.2 pgoyette (void) sigsuspend(&sigmask);
720 1.2.2.2 pgoyette
721 1.2.2.2 pgoyette if (did_sigchild) {
722 1.2.2.2 pgoyette c_status = child_status;
723 1.2.2.2 pgoyette if (c_status < 0)
724 1.2.2.2 pgoyette atf_tc_fail("waitpid: %d", -c_status);
725 1.2.2.2 pgoyette else if (WIFEXITED(c_status) == 0)
726 1.2.2.2 pgoyette atf_tc_fail("c abnormal exit: %d", c_status);
727 1.2.2.2 pgoyette else if (WEXITSTATUS(c_status) != 0)
728 1.2.2.2 pgoyette atf_tc_fail("c status: %d", WEXITSTATUS(c_status));
729 1.2.2.2 pgoyette else {
730 1.2.2.2 pgoyette ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT,
731 1.2.2.2 pgoyette &s_ds) != -1,
732 1.2.2.2 pgoyette "shmctl IPC_STAT: %d", errno);
733 1.2.2.2 pgoyette
734 1.2.2.2 pgoyette print_shmid_ds(&s_ds, 0600);
735 1.2.2.2 pgoyette atf_tc_pass();
736 1.2.2.2 pgoyette }
737 1.2.2.2 pgoyette } else
738 1.2.2.2 pgoyette atf_tc_fail("sender: received unexpected signal");
739 1.2.2.2 pgoyette }
740 1.2.2.2 pgoyette
741 1.2.2.2 pgoyette ATF_TC_CLEANUP(shm, tc)
742 1.2.2.2 pgoyette {
743 1.2.2.2 pgoyette
744 1.2.2.2 pgoyette /*
745 1.2.2.2 pgoyette * Remove the shared memory area if it exists.
746 1.2.2.2 pgoyette */
747 1.2.2.2 pgoyette if (sender_shmid != -1)
748 1.2.2.2 pgoyette ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_RMID, NULL) != -1,
749 1.2.2.2 pgoyette "shmctl IPC_RMID: %d", errno);
750 1.2.2.2 pgoyette sender_shmid = -1;
751 1.2.2.2 pgoyette }
752 1.2.2.2 pgoyette
753 1.2.2.2 pgoyette void
754 1.2.2.2 pgoyette print_shmid_ds(sp, mode)
755 1.2.2.2 pgoyette struct shmid_ds *sp;
756 1.2.2.2 pgoyette mode_t mode;
757 1.2.2.2 pgoyette {
758 1.2.2.2 pgoyette uid_t uid = geteuid();
759 1.2.2.2 pgoyette gid_t gid = getegid();
760 1.2.2.2 pgoyette
761 1.2.2.2 pgoyette printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n",
762 1.2.2.2 pgoyette sp->shm_perm.uid, sp->shm_perm.gid,
763 1.2.2.2 pgoyette sp->shm_perm.cuid, sp->shm_perm.cgid,
764 1.2.2.2 pgoyette sp->shm_perm.mode & 0777);
765 1.2.2.2 pgoyette
766 1.2.2.2 pgoyette printf("segsz %lu, lpid %d, cpid %d, nattch %u\n",
767 1.2.2.2 pgoyette (u_long)sp->shm_segsz, sp->shm_lpid, sp->shm_cpid,
768 1.2.2.2 pgoyette sp->shm_nattch);
769 1.2.2.2 pgoyette
770 1.2.2.2 pgoyette printf("atime: %s", ctime(&sp->shm_atime));
771 1.2.2.2 pgoyette printf("dtime: %s", ctime(&sp->shm_dtime));
772 1.2.2.2 pgoyette printf("ctime: %s", ctime(&sp->shm_ctime));
773 1.2.2.2 pgoyette
774 1.2.2.2 pgoyette /*
775 1.2.2.2 pgoyette * Sanity check a few things.
776 1.2.2.2 pgoyette */
777 1.2.2.2 pgoyette
778 1.2.2.2 pgoyette ATF_REQUIRE_MSG(sp->shm_perm.uid == uid && sp->shm_perm.cuid == uid,
779 1.2.2.2 pgoyette "uid mismatch");
780 1.2.2.2 pgoyette
781 1.2.2.2 pgoyette ATF_REQUIRE_MSG(sp->shm_perm.gid == gid && sp->shm_perm.cgid == gid,
782 1.2.2.2 pgoyette "gid mismatch");
783 1.2.2.2 pgoyette
784 1.2.2.2 pgoyette ATF_REQUIRE_MSG((sp->shm_perm.mode & 0777) == mode, "mode mismatch");
785 1.2.2.2 pgoyette }
786 1.2.2.2 pgoyette
787 1.2.2.2 pgoyette void
788 1.2.2.2 pgoyette sharer()
789 1.2.2.2 pgoyette {
790 1.2.2.2 pgoyette int shmid;
791 1.2.2.2 pgoyette void *shm_buf;
792 1.2.2.2 pgoyette
793 1.2.2.2 pgoyette shmid = shmget(shmkey, pgsize, 0);
794 1.2.2.2 pgoyette ATF_REQUIRE_MSG(shmid != -1, "receiver: shmget:%d", errno);
795 1.2.2.2 pgoyette
796 1.2.2.2 pgoyette shm_buf = shmat(shmid, NULL, 0);
797 1.2.2.2 pgoyette ATF_REQUIRE_MSG(shm_buf != (void *) -1, "receiver: shmat: %d", errno);
798 1.2.2.2 pgoyette
799 1.2.2.2 pgoyette printf("%s\n", (const char *)shm_buf);
800 1.2.2.2 pgoyette
801 1.2.2.2 pgoyette ATF_REQUIRE_MSG(strcmp((const char *)shm_buf, m2_str) == 0,
802 1.2.2.2 pgoyette "receiver: data isn't correct");
803 1.2.2.2 pgoyette
804 1.2.2.2 pgoyette exit(0);
805 1.2.2.2 pgoyette }
806 1.2.2.2 pgoyette
807 1.2.2.2 pgoyette ATF_TP_ADD_TCS(tp)
808 1.2.2.2 pgoyette {
809 1.2.2.2 pgoyette
810 1.2.2.2 pgoyette ATF_TP_ADD_TC(tp, msg);
811 1.2.2.2 pgoyette ATF_TP_ADD_TC(tp, sem);
812 1.2.2.2 pgoyette ATF_TP_ADD_TC(tp, shm);
813 1.2.2.2 pgoyette
814 1.2.2.2 pgoyette return atf_no_error();
815 1.2.2.2 pgoyette }
816 1.2.2.2 pgoyette
817