2 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
7 * NASA Ames Research Center.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the NetBSD
20 * Foundation, Inc. and its contributors.
21 * 4. Neither the name of The NetBSD Foundation nor the names of its
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
37 * Obtained from: $NetBSD: shmtest.c,v 1.3 2002/07/20 08:36:26 grant Exp $
38 * $DragonFly: src/tools/regression/sysvshm/shmtest.c,v 1.2 2003/11/14 03:54:33 dillon Exp $
42 * Test the SVID-compatible Shared Memory facility.
45 #include <sys/param.h>
59 int main (int, char *[]);
60 void print_shmid_ds (struct shmid_ds
*, mode_t
);
61 void sigsys_handler (int);
62 void sigchld_handler (int);
67 const char *m_str
= "The quick brown fox jumped over the lazy dog.";
69 int sender_shmid
= -1;
90 * Install a SIGSYS handler so that we can exit gracefully if
91 * System V Shared Memory support isn't in the kernel.
93 sa
.sa_handler
= sigsys_handler
;
94 sigemptyset(&sa
.sa_mask
);
96 if (sigaction(SIGSYS
, &sa
, NULL
) == -1)
97 err(1, "sigaction SIGSYS");
100 * Install and SIGCHLD handler to deal with all possible exit
101 * conditions of the receiver.
103 sa
.sa_handler
= sigchld_handler
;
104 sigemptyset(&sa
.sa_mask
);
106 if (sigaction(SIGCHLD
, &sa
, NULL
) == -1)
107 err(1, "sigaction SIGCHLD");
109 pgsize
= sysconf(_SC_PAGESIZE
);
111 shmkey
= ftok(argv
[1], 4160);
114 * Initialize child_pid to ourselves to that the cleanup function
115 * works before we create the receiver.
117 child_pid
= getpid();
120 * Make sure that when the sender exits, the message queue is
123 if (atexit(cleanup
) == -1)
126 if ((sender_shmid
= shmget(shmkey
, pgsize
, IPC_CREAT
| 0640)) == -1)
129 if (shmctl(sender_shmid
, IPC_STAT
, &s_ds
) == -1)
130 err(1, "shmctl IPC_STAT");
132 print_shmid_ds(&s_ds
, 0640);
134 s_ds
.shm_perm
.mode
= (s_ds
.shm_perm
.mode
& ~0777) | 0600;
136 if (shmctl(sender_shmid
, IPC_SET
, &s_ds
) == -1)
137 err(1, "shmctl IPC_SET");
139 memset(&s_ds
, 0, sizeof(s_ds
));
141 if (shmctl(sender_shmid
, IPC_STAT
, &s_ds
) == -1)
142 err(1, "shmctl IPC_STAT");
144 if ((s_ds
.shm_perm
.mode
& 0777) != 0600)
145 err(1, "IPC_SET of mode didn't hold");
147 print_shmid_ds(&s_ds
, 0600);
149 if ((shm_buf
= shmat(sender_shmid
, NULL
, 0)) == (void *) -1)
150 err(1, "sender: shmat");
153 * Write the test pattern into the shared memory buffer.
155 strcpy(shm_buf
, m_str
);
157 switch ((child_pid
= fork())) {
171 * Suspend forever; when we get SIGCHLD, the handler will exit.
173 sigemptyset(&sigmask
);
174 (void) sigsuspend(&sigmask
);
177 * ...and any other signal is an unexpected error.
179 errx(1, "sender: received unexpected signal");
183 sigsys_handler(signo
)
187 errx(1, "System V Shared Memory support is not present in the kernel");
191 sigchld_handler(signo
)
194 struct shmid_ds s_ds
;
198 * Reap the child; if it exited successfully, then the test passed!
200 if (waitpid(child_pid
, &cstatus
, 0) != child_pid
)
203 if (WIFEXITED(cstatus
) == 0)
204 errx(1, "receiver exited abnormally");
206 if (WEXITSTATUS(cstatus
) != 0)
207 errx(1, "receiver exited with status %d",
208 WEXITSTATUS(cstatus
));
211 * If we get here, the child has exited normally, and thus
212 * we should exit normally too. First, tho, we print out
213 * the final stats for the message queue.
216 if (shmctl(sender_shmid
, IPC_STAT
, &s_ds
) == -1)
217 err(1, "shmctl IPC_STAT");
219 print_shmid_ds(&s_ds
, 0600);
229 * If we're the sender, and it exists, remove the shared memory area.
231 if (child_pid
!= 0 && sender_shmid
!= -1) {
232 if (shmctl(sender_shmid
, IPC_RMID
, NULL
) == -1)
233 warn("shmctl IPC_RMID");
238 print_shmid_ds(sp
, mode
)
242 uid_t uid
= geteuid();
243 gid_t gid
= getegid();
245 printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n",
246 sp
->shm_perm
.uid
, sp
->shm_perm
.gid
,
247 sp
->shm_perm
.cuid
, sp
->shm_perm
.cgid
,
248 sp
->shm_perm
.mode
& 0777);
250 printf("segsz %lu, lpid %d, cpid %d, nattch %u\n",
251 (u_long
)sp
->shm_segsz
, sp
->shm_lpid
, sp
->shm_cpid
,
254 printf("atime: %s", ctime(&sp
->shm_atime
));
255 printf("dtime: %s", ctime(&sp
->shm_dtime
));
256 printf("ctime: %s", ctime(&sp
->shm_ctime
));
259 * Sanity check a few things.
262 if (sp
->shm_perm
.uid
!= uid
|| sp
->shm_perm
.cuid
!= uid
)
263 errx(1, "uid mismatch");
265 if (sp
->shm_perm
.gid
!= gid
|| sp
->shm_perm
.cgid
!= gid
)
266 errx(1, "gid mismatch");
268 if ((sp
->shm_perm
.mode
& 0777) != mode
)
269 errx(1, "mode mismatch");
276 fprintf(stderr
, "usage: %s keypath\n", getprogname());
286 if ((shmid
= shmget(shmkey
, pgsize
, 0)) == -1)
287 err(1, "receiver: shmget");
289 if ((shm_buf
= shmat(shmid
, NULL
, 0)) == (void *) -1)
290 err(1, "receiver: shmat");
292 printf("%s\n", (const char *)shm_buf
);
293 if (strcmp((const char *)shm_buf
, m_str
) != 0)
294 err(1, "receiver: data isn't correct");