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