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