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/7.4/sys/compat/svr4/svr4_ipc.c 196006 2009-07-31 20:32:55Z 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_semop(struct thread *, void *);
109 static int svr4_semget(struct thread *, void *);
110 static int svr4_semctl(struct thread *, void *);
111 #endif
112
113 #ifdef SYSVMSG
114 static void bsd_to_svr4_msqid_ds(const struct msqid_ds *,
115 struct svr4_msqid_ds *);
116 static void svr4_to_bsd_msqid_ds(const struct svr4_msqid_ds *,
117 struct msqid_ds *);
118 static int svr4_msgsnd(struct thread *, void *);
119 static int svr4_msgrcv(struct thread *, void *);
120 static int svr4_msgget(struct thread *, void *);
121 static int svr4_msgctl(struct thread *, void *);
122 #endif
123
124 #ifdef SYSVSHM
125 static void bsd_to_svr4_shmid_ds(const struct shmid_ds *,
126 struct svr4_shmid_ds *);
127 static void svr4_to_bsd_shmid_ds(const struct svr4_shmid_ds *,
128 struct shmid_ds *);
129 static int svr4_shmat(struct thread *, void *);
130 static int svr4_shmdt(struct thread *, void *);
131 static int svr4_shmget(struct thread *, void *);
132 static int svr4_shmctl(struct thread *, void *);
133 #endif
134
135 #if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
136
137 static void
138 svr4_to_bsd_ipc_perm(spp, bpp)
139 const struct svr4_ipc_perm *spp;
140 struct ipc_perm *bpp;
141 {
142 bpp->key = spp->key;
143 bpp->uid = spp->uid;
144 bpp->gid = spp->gid;
145 bpp->cuid = spp->cuid;
146 bpp->cgid = spp->cgid;
147 bpp->mode = spp->mode;
148 bpp->seq = spp->seq;
149 }
150
151 static void
152 bsd_to_svr4_ipc_perm(bpp, spp)
153 const struct ipc_perm *bpp;
154 struct svr4_ipc_perm *spp;
155 {
156 spp->key = bpp->key;
157 spp->uid = bpp->uid;
158 spp->gid = bpp->gid;
159 spp->cuid = bpp->cuid;
160 spp->cgid = bpp->cgid;
161 spp->mode = bpp->mode;
162 spp->seq = bpp->seq;
163 }
164 #endif
165
166 #ifdef SYSVSEM
167 static void
168 bsd_to_svr4_semid_ds(bds, sds)
169 const struct semid_ds *bds;
170 struct svr4_semid_ds *sds;
171 {
172 bzero(sds, sizeof(*sds));
173 bsd_to_svr4_ipc_perm(&bds->sem_perm, &sds->sem_perm);
174 sds->sem_base = (struct svr4_sem *) bds->sem_base;
175 sds->sem_nsems = bds->sem_nsems;
176 sds->sem_otime = bds->sem_otime;
177 sds->sem_ctime = bds->sem_ctime;
178 }
179
180 static void
181 svr4_to_bsd_semid_ds(sds, bds)
182 const struct svr4_semid_ds *sds;
183 struct semid_ds *bds;
184 {
185 svr4_to_bsd_ipc_perm(&sds->sem_perm, &bds->sem_perm);
186 bds->sem_base = (struct sem *) bds->sem_base;
187 bds->sem_nsems = sds->sem_nsems;
188 bds->sem_otime = sds->sem_otime;
189 bds->sem_ctime = sds->sem_ctime;
190 }
191
192 struct svr4_sys_semctl_args {
193 int what;
194 int semid;
195 int semnum;
196 int cmd;
197 union semun arg;
198 };
199
200 static int
201 svr4_semctl(td, v)
202 struct thread *td;
203 void *v;
204 {
205 struct svr4_sys_semctl_args *uap = v;
206 struct svr4_semid_ds ss;
207 struct semid_ds bs;
208 union semun semun;
209 register_t rval;
210 int cmd, error;
211
212 switch (uap->cmd) {
213 case SVR4_SEM_GETZCNT:
214 cmd = GETZCNT;
215 break;
216
217 case SVR4_SEM_GETNCNT:
218 cmd = GETNCNT;
219 break;
220
221 case SVR4_SEM_GETPID:
222 cmd = GETPID;
223 break;
224
225 case SVR4_SEM_GETVAL:
226 cmd = GETVAL;
227 break;
228
229 case SVR4_SEM_SETVAL:
230 cmd = SETVAL;
231 break;
232
233 case SVR4_SEM_GETALL:
234 cmd = GETVAL;
235 break;
236
237 case SVR4_SEM_SETALL:
238 cmd = SETVAL;
239 break;
240
241 case SVR4_IPC_STAT:
242 cmd = IPC_STAT;
243 semun.buf = &bs;
244 error = kern_semctl(td, uap->semid, uap->semnum, cmd, &semun,
245 &rval);
246 if (error)
247 return (error);
248 bsd_to_svr4_semid_ds(&bs, &ss);
249 error = copyout(&ss, uap->arg.buf, sizeof(ss));
250 if (error == 0)
251 td->td_retval[0] = rval;
252 return (error);
253
254 case SVR4_IPC_SET:
255 cmd = IPC_SET;
256 error = copyin(uap->arg.buf, (caddr_t) &ss, sizeof ss);
257 if (error)
258 return (error);
259 svr4_to_bsd_semid_ds(&ss, &bs);
260 semun.buf = &bs;
261 return (kern_semctl(td, uap->semid, uap->semnum, cmd, &semun,
262 td->td_retval));
263
264 case SVR4_IPC_RMID:
265 cmd = IPC_RMID;
266 break;
267
268 default:
269 return EINVAL;
270 }
271
272 return (kern_semctl(td, uap->semid, uap->semnum, cmd, &uap->arg,
273 td->td_retval));
274 }
275
276 struct svr4_sys_semget_args {
277 int what;
278 svr4_key_t key;
279 int nsems;
280 int semflg;
281 };
282
283 static int
284 svr4_semget(td, v)
285 struct thread *td;
286 void *v;
287 {
288 struct svr4_sys_semget_args *uap = v;
289 struct semget_args ap;
290
291 ap.key = uap->key;
292 ap.nsems = uap->nsems;
293 ap.semflg = uap->semflg;
294
295 return semget(td, &ap);
296 }
297
298 struct svr4_sys_semop_args {
299 int what;
300 int semid;
301 struct svr4_sembuf * sops;
302 u_int nsops;
303 };
304
305 static int
306 svr4_semop(td, v)
307 struct thread *td;
308 void *v;
309 {
310 struct svr4_sys_semop_args *uap = v;
311 struct semop_args ap;
312
313 ap.semid = uap->semid;
314 /* These are the same */
315 ap.sops = (struct sembuf *) uap->sops;
316 ap.nsops = uap->nsops;
317
318 return semop(td, &ap);
319 }
320
321 int
322 svr4_sys_semsys(td, uap)
323 struct thread *td;
324 struct svr4_sys_semsys_args *uap;
325 {
326
327 DPRINTF(("svr4_semsys(%d)\n", uap->what));
328
329 switch (uap->what) {
330 case SVR4_semctl:
331 return svr4_semctl(td, uap);
332 case SVR4_semget:
333 return svr4_semget(td, uap);
334 case SVR4_semop:
335 return svr4_semop(td, uap);
336 default:
337 return EINVAL;
338 }
339 }
340
341 MODULE_DEPEND(svr4elf, sysvsem, 1, 1, 1);
342 #endif
343
344 #ifdef SYSVMSG
345 static void
346 bsd_to_svr4_msqid_ds(bds, sds)
347 const struct msqid_ds *bds;
348 struct svr4_msqid_ds *sds;
349 {
350 bzero(sds, sizeof(*sds));
351 bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm);
352 sds->msg_first = (struct svr4_msg *) bds->msg_first;
353 sds->msg_last = (struct svr4_msg *) bds->msg_last;
354 sds->msg_cbytes = bds->msg_cbytes;
355 sds->msg_qnum = bds->msg_qnum;
356 sds->msg_qbytes = bds->msg_qbytes;
357 sds->msg_lspid = bds->msg_lspid;
358 sds->msg_lrpid = bds->msg_lrpid;
359 sds->msg_stime = bds->msg_stime;
360 sds->msg_rtime = bds->msg_rtime;
361 sds->msg_ctime = bds->msg_ctime;
362 }
363
364 static void
365 svr4_to_bsd_msqid_ds(sds, bds)
366 const struct svr4_msqid_ds *sds;
367 struct msqid_ds *bds;
368 {
369 svr4_to_bsd_ipc_perm(&sds->msg_perm, &bds->msg_perm);
370 bds->msg_first = (struct msg *) sds->msg_first;
371 bds->msg_last = (struct msg *) sds->msg_last;
372 bds->msg_cbytes = sds->msg_cbytes;
373 bds->msg_qnum = sds->msg_qnum;
374 bds->msg_qbytes = sds->msg_qbytes;
375 bds->msg_lspid = sds->msg_lspid;
376 bds->msg_lrpid = sds->msg_lrpid;
377 bds->msg_stime = sds->msg_stime;
378 bds->msg_rtime = sds->msg_rtime;
379 bds->msg_ctime = sds->msg_ctime;
380 }
381
382 struct svr4_sys_msgsnd_args {
383 int what;
384 int msqid;
385 void * msgp;
386 size_t msgsz;
387 int msgflg;
388 };
389
390 static int
391 svr4_msgsnd(td, v)
392 struct thread *td;
393 void *v;
394 {
395 struct svr4_sys_msgsnd_args *uap = v;
396 struct msgsnd_args ap;
397
398 ap.msqid = uap->msqid;
399 ap.msgp = uap->msgp;
400 ap.msgsz = uap->msgsz;
401 ap.msgflg = uap->msgflg;
402
403 return msgsnd(td, &ap);
404 }
405
406 struct svr4_sys_msgrcv_args {
407 int what;
408 int msqid;
409 void * msgp;
410 size_t msgsz;
411 long msgtyp;
412 int msgflg;
413 };
414
415 static int
416 svr4_msgrcv(td, v)
417 struct thread *td;
418 void *v;
419 {
420 struct svr4_sys_msgrcv_args *uap = v;
421 struct msgrcv_args ap;
422
423 ap.msqid = uap->msqid;
424 ap.msgp = uap->msgp;
425 ap.msgsz = uap->msgsz;
426 ap.msgtyp = uap->msgtyp;
427 ap.msgflg = uap->msgflg;
428
429 return msgrcv(td, &ap);
430 }
431
432 struct svr4_sys_msgget_args {
433 int what;
434 svr4_key_t key;
435 int msgflg;
436 };
437
438 static int
439 svr4_msgget(td, v)
440 struct thread *td;
441 void *v;
442 {
443 struct svr4_sys_msgget_args *uap = v;
444 struct msgget_args ap;
445
446 ap.key = uap->key;
447 ap.msgflg = uap->msgflg;
448
449 return msgget(td, &ap);
450 }
451
452 struct svr4_sys_msgctl_args {
453 int what;
454 int msqid;
455 int cmd;
456 struct svr4_msqid_ds * buf;
457 };
458
459 static int
460 svr4_msgctl(td, v)
461 struct thread *td;
462 void *v;
463 {
464 struct svr4_sys_msgctl_args *uap = v;
465 struct svr4_msqid_ds ss;
466 struct msqid_ds bs;
467 int error;
468
469 switch (uap->cmd) {
470 case SVR4_IPC_STAT:
471 error = kern_msgctl(td, uap->msqid, IPC_STAT, &bs);
472 if (error)
473 return error;
474 bsd_to_svr4_msqid_ds(&bs, &ss);
475 return copyout(&ss, uap->buf, sizeof ss);
476
477 case SVR4_IPC_SET:
478 error = copyin(uap->buf, &ss, sizeof ss);
479 if (error)
480 return error;
481 svr4_to_bsd_msqid_ds(&ss, &bs);
482 return (kern_msgctl(td, uap->msqid, IPC_SET, &bs));
483
484 case SVR4_IPC_RMID:
485 return (kern_msgctl(td, uap->msqid, IPC_RMID, NULL));
486
487 default:
488 return EINVAL;
489 }
490 }
491
492 int
493 svr4_sys_msgsys(td, uap)
494 struct thread *td;
495 struct svr4_sys_msgsys_args *uap;
496 {
497
498 DPRINTF(("svr4_msgsys(%d)\n", uap->what));
499
500 switch (uap->what) {
501 case SVR4_msgsnd:
502 return svr4_msgsnd(td, uap);
503 case SVR4_msgrcv:
504 return svr4_msgrcv(td, uap);
505 case SVR4_msgget:
506 return svr4_msgget(td, uap);
507 case SVR4_msgctl:
508 return svr4_msgctl(td, uap);
509 default:
510 return EINVAL;
511 }
512 }
513
514 MODULE_DEPEND(svr4elf, sysvmsg, 1, 1, 1);
515 #endif
516
517 #ifdef SYSVSHM
518
519 static void
520 bsd_to_svr4_shmid_ds(bds, sds)
521 const struct shmid_ds *bds;
522 struct svr4_shmid_ds *sds;
523 {
524 bzero(sds, sizeof(*sds));
525 bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm);
526 sds->shm_segsz = bds->shm_segsz;
527 sds->shm_lkcnt = 0;
528 sds->shm_lpid = bds->shm_lpid;
529 sds->shm_cpid = bds->shm_cpid;
530 sds->shm_amp = 0;
531 sds->shm_nattch = bds->shm_nattch;
532 sds->shm_cnattch = 0;
533 sds->shm_atime = bds->shm_atime;
534 sds->shm_dtime = bds->shm_dtime;
535 sds->shm_ctime = bds->shm_ctime;
536 }
537
538 static void
539 svr4_to_bsd_shmid_ds(sds, bds)
540 const struct svr4_shmid_ds *sds;
541 struct shmid_ds *bds;
542 {
543 svr4_to_bsd_ipc_perm(&sds->shm_perm, &bds->shm_perm);
544 bds->shm_segsz = sds->shm_segsz;
545 bds->shm_lpid = sds->shm_lpid;
546 bds->shm_cpid = sds->shm_cpid;
547 bds->shm_nattch = sds->shm_nattch;
548 bds->shm_atime = sds->shm_atime;
549 bds->shm_dtime = sds->shm_dtime;
550 bds->shm_ctime = sds->shm_ctime;
551 }
552
553 struct svr4_sys_shmat_args {
554 int what;
555 int shmid;
556 void * shmaddr;
557 int shmflg;
558 };
559
560 static int
561 svr4_shmat(td, v)
562 struct thread *td;
563 void *v;
564 {
565 struct svr4_sys_shmat_args *uap = v;
566 struct shmat_args ap;
567
568 ap.shmid = uap->shmid;
569 ap.shmaddr = uap->shmaddr;
570 ap.shmflg = uap->shmflg;
571
572 return shmat(td, &ap);
573 }
574
575 struct svr4_sys_shmdt_args {
576 int what;
577 void * shmaddr;
578 };
579
580 static int
581 svr4_shmdt(td, v)
582 struct thread *td;
583 void *v;
584 {
585 struct svr4_sys_shmdt_args *uap = v;
586 struct shmdt_args ap;
587
588 ap.shmaddr = uap->shmaddr;
589
590 return shmdt(td, &ap);
591 }
592
593 struct svr4_sys_shmget_args {
594 int what;
595 key_t key;
596 int size;
597 int shmflg;
598 };
599
600 static int
601 svr4_shmget(td, v)
602 struct thread *td;
603 void *v;
604 {
605 struct svr4_sys_shmget_args *uap = v;
606 struct shmget_args ap;
607
608 ap.key = uap->key;
609 ap.size = uap->size;
610 ap.shmflg = uap->shmflg;
611
612 return shmget(td, &ap);
613 }
614
615 struct svr4_sys_shmctl_args {
616 int what;
617 int shmid;
618 int cmd;
619 struct svr4_shmid_ds * buf;
620 };
621
622 int
623 svr4_shmctl(td, v)
624 struct thread *td;
625 void *v;
626 {
627 struct svr4_sys_shmctl_args *uap = v;
628 struct shmid_ds bs;
629 struct svr4_shmid_ds ss;
630 size_t bufsize;
631 int cmd, error;
632
633 if (uap->buf != NULL) {
634 switch (uap->cmd) {
635 case SVR4_IPC_SET:
636 case SVR4_SHM_LOCK:
637 case SVR4_SHM_UNLOCK:
638 error = copyin(uap->buf, &ss, sizeof(ss));
639 if (error)
640 return (error);
641 svr4_to_bsd_shmid_ds(&ss, &bs);
642 break;
643 default:
644 return (EINVAL);
645 }
646 }
647
648 switch (uap->cmd) {
649 case SVR4_IPC_STAT:
650 cmd = IPC_STAT;
651 break;
652 case SVR4_IPC_SET:
653 cmd = IPC_SET;
654 break;
655 case SVR4_IPC_RMID:
656 cmd = IPC_RMID;
657 break;
658 case SVR4_SHM_LOCK:
659 cmd = SHM_LOCK;
660 break;
661 case SVR4_SHM_UNLOCK:
662 cmd = SHM_UNLOCK;
663 break;
664 default:
665 return (EINVAL);
666 }
667
668 error = kern_shmctl(td, uap->shmid, cmd, &bs, &bufsize);
669 if (error)
670 return (error);
671
672 switch (uap->cmd) {
673 case SVR4_IPC_STAT:
674 if (uap->buf != NULL) {
675 bsd_to_svr4_shmid_ds(&bs, &ss);
676 error = copyout(&ss, uap->buf, sizeof(ss));
677 }
678 break;
679 }
680
681 return (error);
682 }
683
684 int
685 svr4_sys_shmsys(td, uap)
686 struct thread *td;
687 struct svr4_sys_shmsys_args *uap;
688 {
689
690 DPRINTF(("svr4_shmsys(%d)\n", uap->what));
691
692 switch (uap->what) {
693 case SVR4_shmat:
694 return svr4_shmat(td, uap);
695 case SVR4_shmdt:
696 return svr4_shmdt(td, uap);
697 case SVR4_shmget:
698 return svr4_shmget(td, uap);
699 case SVR4_shmctl:
700 return svr4_shmctl(td, uap);
701 default:
702 return ENOSYS;
703 }
704 }
705
706 MODULE_DEPEND(svr4elf, sysvshm, 1, 1, 1);
707 #endif /* SYSVSHM */
Cache object: 09087278e2fd2512e2a606d84fffa4f1
|