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