1 /*-
2 * Copyright (c) 1995 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Christos Zoulas.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the NetBSD
19 * Foundation, Inc. and its contributors.
20 * 4. Neither the name of The NetBSD Foundation nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
28 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36 /*-
37 * Portions of this code have been derived from software contributed
38 * to the FreeBSD Project by Mark Newton.
39 *
40 * Copyright (c) 1999 Mark Newton
41 * All rights reserved.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution.
51 * 3. The name of the author may not be used to endorse or promote products
52 * derived from this software without specific prior written permission
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
58 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 *
65 * XXX- This code is presently a no-op on FreeBSD (and isn't compiled due
66 * to preprocessor conditionals). A nice project for a kernel hacking
67 * novice might be to MakeItGo, but I have more important fish to fry
68 * at present.
69 *
70 * Derived from: $NetBSD: svr4_ipc.c,v 1.7 1998/10/19 22:43:00 tron Exp $
71 */
72
73 #include <sys/cdefs.h>
74 __FBSDID("$FreeBSD: releng/6.3/sys/compat/svr4/svr4_ipc.c 147817 2005-07-07 19:25:47Z jhb $");
75
76 #include "opt_sysvipc.h"
77
78 #include <sys/param.h>
79 #include <sys/ipc.h>
80 #include <sys/msg.h>
81 #include <sys/proc.h>
82 #include <sys/sem.h>
83 #include <sys/shm.h>
84 #include <sys/syscallsubr.h>
85 #include <sys/sysproto.h>
86 #include <sys/systm.h>
87 #include <sys/time.h>
88
89 #include <compat/svr4/svr4.h>
90 #include <compat/svr4/svr4_types.h>
91 #include <compat/svr4/svr4_signal.h>
92 #include <compat/svr4/svr4_proto.h>
93 #include <compat/svr4/svr4_util.h>
94 #include <compat/svr4/svr4_ipc.h>
95
96 #if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
97 static void svr4_to_bsd_ipc_perm(const struct svr4_ipc_perm *,
98 struct ipc_perm *);
99 static void bsd_to_svr4_ipc_perm(const struct ipc_perm *,
100 struct svr4_ipc_perm *);
101 #endif
102
103 #ifdef SYSVSEM
104 static void bsd_to_svr4_semid_ds(const struct semid_ds *,
105 struct svr4_semid_ds *);
106 static void svr4_to_bsd_semid_ds(const struct svr4_semid_ds *,
107 struct semid_ds *);
108 static int svr4_setsemun(caddr_t *sgp, union semun **argp,
109 union semun *usp);
110 static int svr4_semop(struct thread *, void *);
111 static int svr4_semget(struct thread *, void *);
112 static int svr4_semctl(struct thread *, void *);
113 #endif
114
115 #ifdef SYSVMSG
116 static void bsd_to_svr4_msqid_ds(const struct msqid_ds *,
117 struct svr4_msqid_ds *);
118 static void svr4_to_bsd_msqid_ds(const struct svr4_msqid_ds *,
119 struct msqid_ds *);
120 static int svr4_msgsnd(struct thread *, void *);
121 static int svr4_msgrcv(struct thread *, void *);
122 static int svr4_msgget(struct thread *, void *);
123 static int svr4_msgctl(struct thread *, void *);
124 #endif
125
126 #ifdef SYSVSHM
127 static void bsd_to_svr4_shmid_ds(const struct shmid_ds *,
128 struct svr4_shmid_ds *);
129 static void svr4_to_bsd_shmid_ds(const struct svr4_shmid_ds *,
130 struct shmid_ds *);
131 static int svr4_shmat(struct thread *, void *);
132 static int svr4_shmdt(struct thread *, void *);
133 static int svr4_shmget(struct thread *, void *);
134 static int svr4_shmctl(struct thread *, void *);
135 #endif
136
137 #if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
138
139 static void
140 svr4_to_bsd_ipc_perm(spp, bpp)
141 const struct svr4_ipc_perm *spp;
142 struct ipc_perm *bpp;
143 {
144 bpp->key = spp->key;
145 bpp->uid = spp->uid;
146 bpp->gid = spp->gid;
147 bpp->cuid = spp->cuid;
148 bpp->cgid = spp->cgid;
149 bpp->mode = spp->mode;
150 bpp->seq = spp->seq;
151 }
152
153 static void
154 bsd_to_svr4_ipc_perm(bpp, spp)
155 const struct ipc_perm *bpp;
156 struct svr4_ipc_perm *spp;
157 {
158 spp->key = bpp->key;
159 spp->uid = bpp->uid;
160 spp->gid = bpp->gid;
161 spp->cuid = bpp->cuid;
162 spp->cgid = bpp->cgid;
163 spp->mode = bpp->mode;
164 spp->seq = bpp->seq;
165 }
166 #endif
167
168 #ifdef SYSVSEM
169 static void
170 bsd_to_svr4_semid_ds(bds, sds)
171 const struct semid_ds *bds;
172 struct svr4_semid_ds *sds;
173 {
174 bsd_to_svr4_ipc_perm(&bds->sem_perm, &sds->sem_perm);
175 sds->sem_base = (struct svr4_sem *) bds->sem_base;
176 sds->sem_nsems = bds->sem_nsems;
177 sds->sem_otime = bds->sem_otime;
178 sds->sem_pad1 = bds->sem_pad1;
179 sds->sem_ctime = bds->sem_ctime;
180 sds->sem_pad2 = bds->sem_pad2;
181 }
182
183 static void
184 svr4_to_bsd_semid_ds(sds, bds)
185 const struct svr4_semid_ds *sds;
186 struct semid_ds *bds;
187 {
188 svr4_to_bsd_ipc_perm(&sds->sem_perm, &bds->sem_perm);
189 bds->sem_base = (struct sem *) bds->sem_base;
190 bds->sem_nsems = sds->sem_nsems;
191 bds->sem_otime = sds->sem_otime;
192 bds->sem_pad1 = sds->sem_pad1;
193 bds->sem_ctime = sds->sem_ctime;
194 bds->sem_pad2 = sds->sem_pad2;
195 }
196
197 static int
198 svr4_setsemun(sgp, argp, usp)
199 caddr_t *sgp;
200 union semun **argp;
201 union semun *usp;
202 {
203 *argp = stackgap_alloc(sgp, sizeof(union semun));
204 return copyout((caddr_t)usp, *argp, sizeof(union semun));
205 }
206
207 struct svr4_sys_semctl_args {
208 int what;
209 int semid;
210 int semnum;
211 int cmd;
212 union semun arg;
213 };
214
215 static int
216 svr4_semctl(td, v)
217 struct thread *td;
218 void *v;
219 {
220 int error;
221 struct svr4_sys_semctl_args *uap = v;
222 struct __semctl_args ap;
223 struct svr4_semid_ds ss;
224 struct semid_ds bs, *bsp;
225 caddr_t sg = stackgap_init();
226
227 ap.semid = uap->semid;
228 ap.semnum = uap->semnum;
229
230 switch (uap->cmd) {
231 case SVR4_SEM_GETZCNT:
232 case SVR4_SEM_GETNCNT:
233 case SVR4_SEM_GETPID:
234 case SVR4_SEM_GETVAL:
235 switch (uap->cmd) {
236 case SVR4_SEM_GETZCNT:
237 ap.cmd = GETZCNT;
238 break;
239 case SVR4_SEM_GETNCNT:
240 ap.cmd = GETNCNT;
241 break;
242 case SVR4_SEM_GETPID:
243 ap.cmd = GETPID;
244 break;
245 case SVR4_SEM_GETVAL:
246 ap.cmd = GETVAL;
247 break;
248 }
249 return __semctl(td, &ap);
250
251 case SVR4_SEM_SETVAL:
252 error = svr4_setsemun(&sg, &ap.arg, &uap->arg);
253 if (error)
254 return error;
255 ap.cmd = SETVAL;
256 return __semctl(td, &ap);
257
258 case SVR4_SEM_GETALL:
259 error = svr4_setsemun(&sg, &ap.arg, &uap->arg);
260 if (error)
261 return error;
262 ap.cmd = GETVAL;
263 return __semctl(td, &ap);
264
265 case SVR4_SEM_SETALL:
266 error = svr4_setsemun(&sg, &ap.arg, &uap->arg);
267 if (error)
268 return error;
269 ap.cmd = SETVAL;
270 return __semctl(td, &ap);
271
272 case SVR4_IPC_STAT:
273 ap.cmd = IPC_STAT;
274 bsp = stackgap_alloc(&sg, sizeof(bs));
275 error = svr4_setsemun(&sg, &ap.arg,
276 (union semun *)&bsp);
277 if (error)
278 return error;
279 if ((error = __semctl(td, &ap)) != 0)
280 return error;
281 error = copyin((caddr_t)bsp, (caddr_t)&bs, sizeof(bs));
282 if (error)
283 return error;
284 bsd_to_svr4_semid_ds(&bs, &ss);
285 return copyout(&ss, uap->arg.buf, sizeof(ss));
286
287 case SVR4_IPC_SET:
288 ap.cmd = IPC_SET;
289 bsp = stackgap_alloc(&sg, sizeof(bs));
290 error = svr4_setsemun(&sg, &ap.arg,
291 (union semun *)&bsp);
292 if (error)
293 return error;
294 error = copyin(uap->arg.buf, (caddr_t) &ss, sizeof ss);
295 if (error)
296 return error;
297 svr4_to_bsd_semid_ds(&ss, &bs);
298 error = copyout(&bs, bsp, sizeof(bs));
299 if (error)
300 return error;
301 return __semctl(td, &ap);
302
303 case SVR4_IPC_RMID:
304 ap.cmd = IPC_RMID;
305 bsp = stackgap_alloc(&sg, sizeof(bs));
306 error = svr4_setsemun(&sg, &ap.arg,
307 (union semun *)&bsp);
308 if (error)
309 return error;
310 error = copyin(uap->arg.buf, &ss, sizeof ss);
311 if (error)
312 return error;
313 svr4_to_bsd_semid_ds(&ss, &bs);
314 error = copyout(&bs, bsp, sizeof(bs));
315 if (error)
316 return error;
317 return __semctl(td, &ap);
318
319 default:
320 return EINVAL;
321 }
322 }
323
324 struct svr4_sys_semget_args {
325 int what;
326 svr4_key_t key;
327 int nsems;
328 int semflg;
329 };
330
331 static int
332 svr4_semget(td, v)
333 struct thread *td;
334 void *v;
335 {
336 struct svr4_sys_semget_args *uap = v;
337 struct semget_args ap;
338
339 ap.key = uap->key;
340 ap.nsems = uap->nsems;
341 ap.semflg = uap->semflg;
342
343 return semget(td, &ap);
344 }
345
346 struct svr4_sys_semop_args {
347 int what;
348 int semid;
349 struct svr4_sembuf * sops;
350 u_int nsops;
351 };
352
353 static int
354 svr4_semop(td, v)
355 struct thread *td;
356 void *v;
357 {
358 struct svr4_sys_semop_args *uap = v;
359 struct semop_args ap;
360
361 ap.semid = uap->semid;
362 /* These are the same */
363 ap.sops = (struct sembuf *) uap->sops;
364 ap.nsops = uap->nsops;
365
366 return semop(td, &ap);
367 }
368
369 int
370 svr4_sys_semsys(td, uap)
371 struct thread *td;
372 struct svr4_sys_semsys_args *uap;
373 {
374
375 DPRINTF(("svr4_semsys(%d)\n", uap->what));
376
377 switch (uap->what) {
378 case SVR4_semctl:
379 return svr4_semctl(td, uap);
380 case SVR4_semget:
381 return svr4_semget(td, uap);
382 case SVR4_semop:
383 return svr4_semop(td, uap);
384 default:
385 return EINVAL;
386 }
387 }
388 #endif
389
390 #ifdef SYSVMSG
391 static void
392 bsd_to_svr4_msqid_ds(bds, sds)
393 const struct msqid_ds *bds;
394 struct svr4_msqid_ds *sds;
395 {
396 bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm);
397 sds->msg_first = (struct svr4_msg *) bds->msg_first;
398 sds->msg_last = (struct svr4_msg *) bds->msg_last;
399 sds->msg_cbytes = bds->msg_cbytes;
400 sds->msg_qnum = bds->msg_qnum;
401 sds->msg_qbytes = bds->msg_qbytes;
402 sds->msg_lspid = bds->msg_lspid;
403 sds->msg_lrpid = bds->msg_lrpid;
404 sds->msg_stime = bds->msg_stime;
405 sds->msg_pad1 = bds->msg_pad1;
406 sds->msg_rtime = bds->msg_rtime;
407 sds->msg_pad2 = bds->msg_pad2;
408 sds->msg_ctime = bds->msg_ctime;
409 sds->msg_pad3 = bds->msg_pad3;
410
411 /* use the padding for the rest of the fields */
412 {
413 const short *pad = (const short *) bds->msg_pad4;
414 sds->msg_cv = pad[0];
415 sds->msg_qnum_cv = pad[1];
416 }
417 }
418
419 static void
420 svr4_to_bsd_msqid_ds(sds, bds)
421 const struct svr4_msqid_ds *sds;
422 struct msqid_ds *bds;
423 {
424 svr4_to_bsd_ipc_perm(&sds->msg_perm, &bds->msg_perm);
425 bds->msg_first = (struct msg *) sds->msg_first;
426 bds->msg_last = (struct msg *) sds->msg_last;
427 bds->msg_cbytes = sds->msg_cbytes;
428 bds->msg_qnum = sds->msg_qnum;
429 bds->msg_qbytes = sds->msg_qbytes;
430 bds->msg_lspid = sds->msg_lspid;
431 bds->msg_lrpid = sds->msg_lrpid;
432 bds->msg_stime = sds->msg_stime;
433 bds->msg_pad1 = sds->msg_pad1;
434 bds->msg_rtime = sds->msg_rtime;
435 bds->msg_pad2 = sds->msg_pad2;
436 bds->msg_ctime = sds->msg_ctime;
437 bds->msg_pad3 = sds->msg_pad3;
438
439 /* use the padding for the rest of the fields */
440 {
441 short *pad = (short *) bds->msg_pad4;
442 pad[0] = sds->msg_cv;
443 pad[1] = sds->msg_qnum_cv;
444 }
445 }
446
447 struct svr4_sys_msgsnd_args {
448 int what;
449 int msqid;
450 void * msgp;
451 size_t msgsz;
452 int msgflg;
453 };
454
455 static int
456 svr4_msgsnd(td, v)
457 struct thread *td;
458 void *v;
459 {
460 struct svr4_sys_msgsnd_args *uap = v;
461 struct msgsnd_args ap;
462
463 ap.msqid = uap->msqid;
464 ap.msgp = uap->msgp;
465 ap.msgsz = uap->msgsz;
466 ap.msgflg = uap->msgflg;
467
468 return msgsnd(td, &ap);
469 }
470
471 struct svr4_sys_msgrcv_args {
472 int what;
473 int msqid;
474 void * msgp;
475 size_t msgsz;
476 long msgtyp;
477 int msgflg;
478 };
479
480 static int
481 svr4_msgrcv(td, v)
482 struct thread *td;
483 void *v;
484 {
485 struct svr4_sys_msgrcv_args *uap = v;
486 struct msgrcv_args ap;
487
488 ap.msqid = uap->msqid;
489 ap.msgp = uap->msgp;
490 ap.msgsz = uap->msgsz;
491 ap.msgtyp = uap->msgtyp;
492 ap.msgflg = uap->msgflg;
493
494 return msgrcv(td, &ap);
495 }
496
497 struct svr4_sys_msgget_args {
498 int what;
499 svr4_key_t key;
500 int msgflg;
501 };
502
503 static int
504 svr4_msgget(td, v)
505 struct thread *td;
506 void *v;
507 {
508 struct svr4_sys_msgget_args *uap = v;
509 struct msgget_args ap;
510
511 ap.key = uap->key;
512 ap.msgflg = uap->msgflg;
513
514 return msgget(td, &ap);
515 }
516
517 struct svr4_sys_msgctl_args {
518 int what;
519 int msqid;
520 int cmd;
521 struct svr4_msqid_ds * buf;
522 };
523
524 static int
525 svr4_msgctl(td, v)
526 struct thread *td;
527 void *v;
528 {
529 struct svr4_sys_msgctl_args *uap = v;
530 struct svr4_msqid_ds ss;
531 struct msqid_ds bs;
532 int error;
533
534 switch (uap->cmd) {
535 case SVR4_IPC_STAT:
536 error = kern_msgctl(td, uap->msqid, IPC_STAT, &bs);
537 if (error)
538 return error;
539 bsd_to_svr4_msqid_ds(&bs, &ss);
540 return copyout(&ss, uap->buf, sizeof ss);
541
542 case SVR4_IPC_SET:
543 error = copyin(uap->buf, &ss, sizeof ss);
544 if (error)
545 return error;
546 svr4_to_bsd_msqid_ds(&ss, &bs);
547 return (kern_msgctl(td, uap->msqid, IPC_SET, &bs));
548
549 case SVR4_IPC_RMID:
550 error = copyin(uap->buf, &ss, sizeof ss);
551 if (error)
552 return error;
553 svr4_to_bsd_msqid_ds(&ss, &bs);
554 return (kern_msgctl(td, uap->msqid, IPC_RMID, &bs));
555
556 default:
557 return EINVAL;
558 }
559 }
560
561 int
562 svr4_sys_msgsys(td, uap)
563 struct thread *td;
564 struct svr4_sys_msgsys_args *uap;
565 {
566
567 DPRINTF(("svr4_msgsys(%d)\n", uap->what));
568
569 switch (uap->what) {
570 case SVR4_msgsnd:
571 return svr4_msgsnd(td, uap);
572 case SVR4_msgrcv:
573 return svr4_msgrcv(td, uap);
574 case SVR4_msgget:
575 return svr4_msgget(td, uap);
576 case SVR4_msgctl:
577 return svr4_msgctl(td, uap);
578 default:
579 return EINVAL;
580 }
581 }
582 #endif
583
584 #ifdef SYSVSHM
585
586 static void
587 bsd_to_svr4_shmid_ds(bds, sds)
588 const struct shmid_ds *bds;
589 struct svr4_shmid_ds *sds;
590 {
591 bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm);
592 sds->shm_segsz = bds->shm_segsz;
593 sds->shm_lkcnt = 0;
594 sds->shm_lpid = bds->shm_lpid;
595 sds->shm_cpid = bds->shm_cpid;
596 sds->shm_amp = bds->shm_internal;
597 sds->shm_nattch = bds->shm_nattch;
598 sds->shm_cnattch = 0;
599 sds->shm_atime = bds->shm_atime;
600 sds->shm_pad1 = 0;
601 sds->shm_dtime = bds->shm_dtime;
602 sds->shm_pad2 = 0;
603 sds->shm_ctime = bds->shm_ctime;
604 sds->shm_pad3 = 0;
605 }
606
607 static void
608 svr4_to_bsd_shmid_ds(sds, bds)
609 const struct svr4_shmid_ds *sds;
610 struct shmid_ds *bds;
611 {
612 svr4_to_bsd_ipc_perm(&sds->shm_perm, &bds->shm_perm);
613 bds->shm_segsz = sds->shm_segsz;
614 bds->shm_lpid = sds->shm_lpid;
615 bds->shm_cpid = sds->shm_cpid;
616 bds->shm_internal = sds->shm_amp;
617 bds->shm_nattch = sds->shm_nattch;
618 bds->shm_atime = sds->shm_atime;
619 bds->shm_dtime = sds->shm_dtime;
620 bds->shm_ctime = sds->shm_ctime;
621 }
622
623 struct svr4_sys_shmat_args {
624 int what;
625 int shmid;
626 void * shmaddr;
627 int shmflg;
628 };
629
630 static int
631 svr4_shmat(td, v)
632 struct thread *td;
633 void *v;
634 {
635 struct svr4_sys_shmat_args *uap = v;
636 struct shmat_args ap;
637
638 ap.shmid = uap->shmid;
639 ap.shmaddr = uap->shmaddr;
640 ap.shmflg = uap->shmflg;
641
642 return shmat(td, &ap);
643 }
644
645 struct svr4_sys_shmdt_args {
646 int what;
647 void * shmaddr;
648 };
649
650 static int
651 svr4_shmdt(td, v)
652 struct thread *td;
653 void *v;
654 {
655 struct svr4_sys_shmdt_args *uap = v;
656 struct shmdt_args ap;
657
658 ap.shmaddr = uap->shmaddr;
659
660 return shmdt(td, &ap);
661 }
662
663 struct svr4_sys_shmget_args {
664 int what;
665 key_t key;
666 int size;
667 int shmflg;
668 };
669
670 static int
671 svr4_shmget(td, v)
672 struct thread *td;
673 void *v;
674 {
675 struct svr4_sys_shmget_args *uap = v;
676 struct shmget_args ap;
677
678 ap.key = uap->key;
679 ap.size = uap->size;
680 ap.shmflg = uap->shmflg;
681
682 return shmget(td, &ap);
683 }
684
685 struct svr4_sys_shmctl_args {
686 int what;
687 int shmid;
688 int cmd;
689 struct svr4_shmid_ds * buf;
690 };
691
692 int
693 svr4_shmctl(td, v)
694 struct thread *td;
695 void *v;
696 {
697 struct svr4_sys_shmctl_args *uap = v;
698 int error;
699 caddr_t sg = stackgap_init();
700 struct shmctl_args ap;
701 struct shmid_ds bs;
702 struct svr4_shmid_ds ss;
703
704 ap.shmid = uap->shmid;
705
706 if (uap->buf != NULL) {
707 ap.buf = stackgap_alloc(&sg, sizeof (struct shmid_ds));
708 switch (uap->cmd) {
709 case SVR4_IPC_SET:
710 case SVR4_IPC_RMID:
711 case SVR4_SHM_LOCK:
712 case SVR4_SHM_UNLOCK:
713 error = copyin(uap->buf, (caddr_t) &ss,
714 sizeof ss);
715 if (error)
716 return error;
717 svr4_to_bsd_shmid_ds(&ss, &bs);
718 error = copyout(&bs, ap.buf, sizeof bs);
719 if (error)
720 return error;
721 break;
722 default:
723 break;
724 }
725 }
726 else
727 ap.buf = NULL;
728
729
730 switch (uap->cmd) {
731 case SVR4_IPC_STAT:
732 ap.cmd = IPC_STAT;
733 if ((error = shmctl(td, &ap)) != 0)
734 return error;
735 if (uap->buf == NULL)
736 return 0;
737 error = copyin(&bs, ap.buf, sizeof bs);
738 if (error)
739 return error;
740 bsd_to_svr4_shmid_ds(&bs, &ss);
741 return copyout(&ss, uap->buf, sizeof ss);
742
743 case SVR4_IPC_SET:
744 ap.cmd = IPC_SET;
745 return shmctl(td, &ap);
746
747 case SVR4_IPC_RMID:
748 case SVR4_SHM_LOCK:
749 case SVR4_SHM_UNLOCK:
750 switch (uap->cmd) {
751 case SVR4_IPC_RMID:
752 ap.cmd = IPC_RMID;
753 break;
754 case SVR4_SHM_LOCK:
755 ap.cmd = SHM_LOCK;
756 break;
757 case SVR4_SHM_UNLOCK:
758 ap.cmd = SHM_UNLOCK;
759 break;
760 default:
761 return EINVAL;
762 }
763 return shmctl(td, &ap);
764
765 default:
766 return EINVAL;
767 }
768 }
769
770 int
771 svr4_sys_shmsys(td, uap)
772 struct thread *td;
773 struct svr4_sys_shmsys_args *uap;
774 {
775
776 DPRINTF(("svr4_shmsys(%d)\n", uap->what));
777
778 switch (uap->what) {
779 case SVR4_shmat:
780 return svr4_shmat(td, uap);
781 case SVR4_shmdt:
782 return svr4_shmdt(td, uap);
783 case SVR4_shmget:
784 return svr4_shmget(td, uap);
785 case SVR4_shmctl:
786 return svr4_shmctl(td, uap);
787 default:
788 return ENOSYS;
789 }
790 }
791 #endif /* SYSVSHM */
Cache object: db2f79d93e13aa50d490edc13c58cafe
|