1 /* $NetBSD: svr4_ipc.c,v 1.25 2007/12/20 23:03:05 dsl Exp $ */
4 * Copyright (c) 1995 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: svr4_ipc.c,v 1.25 2007/12/20 23:03:05 dsl Exp $");
35 #if defined(_KERNEL_OPT)
39 #include <sys/param.h>
40 #include <sys/kernel.h>
47 #include <sys/malloc.h>
49 #include <sys/systm.h>
52 #include <sys/mount.h>
53 #include <sys/syscallargs.h>
55 #include <compat/svr4/svr4_types.h>
56 #include <compat/svr4/svr4_signal.h>
57 #include <compat/svr4/svr4_lwp.h>
58 #include <compat/svr4/svr4_ucontext.h>
59 #include <compat/svr4/svr4_syscallargs.h>
60 #include <compat/svr4/svr4_util.h>
61 #include <compat/svr4/svr4_ipc.h>
63 #if defined(SYSVMSG) || defined(SYSVSHM) || defined(SYSVSEM)
66 svr4_to_bsd_ipc_perm(const struct svr4_ipc_perm
*spp
, struct ipc_perm
*bpp
)
71 bpp
->cuid
= spp
->cuid
;
72 bpp
->cgid
= spp
->cgid
;
73 bpp
->mode
= spp
->mode
;
78 bsd_to_svr4_ipc_perm(const struct ipc_perm
*bpp
, struct svr4_ipc_perm
*spp
)
83 spp
->cuid
= bpp
->cuid
;
84 spp
->cgid
= bpp
->cgid
;
85 spp
->mode
= bpp
->mode
;
92 bsd_to_svr4_semid_ds(const struct semid_ds
*bds
, struct svr4_semid_ds
*sds
)
94 bsd_to_svr4_ipc_perm(&bds
->sem_perm
, &sds
->sem_perm
);
95 sds
->sem_base
= (struct svr4_sem
*) bds
->_sem_base
;
96 sds
->sem_nsems
= bds
->sem_nsems
;
97 sds
->sem_otime
= bds
->sem_otime
;
98 sds
->sem_ctime
= bds
->sem_ctime
;
102 svr4_to_bsd_semid_ds(const struct svr4_semid_ds
*sds
, struct semid_ds
*bds
)
104 svr4_to_bsd_ipc_perm(&sds
->sem_perm
, &bds
->sem_perm
);
105 bds
->_sem_base
= (struct __sem
*) sds
->sem_base
;
106 bds
->sem_nsems
= sds
->sem_nsems
;
107 bds
->sem_otime
= sds
->sem_otime
;
108 bds
->sem_ctime
= sds
->sem_ctime
;
111 struct svr4_sys_semctl_args
{
112 syscallarg(int) what
;
113 syscallarg(int) semid
;
114 syscallarg(int) semnum
;
116 syscallarg(union __semun
) arg
;
120 svr4_semctl(struct lwp
*l
, const struct svr4_sys_semctl_args
*uap
, register_t
*retval
)
122 struct semid_ds sembuf
;
123 struct svr4_semid_ds ssembuf
;
125 void *pass_arg
= NULL
;
126 union __semun arg
= SCARG(uap
, arg
);
128 cmd
= SCARG(uap
, cmd
);
145 case SVR4_SEM_GETVAL
:
149 case SVR4_SEM_GETPID
:
153 case SVR4_SEM_GETNCNT
:
157 case SVR4_SEM_GETZCNT
:
161 case SVR4_SEM_GETALL
:
166 case SVR4_SEM_SETVAL
:
171 case SVR4_SEM_SETALL
:
180 if (cmd
== IPC_SET
) {
181 error
= copyin(SCARG(uap
, arg
).buf
, &ssembuf
, sizeof(ssembuf
));
184 svr4_to_bsd_semid_ds(&ssembuf
, &sembuf
);
187 error
= semctl1(l
, SCARG(uap
, semid
), SCARG(uap
, semnum
), cmd
,
190 if (error
== 0 && cmd
== IPC_STAT
) {
191 bsd_to_svr4_semid_ds(&sembuf
, &ssembuf
);
192 error
= copyout(&ssembuf
, SCARG(uap
, arg
).buf
, sizeof(ssembuf
));
198 struct svr4_sys_semget_args
{
199 syscallarg(int) what
;
200 syscallarg(svr4_key_t
) key
;
201 syscallarg(int) nsems
;
202 syscallarg(int) semflg
;
206 svr4_semget(struct lwp
*l
, const struct svr4_sys_semget_args
*uap
, register_t
*retval
)
208 struct sys_semget_args ap
;
210 SCARG(&ap
, key
) = SCARG(uap
, key
);
211 SCARG(&ap
, nsems
) = SCARG(uap
, nsems
);
212 SCARG(&ap
, semflg
) = SCARG(uap
, semflg
);
214 return sys_semget(l
, &ap
, retval
);
217 struct svr4_sys_semop_args
{
218 syscallarg(int) what
;
219 syscallarg(int) semid
;
220 syscallarg(struct svr4_sembuf
*) sops
;
221 syscallarg(u_int
) nsops
;
225 svr4_semop(struct lwp
*l
, const struct svr4_sys_semop_args
*uap
, register_t
*retval
)
227 struct sys_semop_args ap
;
229 SCARG(&ap
, semid
) = SCARG(uap
, semid
);
230 /* These are the same */
231 SCARG(&ap
, sops
) = (struct sembuf
*) SCARG(uap
, sops
);
232 SCARG(&ap
, nsops
) = SCARG(uap
, nsops
);
234 return sys_semop(l
, &ap
, retval
);
238 svr4_sys_semsys(struct lwp
*l
, const struct svr4_sys_semsys_args
*uap
, register_t
*retval
)
241 DPRINTF(("svr4_semsys(%d)\n", SCARG(uap
, what
)));
243 switch (SCARG(uap
, what
)) {
245 return svr4_semctl(l
, (const void *)uap
, retval
);
247 return svr4_semget(l
, (const void *)uap
, retval
);
249 return svr4_semop(l
, (const void *)uap
, retval
);
258 bsd_to_svr4_msqid_ds(const struct msqid_ds
*bds
, struct svr4_msqid_ds
*sds
)
260 bsd_to_svr4_ipc_perm(&bds
->msg_perm
, &sds
->msg_perm
);
261 sds
->msg_first
= (struct svr4_msg
*) bds
->_msg_first
;
262 sds
->msg_last
= (struct svr4_msg
*) bds
->_msg_last
;
263 sds
->msg_cbytes
= bds
->_msg_cbytes
;
264 sds
->msg_qnum
= bds
->msg_qnum
;
265 sds
->msg_qbytes
= bds
->msg_qbytes
;
266 sds
->msg_lspid
= bds
->msg_lspid
;
267 sds
->msg_lrpid
= bds
->msg_lrpid
;
268 sds
->msg_stime
= bds
->msg_stime
;
269 sds
->msg_rtime
= bds
->msg_rtime
;
270 sds
->msg_ctime
= bds
->msg_ctime
;
273 /* XXX What to put here? */
275 sds
->msg_qnum_cv
= 0;
280 svr4_to_bsd_msqid_ds(const struct svr4_msqid_ds
*sds
, struct msqid_ds
*bds
)
282 svr4_to_bsd_ipc_perm(&sds
->msg_perm
, &bds
->msg_perm
);
283 bds
->_msg_first
= (struct __msg
*) sds
->msg_first
;
284 bds
->_msg_last
= (struct __msg
*) sds
->msg_last
;
285 bds
->_msg_cbytes
= sds
->msg_cbytes
;
286 bds
->msg_qnum
= sds
->msg_qnum
;
287 bds
->msg_qbytes
= sds
->msg_qbytes
;
288 bds
->msg_lspid
= sds
->msg_lspid
;
289 bds
->msg_lrpid
= sds
->msg_lrpid
;
290 bds
->msg_stime
= sds
->msg_stime
;
291 bds
->msg_rtime
= sds
->msg_rtime
;
292 bds
->msg_ctime
= sds
->msg_ctime
;
300 struct svr4_sys_msgsnd_args
{
301 syscallarg(int) what
;
302 syscallarg(int) msqid
;
303 syscallarg(void *) msgp
;
304 syscallarg(size_t) msgsz
;
305 syscallarg(int) msgflg
;
309 svr4_msgsnd(struct lwp
*l
, const struct svr4_sys_msgsnd_args
*uap
, register_t
*retval
)
311 struct sys_msgsnd_args ap
;
313 SCARG(&ap
, msqid
) = SCARG(uap
, msqid
);
314 SCARG(&ap
, msgp
) = SCARG(uap
, msgp
);
315 SCARG(&ap
, msgsz
) = SCARG(uap
, msgsz
);
316 SCARG(&ap
, msgflg
) = SCARG(uap
, msgflg
);
318 return sys_msgsnd(l
, &ap
, retval
);
321 struct svr4_sys_msgrcv_args
{
322 syscallarg(int) what
;
323 syscallarg(int) msqid
;
324 syscallarg(void *) msgp
;
325 syscallarg(size_t) msgsz
;
326 syscallarg(long) msgtyp
;
327 syscallarg(int) msgflg
;
331 svr4_msgrcv(struct lwp
*l
, const struct svr4_sys_msgrcv_args
*uap
, register_t
*retval
)
333 struct sys_msgrcv_args ap
;
335 SCARG(&ap
, msqid
) = SCARG(uap
, msqid
);
336 SCARG(&ap
, msgp
) = SCARG(uap
, msgp
);
337 SCARG(&ap
, msgsz
) = SCARG(uap
, msgsz
);
338 SCARG(&ap
, msgtyp
) = SCARG(uap
, msgtyp
);
339 SCARG(&ap
, msgflg
) = SCARG(uap
, msgflg
);
341 return sys_msgrcv(l
, &ap
, retval
);
344 struct svr4_sys_msgget_args
{
345 syscallarg(int) what
;
346 syscallarg(svr4_key_t
) key
;
347 syscallarg(int) msgflg
;
351 svr4_msgget(struct lwp
*l
, const struct svr4_sys_msgget_args
*uap
, register_t
*retval
)
353 struct sys_msgget_args ap
;
355 SCARG(&ap
, key
) = SCARG(uap
, key
);
356 SCARG(&ap
, msgflg
) = SCARG(uap
, msgflg
);
358 return sys_msgget(l
, &ap
, retval
);
361 struct svr4_sys_msgctl_args
{
362 syscallarg(int) what
;
363 syscallarg(int) msqid
;
365 syscallarg(struct svr4_msqid_ds
*) buf
;
369 svr4_msgctl(struct lwp
*l
, const struct svr4_sys_msgctl_args
*uap
, register_t
*retval
)
371 struct svr4_msqid_ds ss
;
375 switch (SCARG(uap
, cmd
)) {
377 error
= msgctl1(l
, SCARG(uap
, msqid
), IPC_STAT
, &bs
);
379 bsd_to_svr4_msqid_ds(&bs
, &ss
);
380 error
= copyout(&ss
, SCARG(uap
, buf
), sizeof ss
);
385 error
= copyin(SCARG(uap
, buf
), &ss
, sizeof ss
);
388 svr4_to_bsd_msqid_ds(&ss
, &bs
);
389 return msgctl1(l
, SCARG(uap
, msqid
), IPC_SET
, &bs
);
392 return msgctl1(l
, SCARG(uap
, msqid
), IPC_RMID
, NULL
);
400 svr4_sys_msgsys(struct lwp
*l
, const struct svr4_sys_msgsys_args
*uap
, register_t
*retval
)
403 DPRINTF(("svr4_msgsys(%d)\n", SCARG(uap
, what
)));
405 switch (SCARG(uap
, what
)) {
407 return svr4_msgsnd(l
, (const void *)uap
, retval
);
409 return svr4_msgrcv(l
, (const void *)uap
, retval
);
411 return svr4_msgget(l
, (const void *)uap
, retval
);
413 return svr4_msgctl(l
, (const void *)uap
, retval
);
423 bsd_to_svr4_shmid_ds(const struct shmid_ds
*bds
, struct svr4_shmid_ds
*sds
)
425 bsd_to_svr4_ipc_perm(&bds
->shm_perm
, &sds
->shm_perm
);
426 sds
->shm_segsz
= bds
->shm_segsz
;
428 sds
->shm_lpid
= bds
->shm_lpid
;
429 sds
->shm_cpid
= bds
->shm_cpid
;
430 sds
->shm_amp
= bds
->_shm_internal
;
431 sds
->shm_nattch
= bds
->shm_nattch
;
432 sds
->shm_cnattch
= 0;
433 sds
->shm_atime
= bds
->shm_atime
;
435 sds
->shm_dtime
= bds
->shm_dtime
;
437 sds
->shm_ctime
= bds
->shm_ctime
;
442 svr4_to_bsd_shmid_ds(const struct svr4_shmid_ds
*sds
, struct shmid_ds
*bds
)
444 svr4_to_bsd_ipc_perm(&sds
->shm_perm
, &bds
->shm_perm
);
445 bds
->shm_segsz
= sds
->shm_segsz
;
446 bds
->shm_lpid
= sds
->shm_lpid
;
447 bds
->shm_cpid
= sds
->shm_cpid
;
448 bds
->_shm_internal
= sds
->shm_amp
;
449 bds
->shm_nattch
= sds
->shm_nattch
;
450 bds
->shm_atime
= sds
->shm_atime
;
451 bds
->shm_dtime
= sds
->shm_dtime
;
452 bds
->shm_ctime
= sds
->shm_ctime
;
455 struct svr4_sys_shmat_args
{
456 syscallarg(int) what
;
457 syscallarg(int) shmid
;
458 syscallarg(void *) shmaddr
;
459 syscallarg(int) shmflg
;
463 svr4_shmat(struct lwp
*l
, const struct svr4_sys_shmat_args
*uap
, register_t
*retval
)
465 struct sys_shmat_args ap
;
467 SCARG(&ap
, shmid
) = SCARG(uap
, shmid
);
468 SCARG(&ap
, shmaddr
) = SCARG(uap
, shmaddr
);
469 SCARG(&ap
, shmflg
) = SCARG(uap
, shmflg
);
471 return sys_shmat(l
, &ap
, retval
);
474 struct svr4_sys_shmdt_args
{
475 syscallarg(int) what
;
476 syscallarg(void *) shmaddr
;
480 svr4_shmdt(struct lwp
*l
, const struct svr4_sys_shmdt_args
*uap
, register_t
*retval
)
482 struct sys_shmdt_args ap
;
484 SCARG(&ap
, shmaddr
) = SCARG(uap
, shmaddr
);
486 return sys_shmdt(l
, &ap
, retval
);
489 struct svr4_sys_shmget_args
{
490 syscallarg(int) what
;
491 syscallarg(key_t
) key
;
492 syscallarg(int) size
;
493 syscallarg(int) shmflg
;
497 svr4_shmget(struct lwp
*l
, const struct svr4_sys_shmget_args
*uap
, register_t
*retval
)
499 struct sys_shmget_args ap
;
501 SCARG(&ap
, key
) = SCARG(uap
, key
);
502 SCARG(&ap
, size
) = SCARG(uap
, size
);
503 SCARG(&ap
, shmflg
) = SCARG(uap
, shmflg
);
505 return sys_shmget(l
, &ap
, retval
);
508 struct svr4_sys_shmctl_args
{
509 syscallarg(int) what
;
510 syscallarg(int) shmid
;
512 syscallarg(struct svr4_shmid_ds
*) buf
;
516 svr4_shmctl(struct lwp
*l
, const struct svr4_sys_shmctl_args
*uap
, register_t
*retval
)
519 struct svr4_shmid_ds ss
;
522 switch (SCARG(uap
, cmd
)) {
524 error
= shmctl1(l
, SCARG(uap
, shmid
), IPC_STAT
, &bs
);
526 bsd_to_svr4_shmid_ds(&bs
, &ss
);
527 error
= copyout(&ss
, SCARG(uap
, buf
), sizeof ss
);
532 error
= copyin(SCARG(uap
, buf
), &ss
, sizeof ss
);
535 svr4_to_bsd_shmid_ds(&ss
, &bs
);
536 return shmctl1(l
, SCARG(uap
, shmid
), IPC_SET
, &bs
);
539 return shmctl1(l
, SCARG(uap
, shmid
), IPC_RMID
, NULL
);
542 return shmctl1(l
, SCARG(uap
, shmid
), SHM_LOCK
, NULL
);
544 case SVR4_SHM_UNLOCK
:
545 return shmctl1(l
, SCARG(uap
, shmid
), SHM_UNLOCK
, NULL
);
553 svr4_sys_shmsys(struct lwp
*l
, const struct svr4_sys_shmsys_args
*uap
, register_t
*retval
)
556 DPRINTF(("svr4_shmsys(%d)\n", SCARG(uap
, what
)));
558 switch (SCARG(uap
, what
)) {
560 return svr4_shmat(l
, (const void *)uap
, retval
);
562 return svr4_shmdt(l
, (const void *)uap
, retval
);
564 return svr4_shmget(l
, (const void *)uap
, retval
);
566 return svr4_shmctl(l
, (const void *)uap
, retval
);