1 /* $NetBSD: ibcs2_ipc.c,v 1.26 2007/12/08 18:36:01 dsl Exp $ */
4 * Copyright (c) 1995 Scott Bartram
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __KERNEL_RCSID(0, "$NetBSD: ibcs2_ipc.c,v 1.26 2007/12/08 18:36:01 dsl Exp $");
30 #if defined(_KERNEL_OPT)
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/namei.h>
40 #include <sys/filedesc.h>
41 #include <sys/ioctl.h>
43 #include <sys/kernel.h>
46 #include <sys/mount.h>
47 #include <sys/reboot.h>
48 #include <sys/resource.h>
49 #include <sys/resourcevar.h>
50 #include <sys/signal.h>
51 #include <sys/signalvar.h>
52 #include <sys/socket.h>
54 #include <sys/times.h>
55 #include <sys/vnode.h>
58 #include <sys/utsname.h>
59 #include <sys/unistd.h>
63 #include <sys/syscallargs.h>
65 #include <compat/ibcs2/ibcs2_types.h>
66 #include <compat/ibcs2/ibcs2_signal.h>
67 #include <compat/ibcs2/ibcs2_syscallargs.h>
68 #include <compat/ibcs2/ibcs2_util.h>
70 #include <compat/sys/sem.h>
71 #include <compat/sys/shm.h>
72 #include <compat/sys/msg.h>
74 /* Verify that the standard values are correct. */
75 typedef char x
[IPC_RMID
== 0 && IPC_SET
== 1 && IPC_STAT
== 2 ? 1 : -1];
77 struct ibcs2_ipc_perm
{
87 struct ibcs2_msqid_ds
{
88 struct ibcs2_ipc_perm msg_perm
;
89 struct __msg
*msg_first
; /* kernel address don't copyout */
90 struct __msg
*msg_last
; /* kernel address don't copyout */
96 ibcs2_time_t msg_stime
;
97 ibcs2_time_t msg_rtime
;
98 ibcs2_time_t msg_ctime
;
101 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
103 cvt_perm2iperm(const struct ipc_perm
*bp
, struct ibcs2_ipc_perm
*ibp
)
105 ibp
->cuid
= bp
->cuid
;
106 ibp
->cgid
= bp
->cgid
;
109 ibp
->mode
= bp
->mode
;
115 cvt_iperm2perm(const struct ibcs2_ipc_perm
*ibp
, struct ipc_perm
*bp
)
117 bp
->cuid
= ibp
->cuid
;
118 bp
->cgid
= ibp
->cgid
;
121 bp
->mode
= ibp
->mode
;
125 #endif /* SYSVMSG || SYSVSEM || SYSVMSG */
134 cvt_msqid2imsqid(const struct msqid_ds
*bp
, struct ibcs2_msqid_ds
*ibp
)
136 cvt_perm2iperm(&bp
->msg_perm
, &ibp
->msg_perm
);
137 ibp
->msg_first
= NULL
;
138 ibp
->msg_last
= NULL
;
139 ibp
->msg_cbytes
= bp
->_msg_cbytes
;
140 ibp
->msg_qnum
= bp
->msg_qnum
;
141 ibp
->msg_qbytes
= bp
->msg_qbytes
;
142 ibp
->msg_lspid
= bp
->msg_lspid
;
143 ibp
->msg_lrpid
= bp
->msg_lrpid
;
144 ibp
->msg_stime
= bp
->msg_stime
;
145 ibp
->msg_rtime
= bp
->msg_rtime
;
146 ibp
->msg_ctime
= bp
->msg_ctime
;
150 cvt_imsqid2msqid(struct ibcs2_msqid_ds
*ibp
, struct msqid_ds
*bp
)
152 cvt_iperm2perm(&ibp
->msg_perm
, &bp
->msg_perm
);
153 bp
->_msg_first
= NULL
;
154 bp
->_msg_last
= NULL
;
155 bp
->_msg_cbytes
= ibp
->msg_cbytes
;
156 bp
->msg_qnum
= ibp
->msg_qnum
;
157 bp
->msg_qbytes
= ibp
->msg_qbytes
;
158 bp
->msg_lspid
= ibp
->msg_lspid
;
159 bp
->msg_lrpid
= ibp
->msg_lrpid
;
160 bp
->msg_stime
= ibp
->msg_stime
;
161 bp
->msg_rtime
= ibp
->msg_rtime
;
162 bp
->msg_ctime
= ibp
->msg_ctime
;
166 do_compat_10_sys_msgsys(struct lwp
*l
, const struct ibcs2_sys_msgsys_args
*uap
,
167 register_t
*retval
, int which
)
169 struct compat_10_sys_msgsys_args bsd_ua
;
171 SCARG(&bsd_ua
, which
) = which
;
172 SCARG(&bsd_ua
, a2
) = SCARG(uap
, a2
);
173 SCARG(&bsd_ua
, a3
) = SCARG(uap
, a3
);
174 SCARG(&bsd_ua
, a4
) = SCARG(uap
, a4
);
175 SCARG(&bsd_ua
, a5
) = SCARG(uap
, a5
);
176 SCARG(&bsd_ua
, a6
) = SCARG(uap
, a6
);
178 return compat_10_sys_msgsys(l
, &bsd_ua
, retval
);
182 ibcs2_sys_msgsys(struct lwp
*l
, const struct ibcs2_sys_msgsys_args
*uap
, register_t
*retval
)
186 syscallarg(int) which;
194 struct msqid_ds msqbuf
;
195 struct ibcs2_msqid_ds msqbuf_ibcs2
, *ibp
;
197 switch (SCARG(uap
, which
)) {
199 return do_compat_10_sys_msgsys(l
, uap
, retval
, 1);
201 ibp
= (void *)SCARG(uap
, a4
);
202 switch (SCARG(uap
, a3
)) {
204 error
= msgctl1(l
, SCARG(uap
, a2
), IPC_STAT
, &msqbuf
);
206 cvt_msqid2imsqid(&msqbuf
, &msqbuf_ibcs2
);
207 error
= copyout(&msqbuf_ibcs2
, ibp
,
208 sizeof msqbuf_ibcs2
);
212 error
= copyin(ibp
, &msqbuf_ibcs2
, sizeof msqbuf_ibcs2
);
214 cvt_imsqid2msqid(&msqbuf_ibcs2
, &msqbuf
);
215 error
= msgctl1(l
, SCARG(uap
, a2
),
220 return msgctl1(l
, SCARG(uap
, a2
), IPC_RMID
, NULL
);
224 return do_compat_10_sys_msgsys(l
, uap
, retval
, 3);
226 return do_compat_10_sys_msgsys(l
, uap
, retval
, 2);
242 struct ibcs2_semid_ds
{
243 struct ibcs2_ipc_perm sem_perm
;
244 struct ibcs2_sem
*sem_base
;
247 ibcs2_time_t sem_otime
;
248 ibcs2_time_t sem_ctime
;
259 static void cvt_sem2isem(struct sem
*, struct ibcs2_sem
*);
260 static void cvt_isem2sem(struct ibcs2_sem
*, struct sem
*);
263 cvt_sem2isem(struct __sem
*bp
, struct ibcs2_sem
*ibp
)
265 ibp
->semval
= bp
->semval
;
266 ibp
->sempid
= bp
->sempid
;
267 ibp
->semncnt
= bp
->semncnt
;
268 ibp
->semzcnt
= bp
->semzcnt
;
272 cvt_isem2sem(struct ibcs2_sem
*ibp
, struct __sem
*bp
)
274 bp
->semval
= ibp
->semval
;
275 bp
->sempid
= ibp
->sempid
;
276 bp
->semncnt
= ibp
->semncnt
;
277 bp
->semzcnt
= ibp
->semzcnt
;
282 cvt_semid2isemid(const struct semid_ds
*bp
, struct ibcs2_semid_ds
*ibp
)
284 cvt_perm2iperm(&bp
->sem_perm
, &ibp
->sem_perm
);
285 ibp
->sem_base
= (struct ibcs2_sem
*)bp
->_sem_base
;
286 ibp
->sem_nsems
= bp
->sem_nsems
;
287 ibp
->sem_otime
= bp
->sem_otime
;
288 ibp
->sem_ctime
= bp
->sem_ctime
;
293 cvt_isemid2semid(const struct ibcs2_semid_ds
*ibp
, struct semid_ds
*bp
)
295 cvt_iperm2perm(&ibp
->sem_perm
, &bp
->sem_perm
);
296 bp
->_sem_base
= (struct __sem
*)ibp
->sem_base
;
297 bp
->sem_nsems
= ibp
->sem_nsems
;
298 bp
->sem_otime
= ibp
->sem_otime
;
299 bp
->sem_ctime
= ibp
->sem_ctime
;
303 ibcs2_sys_semsys(struct lwp
*l
, const struct ibcs2_sys_semsys_args
*uap
, register_t
*retval
)
307 syscallarg(int) which;
313 struct semid_ds sembuf
;
314 struct ibcs2_semid_ds isembuf
;
316 int a5
= SCARG(uap
, a5
);
319 switch (SCARG(uap
, which
)) {
321 #define semctl_semid SCARG(uap, a2)
322 #define semctl_semnum SCARG(uap, a3)
323 #define semctl_cmd SCARG(uap, a4)
324 #define semctl_arg ((union __semun *)&a5)
325 pass_arg
= get_semctl_arg(semctl_cmd
, &sembuf
, semctl_arg
);
326 if (semctl_cmd
== IPC_SET
) {
327 error
= copyin(semctl_arg
->buf
, &isembuf
, sizeof isembuf
);
330 cvt_isemid2semid(&isembuf
, &sembuf
);
332 error
= semctl1(l
, semctl_semid
, semctl_semnum
, semctl_cmd
,
334 if (error
== 0 && semctl_cmd
== IPC_STAT
) {
335 cvt_semid2isemid(&sembuf
, &isembuf
);
336 error
= copyout(&isembuf
, semctl_arg
->buf
, sizeof(isembuf
));
345 return compat_10_sys_semsys(l
, (const void *)uap
, retval
);
348 return compat_10_sys_semsys(l
, (const void *)uap
, retval
);
362 struct ibcs2_shmid_ds
{
363 struct ibcs2_ipc_perm shm_perm
;
371 ibcs2_time_t shm_atime
;
372 ibcs2_time_t shm_dtime
;
373 ibcs2_time_t shm_ctime
;
377 cvt_shmid2ishmid(const struct shmid_ds
*bp
, struct ibcs2_shmid_ds
*ibp
)
379 cvt_perm2iperm(&bp
->shm_perm
, &ibp
->shm_perm
);
380 ibp
->shm_segsz
= bp
->shm_segsz
;
381 ibp
->shm_lpid
= bp
->shm_lpid
;
382 ibp
->shm_cpid
= bp
->shm_cpid
;
383 ibp
->shm_nattch
= bp
->shm_nattch
;
384 ibp
->shm_cnattch
= 0; /* ignored anyway */
385 ibp
->shm_atime
= bp
->shm_atime
;
386 ibp
->shm_dtime
= bp
->shm_dtime
;
387 ibp
->shm_ctime
= bp
->shm_ctime
;
391 cvt_ishmid2shmid(const struct ibcs2_shmid_ds
*ibp
, struct shmid_ds
*bp
)
393 cvt_iperm2perm(&ibp
->shm_perm
, &bp
->shm_perm
);
394 bp
->shm_segsz
= ibp
->shm_segsz
;
395 bp
->shm_lpid
= ibp
->shm_lpid
;
396 bp
->shm_cpid
= ibp
->shm_cpid
;
397 bp
->shm_nattch
= ibp
->shm_nattch
;
398 bp
->shm_atime
= ibp
->shm_atime
;
399 bp
->shm_dtime
= ibp
->shm_dtime
;
400 bp
->shm_ctime
= ibp
->shm_ctime
;
401 bp
->_shm_internal
= (void *)0; /* ignored anyway */
406 ibcs2_sys_shmsys(struct lwp
*l
, const struct ibcs2_sys_shmsys_args
*uap
, register_t
*retval
)
410 syscallarg(int) which;
415 struct shmid_ds shmbuf
;
416 struct ibcs2_shmid_ds
*isp
, ishmbuf
;
419 switch (SCARG(uap
, which
)) {
424 cmd
= SCARG(uap
, a3
);
425 isp
= (struct ibcs2_shmid_ds
*)SCARG(uap
, a4
);
426 if (cmd
== IPC_SET
) {
427 error
= copyin(isp
, &ishmbuf
, sizeof(ishmbuf
));
430 cvt_ishmid2shmid(&ishmbuf
, &shmbuf
);
433 error
= shmctl1(l
, SCARG(uap
, a2
), cmd
,
434 (cmd
== IPC_SET
|| cmd
== IPC_STAT
) ? &shmbuf
: NULL
);
436 if (error
== 0 && cmd
== IPC_STAT
) {
437 cvt_shmid2ishmid(&shmbuf
, &ishmbuf
);
438 error
= copyout(&ishmbuf
, isp
, sizeof(ishmbuf
));
451 return compat_10_sys_shmsys(l
, (const void *)uap
, retval
);