1 /*
2 * Copyright (c) 1995 Scott Bartram
3 * Copyright (c) 1995 Steven Wallace
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. The name of the author may not be used to endorse or promote products
12 * derived from this software without specific prior written permission
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * $FreeBSD: src/sys/i386/ibcs2/ibcs2_ipc.c,v 1.7.2.2 1999/09/05 08:11:24 peter Exp $
26 */
27
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/namei.h>
31 #include <sys/proc.h>
32 #include <sys/file.h>
33 #include <sys/stat.h>
34 #include <sys/filedesc.h>
35 #include <sys/ioctl.h>
36 #include <sys/ipc.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/mbuf.h>
40 #include <sys/mman.h>
41 #include <sys/mount.h>
42 #include <sys/reboot.h>
43 #include <sys/resource.h>
44 #include <sys/resourcevar.h>
45 #include <sys/signal.h>
46 #include <sys/signalvar.h>
47 #include <sys/socket.h>
48 #include <sys/time.h>
49 #include <sys/times.h>
50 #include <sys/vnode.h>
51 #include <sys/uio.h>
52 #include <sys/wait.h>
53 #include <sys/utsname.h>
54 #include <sys/unistd.h>
55 #include <sys/msg.h>
56 #include <sys/sem.h>
57 #include <sys/shm.h>
58 #include <sys/sysproto.h>
59
60 #include <vm/vm.h>
61
62 #include <i386/ibcs2/ibcs2_types.h>
63 #include <i386/ibcs2/ibcs2_signal.h>
64 #include <i386/ibcs2/ibcs2_proto.h>
65 #include <i386/ibcs2/ibcs2_util.h>
66 #include <i386/ibcs2/ibcs2_ipc.h>
67
68 #define IBCS2_IPC_RMID 0
69 #define IBCS2_IPC_SET 1
70 #define IBCS2_IPC_STAT 2
71 #define IBCS2_SETVAL 8
72
73
74
75 static void cvt_msqid2imsqid __P((struct msqid_ds *, struct ibcs2_msqid_ds *));
76 static void cvt_imsqid2msqid __P((struct ibcs2_msqid_ds *, struct msqid_ds *));
77 #ifdef unused
78 static void cvt_sem2isem __P((struct sem *, struct ibcs2_sem *));
79 static void cvt_isem2sem __P((struct ibcs2_sem *, struct sem *));
80 #endif
81 static void cvt_semid2isemid __P((struct semid_ds *, struct ibcs2_semid_ds *));
82 static void cvt_isemid2semid __P((struct ibcs2_semid_ds *, struct semid_ds *));
83 static void cvt_shmid2ishmid __P((struct shmid_ds *, struct ibcs2_shmid_ds *));
84 static void cvt_ishmid2shmid __P((struct ibcs2_shmid_ds *, struct shmid_ds *));
85
86
87 /*
88 * iBCS2 msgsys call
89 */
90
91 static void
92 cvt_msqid2imsqid(bp, ibp)
93 struct msqid_ds *bp;
94 struct ibcs2_msqid_ds *ibp;
95 {
96 ibp->msg_perm = bp->msg_perm;
97 ibp->msg_first = bp->msg_first;
98 ibp->msg_last = bp->msg_last;
99 ibp->msg_cbytes = (u_short)bp->msg_cbytes;
100 ibp->msg_qnum = (u_short)bp->msg_qnum;
101 ibp->msg_qbytes = (u_short)bp->msg_qbytes;
102 ibp->msg_lspid = (u_short)bp->msg_lspid;
103 ibp->msg_lrpid = (u_short)bp->msg_lrpid;
104 ibp->msg_stime = bp->msg_stime;
105 ibp->msg_rtime = bp->msg_rtime;
106 ibp->msg_ctime = bp->msg_ctime;
107 return;
108 }
109
110 static void
111 cvt_imsqid2msqid(ibp, bp)
112 struct ibcs2_msqid_ds *ibp;
113 struct msqid_ds *bp;
114 {
115 bp->msg_perm = ibp->msg_perm;
116 bp->msg_first = ibp->msg_first;
117 bp->msg_last = ibp->msg_last;
118 bp->msg_cbytes = ibp->msg_cbytes;
119 bp->msg_qnum = ibp->msg_qnum;
120 bp->msg_qbytes = ibp->msg_qbytes;
121 bp->msg_lspid = ibp->msg_lspid;
122 bp->msg_lrpid = ibp->msg_lrpid;
123 bp->msg_stime = ibp->msg_stime;
124 bp->msg_rtime = ibp->msg_rtime;
125 bp->msg_ctime = ibp->msg_ctime;
126 return;
127 }
128
129 int
130 ibcs2_msgsys(p, uap, retval)
131 struct proc *p;
132 struct ibcs2_msgsys_args *uap;
133 int *retval;
134 {
135 switch (SCARG(uap, which)) {
136 case 0: /* msgget */
137 SCARG(uap, which) = 1;
138 return msgsys(p, (struct msgsys_args *)uap, retval);
139 case 1: { /* msgctl */
140 int error;
141 struct msgsys_args margs;
142 caddr_t sg = stackgap_init();
143
144 SCARG(&margs, which) = 0;
145 SCARG(&margs, a2) = SCARG(uap, a2);
146 SCARG(&margs, a4) =
147 (int)stackgap_alloc(&sg, sizeof(struct msqid_ds));
148 SCARG(&margs, a3) = SCARG(uap, a3);
149 switch (SCARG(&margs, a3)) {
150 case IBCS2_IPC_STAT:
151 error = msgsys(p, &margs, retval);
152 if (!error)
153 cvt_msqid2imsqid(
154 (struct msqid_ds *)SCARG(&margs, a4),
155 (struct ibcs2_msqid_ds *)SCARG(uap, a4));
156 return error;
157 case IBCS2_IPC_SET:
158 cvt_imsqid2msqid((struct ibcs2_msqid_ds *)SCARG(uap,
159 a4),
160 (struct msqid_ds *)SCARG(&margs, a4));
161 return msgsys(p, &margs, retval);
162 case IBCS2_IPC_RMID:
163 return msgsys(p, &margs, retval);
164 }
165 return EINVAL;
166 }
167 case 2: /* msgrcv */
168 SCARG(uap, which) = 3;
169 return msgsys(p, (struct msgsys_args *)uap, retval);
170 case 3: /* msgsnd */
171 SCARG(uap, which) = 2;
172 return msgsys(p, (struct msgsys_args *)uap, retval);
173 default:
174 return EINVAL;
175 }
176 }
177
178 /*
179 * iBCS2 semsys call
180 */
181 #ifdef unused
182 static void
183 cvt_sem2isem(bp, ibp)
184 struct sem *bp;
185 struct ibcs2_sem *ibp;
186 {
187 ibp->semval = bp->semval;
188 ibp->sempid = bp->sempid;
189 ibp->semncnt = bp->semncnt;
190 ibp->semzcnt = bp->semzcnt;
191 return;
192 }
193
194 static void
195 cvt_isem2sem(ibp, bp)
196 struct ibcs2_sem *ibp;
197 struct sem *bp;
198 {
199 bp->semval = ibp->semval;
200 bp->sempid = ibp->sempid;
201 bp->semncnt = ibp->semncnt;
202 bp->semzcnt = ibp->semzcnt;
203 return;
204 }
205 #endif
206
207 static void
208 cvt_semid2isemid(bp, ibp)
209 struct semid_ds *bp;
210 struct ibcs2_semid_ds *ibp;
211 {
212 ibp->sem_perm = bp->sem_perm;
213 ibp->sem_base = (struct ibcs2_sem *)bp->sem_base;
214 ibp->sem_nsems = bp->sem_nsems;
215 ibp->sem_otime = bp->sem_otime;
216 ibp->sem_ctime = bp->sem_ctime;
217 return;
218 }
219
220 static void
221 cvt_isemid2semid(ibp, bp)
222 struct ibcs2_semid_ds *ibp;
223 struct semid_ds *bp;
224 {
225 bp->sem_perm = ibp->sem_perm;
226 bp->sem_base = (struct sem *)ibp->sem_base;
227 bp->sem_nsems = ibp->sem_nsems;
228 bp->sem_otime = ibp->sem_otime;
229 bp->sem_ctime = ibp->sem_ctime;
230 return;
231 }
232
233 int
234 ibcs2_semsys(p, uap, retval)
235 struct proc *p;
236 struct ibcs2_semsys_args *uap;
237 int *retval;
238 {
239 int error;
240
241 switch (SCARG(uap, which)) {
242 case 0: /* semctl */
243 switch(SCARG(uap, a4)) {
244 case IBCS2_IPC_STAT:
245 {
246 struct ibcs2_semid_ds *isp;
247 struct semid_ds *sp;
248 caddr_t sg = stackgap_init();
249
250 isp = (struct ibcs2_semid_ds *)SCARG(uap, a5);
251 sp = stackgap_alloc(&sg, sizeof(struct semid_ds));
252 SCARG(uap, a5) = (int)sp;
253 error = semsys(p, (struct semsys_args *)uap, retval);
254 if (!error) {
255 SCARG(uap, a5) = (int)isp;
256 isp = stackgap_alloc(&sg, sizeof(*isp));
257 cvt_semid2isemid(sp, isp);
258 error = copyout((caddr_t)isp,
259 (caddr_t)SCARG(uap, a5),
260 sizeof(*isp));
261 }
262 return error;
263 }
264 case IBCS2_IPC_SET:
265 {
266 struct ibcs2_semid_ds *isp;
267 struct semid_ds *sp;
268 caddr_t sg = stackgap_init();
269
270 isp = stackgap_alloc(&sg, sizeof(*isp));
271 sp = stackgap_alloc(&sg, sizeof(*sp));
272 error = copyin((caddr_t)SCARG(uap, a5), (caddr_t)isp,
273 sizeof(*isp));
274 if (error)
275 return error;
276 cvt_isemid2semid(isp, sp);
277 SCARG(uap, a5) = (int)sp;
278 return semsys(p, (struct semsys_args *)uap, retval);
279 }
280 case IBCS2_SETVAL:
281 {
282 union semun *sp;
283 caddr_t sg = stackgap_init();
284
285 sp = stackgap_alloc(&sg, sizeof(*sp));
286 sp->val = (int) SCARG(uap, a5);
287 SCARG(uap, a5) = (int)sp;
288 return semsys(p, (struct semsys_args *)uap, retval);
289 }
290 }
291
292 return semsys(p, (struct semsys_args *)uap, retval);
293
294 case 1: /* semget */
295 return semsys(p, (struct semsys_args *)uap, retval);
296
297 case 2: /* semop */
298 return semsys(p, (struct semsys_args *)uap, retval);
299 }
300 return EINVAL;
301 }
302
303
304 /*
305 * iBCS2 shmsys call
306 */
307
308 static void
309 cvt_shmid2ishmid(bp, ibp)
310 struct shmid_ds *bp;
311 struct ibcs2_shmid_ds *ibp;
312 {
313 ibp->shm_perm = bp->shm_perm;
314 ibp->shm_segsz = bp->shm_segsz;
315 ibp->shm_lpid = bp->shm_lpid;
316 ibp->shm_cpid = bp->shm_cpid;
317 ibp->shm_nattch = bp->shm_nattch;
318 ibp->shm_cnattch = 0; /* ignored anyway */
319 ibp->shm_atime = bp->shm_atime;
320 ibp->shm_dtime = bp->shm_dtime;
321 ibp->shm_ctime = bp->shm_ctime;
322 return;
323 }
324
325 static void
326 cvt_ishmid2shmid(ibp, bp)
327 struct ibcs2_shmid_ds *ibp;
328 struct shmid_ds *bp;
329 {
330 bp->shm_perm = ibp->shm_perm;
331 bp->shm_segsz = ibp->shm_segsz;
332 bp->shm_lpid = ibp->shm_lpid;
333 bp->shm_cpid = ibp->shm_cpid;
334 bp->shm_nattch = ibp->shm_nattch;
335 bp->shm_atime = ibp->shm_atime;
336 bp->shm_dtime = ibp->shm_dtime;
337 bp->shm_ctime = ibp->shm_ctime;
338 bp->shm_internal = (void *)0; /* ignored anyway */
339 return;
340 }
341
342 int
343 ibcs2_shmsys(p, uap, retval)
344 struct proc *p;
345 struct ibcs2_shmsys_args *uap;
346 int *retval;
347 {
348 int error;
349
350 switch (SCARG(uap, which)) {
351 case 0: /* shmat */
352 return shmsys(p, (struct shmsys_args *)uap, retval);
353
354 case 1: /* shmctl */
355 switch(SCARG(uap, a3)) {
356 case IBCS2_IPC_STAT:
357 {
358 struct ibcs2_shmid_ds *isp;
359 struct shmid_ds *sp;
360 caddr_t sg = stackgap_init();
361
362 isp = (struct ibcs2_shmid_ds *)SCARG(uap, a4);
363 sp = stackgap_alloc(&sg, sizeof(*sp));
364 SCARG(uap, a4) = (int)sp;
365 error = shmsys(p, (struct shmsys_args *)uap, retval);
366 if (!error) {
367 SCARG(uap, a4) = (int)isp;
368 isp = stackgap_alloc(&sg, sizeof(*isp));
369 cvt_shmid2ishmid(sp, isp);
370 error = copyout((caddr_t)isp,
371 (caddr_t)SCARG(uap, a4),
372 sizeof(*isp));
373 }
374 return error;
375 }
376 case IBCS2_IPC_SET:
377 {
378 struct ibcs2_shmid_ds *isp;
379 struct shmid_ds *sp;
380 caddr_t sg = stackgap_init();
381
382 isp = stackgap_alloc(&sg, sizeof(*isp));
383 sp = stackgap_alloc(&sg, sizeof(*sp));
384 error = copyin((caddr_t)SCARG(uap, a4), (caddr_t)isp,
385 sizeof(*isp));
386 if (error)
387 return error;
388 cvt_ishmid2shmid(isp, sp);
389 SCARG(uap, a4) = (int)sp;
390 return shmsys(p, (struct shmsys_args *)uap, retval);
391 }
392 }
393
394 return shmsys(p, (struct shmsys_args *)uap, retval);
395
396 case 2: /* shmdt */
397 return shmsys(p, (struct shmsys_args *)uap, retval);
398
399 case 3: /* shmget */
400 return shmsys(p, (struct shmsys_args *)uap, retval);
401 }
402 return EINVAL;
403 }
Cache object: 21658f970326534a85b1ea728457cb0c
|