2 * Copyright (c) 1994-1995 Søren Schmidt
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer
10 * in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software withough specific prior written permission
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * $FreeBSD: src/sys/compat/linux/linux_ipc.c,v 1.17.2.3 2001/11/05 19:08:22 marcel Exp $
29 * $DragonFly: src/sys/emulation/linux/linux_ipc.c,v 1.8 2006/06/05 07:26:09 dillon Exp $
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/sysproto.h>
40 #include <arch_linux/linux.h>
41 #include <machine/limits.h>
42 #include <arch_linux/linux_proto.h>
43 #include "linux_ipc.h"
44 #include "linux_util.h"
48 bsd_to_linux_shminfo( struct shminfo
*bpp
, struct l_shminfo
*lpp
)
50 lpp
->shmmax
= bpp
->shmmax
;
51 lpp
->shmmin
= bpp
->shmmin
;
52 lpp
->shmmni
= bpp
->shmmni
;
53 lpp
->shmseg
= bpp
->shmseg
;
54 lpp
->shmall
= bpp
->shmall
;
59 bsd_to_linux_shm_info( struct shm_info
*bpp
, struct l_shm_info
*lpp
)
61 lpp
->used_ids
= bpp
->used_ids
;
62 lpp
->shm_tot
= bpp
->shm_tot
;
63 lpp
->shm_rss
= bpp
->shm_rss
;
64 lpp
->shm_swp
= bpp
->shm_swp
;
65 lpp
->swap_attempts
= bpp
->swap_attempts
;
66 lpp
->swap_successes
= bpp
->swap_successes
;
74 linux_to_bsd_ipc_perm(struct l_ipc_perm
*lpp
, struct ipc_perm
*bpp
)
79 bpp
->cuid
= lpp
->cuid
;
80 bpp
->cgid
= lpp
->cgid
;
81 bpp
->mode
= lpp
->mode
;
89 bsd_to_linux_ipc_perm(struct ipc_perm
*bpp
, struct l_ipc_perm
*lpp
)
94 lpp
->cuid
= bpp
->cuid
;
95 lpp
->cgid
= bpp
->cgid
;
96 lpp
->mode
= bpp
->mode
;
104 linux_to_bsd_semid_ds(struct l_semid_ds
*lsp
, struct semid_ds
*bsp
)
106 linux_to_bsd_ipc_perm(&lsp
->sem_perm
, &bsp
->sem_perm
);
107 bsp
->sem_otime
= lsp
->sem_otime
;
108 bsp
->sem_ctime
= lsp
->sem_ctime
;
109 bsp
->sem_nsems
= lsp
->sem_nsems
;
110 bsp
->sem_base
= lsp
->sem_base
;
117 bsd_to_linux_semid_ds(struct semid_ds
*bsp
, struct l_semid_ds
*lsp
)
119 bsd_to_linux_ipc_perm(&bsp
->sem_perm
, &lsp
->sem_perm
);
120 lsp
->sem_otime
= bsp
->sem_otime
;
121 lsp
->sem_ctime
= bsp
->sem_ctime
;
122 lsp
->sem_nsems
= bsp
->sem_nsems
;
123 lsp
->sem_base
= bsp
->sem_base
;
130 linux_to_bsd_shmid_ds(struct l_shmid_ds
*lsp
, struct shmid_ds
*bsp
)
132 linux_to_bsd_ipc_perm(&lsp
->shm_perm
, &bsp
->shm_perm
);
133 bsp
->shm_segsz
= lsp
->shm_segsz
;
134 bsp
->shm_lpid
= lsp
->shm_lpid
;
135 bsp
->shm_cpid
= lsp
->shm_cpid
;
136 bsp
->shm_nattch
= lsp
->shm_nattch
;
137 bsp
->shm_atime
= lsp
->shm_atime
;
138 bsp
->shm_dtime
= lsp
->shm_dtime
;
139 bsp
->shm_ctime
= lsp
->shm_ctime
;
146 bsd_to_linux_shmid_ds(struct shmid_ds
*bsp
, struct l_shmid_ds
*lsp
)
148 bsd_to_linux_ipc_perm(&bsp
->shm_perm
, &lsp
->shm_perm
);
149 if (bsp
->shm_segsz
> INT_MAX
)
150 lsp
->shm_segsz
= INT_MAX
;
152 lsp
->shm_segsz
= bsp
->shm_segsz
;
153 lsp
->shm_lpid
= bsp
->shm_lpid
;
154 lsp
->shm_cpid
= bsp
->shm_cpid
;
155 lsp
->shm_nattch
= bsp
->shm_nattch
;
156 lsp
->shm_atime
= bsp
->shm_atime
;
157 lsp
->shm_dtime
= bsp
->shm_dtime
;
158 lsp
->shm_ctime
= bsp
->shm_ctime
;
163 linux_to_bsd_msqid_ds(struct l_msqid_ds
*lsp
, struct msqid_ds
*bsp
)
165 linux_to_bsd_ipc_perm(&lsp
->msg_perm
, &bsp
->msg_perm
);
166 bsp
->msg_cbytes
= lsp
->msg_cbytes
;
167 bsp
->msg_qnum
= lsp
->msg_qnum
;
168 bsp
->msg_qbytes
= lsp
->msg_qbytes
;
169 bsp
->msg_lspid
= lsp
->msg_lspid
;
170 bsp
->msg_lrpid
= lsp
->msg_lrpid
;
171 bsp
->msg_stime
= lsp
->msg_stime
;
172 bsp
->msg_rtime
= lsp
->msg_rtime
;
173 bsp
->msg_ctime
= lsp
->msg_ctime
;
177 bsd_to_linux_msqid_ds(struct msqid_ds
*bsp
, struct l_msqid_ds
*lsp
)
179 bsd_to_linux_ipc_perm(&bsp
->msg_perm
, &lsp
->msg_perm
);
180 lsp
->msg_cbytes
= bsp
->msg_cbytes
;
181 lsp
->msg_qnum
= bsp
->msg_qnum
;
182 lsp
->msg_qbytes
= bsp
->msg_qbytes
;
183 lsp
->msg_lspid
= bsp
->msg_lspid
;
184 lsp
->msg_lrpid
= bsp
->msg_lrpid
;
185 lsp
->msg_stime
= bsp
->msg_stime
;
186 lsp
->msg_rtime
= bsp
->msg_rtime
;
187 lsp
->msg_ctime
= bsp
->msg_ctime
;
191 linux_ipc_perm_to_ipc64_perm(struct l_ipc_perm
*in
, struct l_ipc64_perm
*out
)
194 /* XXX: do we really need to do something here? */
198 out
->cuid
= in
->cuid
;
199 out
->cgid
= in
->cgid
;
200 out
->mode
= in
->mode
;
205 linux_msqid_pullup(l_int ver
, struct l_msqid_ds
*linux_msqid
, caddr_t uaddr
)
207 struct l_msqid64_ds linux_msqid64
;
210 if (ver
== LINUX_IPC_64
) {
211 error
= copyin(uaddr
, &linux_msqid64
, sizeof(linux_msqid64
));
215 bzero(linux_msqid
, sizeof(*linux_msqid
));
217 linux_msqid
->msg_perm
.uid
= linux_msqid64
.msg_perm
.uid
;
218 linux_msqid
->msg_perm
.gid
= linux_msqid64
.msg_perm
.gid
;
219 linux_msqid
->msg_perm
.mode
= linux_msqid64
.msg_perm
.mode
;
221 if (linux_msqid64
.msg_qbytes
> USHRT_MAX
)
222 linux_msqid
->msg_lqbytes
= linux_msqid64
.msg_qbytes
;
224 linux_msqid
->msg_qbytes
= linux_msqid64
.msg_qbytes
;
226 error
= copyin(uaddr
, linux_msqid
, sizeof(*linux_msqid
));
232 linux_msqid_pushdown(l_int ver
, struct l_msqid_ds
*linux_msqid
, caddr_t uaddr
)
234 struct l_msqid64_ds linux_msqid64
;
236 if (ver
== LINUX_IPC_64
) {
237 bzero(&linux_msqid64
, sizeof(linux_msqid64
));
239 linux_ipc_perm_to_ipc64_perm(&linux_msqid
->msg_perm
,
240 &linux_msqid64
.msg_perm
);
242 linux_msqid64
.msg_stime
= linux_msqid
->msg_stime
;
243 linux_msqid64
.msg_rtime
= linux_msqid
->msg_rtime
;
244 linux_msqid64
.msg_ctime
= linux_msqid
->msg_ctime
;
246 if (linux_msqid
->msg_cbytes
== 0)
247 linux_msqid64
.msg_cbytes
= linux_msqid
->msg_lcbytes
;
249 linux_msqid64
.msg_cbytes
= linux_msqid
->msg_cbytes
;
251 linux_msqid64
.msg_qnum
= linux_msqid
->msg_qnum
;
253 if (linux_msqid
->msg_qbytes
== 0)
254 linux_msqid64
.msg_qbytes
= linux_msqid
->msg_lqbytes
;
256 linux_msqid64
.msg_qbytes
= linux_msqid
->msg_qbytes
;
258 linux_msqid64
.msg_lspid
= linux_msqid
->msg_lspid
;
259 linux_msqid64
.msg_lrpid
= linux_msqid
->msg_lrpid
;
261 return (copyout(&linux_msqid64
, uaddr
, sizeof(linux_msqid64
)));
263 return (copyout(linux_msqid
, uaddr
, sizeof(*linux_msqid
)));
268 linux_semid_pullup(l_int ver
, struct l_semid_ds
*linux_semid
, caddr_t uaddr
)
270 struct l_semid64_ds linux_semid64
;
273 if (ver
== LINUX_IPC_64
) {
274 error
= copyin(uaddr
, &linux_semid64
, sizeof(linux_semid64
));
278 bzero(linux_semid
, sizeof(*linux_semid
));
280 linux_semid
->sem_perm
.uid
= linux_semid64
.sem_perm
.uid
;
281 linux_semid
->sem_perm
.gid
= linux_semid64
.sem_perm
.gid
;
282 linux_semid
->sem_perm
.mode
= linux_semid64
.sem_perm
.mode
;
284 error
= copyin(uaddr
, linux_semid
, sizeof(*linux_semid
));
290 linux_semid_pushdown(l_int ver
, struct l_semid_ds
*linux_semid
, caddr_t uaddr
)
292 struct l_semid64_ds linux_semid64
;
294 if (ver
== LINUX_IPC_64
) {
295 bzero(&linux_semid64
, sizeof(linux_semid64
));
297 linux_ipc_perm_to_ipc64_perm(&linux_semid
->sem_perm
,
298 &linux_semid64
.sem_perm
);
300 linux_semid64
.sem_otime
= linux_semid
->sem_otime
;
301 linux_semid64
.sem_ctime
= linux_semid
->sem_ctime
;
302 linux_semid64
.sem_nsems
= linux_semid
->sem_nsems
;
304 return (copyout(&linux_semid64
, uaddr
, sizeof(linux_semid64
)));
306 return (copyout(linux_semid
, uaddr
, sizeof(*linux_semid
)));
311 linux_shmid_pullup(l_int ver
, struct l_shmid_ds
*linux_shmid
, caddr_t uaddr
)
313 struct l_shmid64_ds linux_shmid64
;
316 if (ver
== LINUX_IPC_64
) {
317 error
= copyin(uaddr
, &linux_shmid64
, sizeof(linux_shmid64
));
321 bzero(linux_shmid
, sizeof(*linux_shmid
));
323 linux_shmid
->shm_perm
.uid
= linux_shmid64
.shm_perm
.uid
;
324 linux_shmid
->shm_perm
.gid
= linux_shmid64
.shm_perm
.gid
;
325 linux_shmid
->shm_perm
.mode
= linux_shmid64
.shm_perm
.mode
;
327 error
= copyin(uaddr
, linux_shmid
, sizeof(*linux_shmid
));
333 linux_shmid_pushdown(l_int ver
, struct l_shmid_ds
*linux_shmid
, caddr_t uaddr
)
335 struct l_shmid64_ds linux_shmid64
;
338 * XXX: This is backwards and loses information in shm_nattch
339 * and shm_segsz. We should probably either expose the BSD
340 * shmid structure directly and convert it to either the
341 * non-64 or 64 variant directly or the code should always
342 * convert to the 64 variant and then truncate values into the
343 * non-64 variant if needed since the 64 variant has more
346 if (ver
== LINUX_IPC_64
) {
347 bzero(&linux_shmid64
, sizeof(linux_shmid64
));
349 linux_ipc_perm_to_ipc64_perm(&linux_shmid
->shm_perm
,
350 &linux_shmid64
.shm_perm
);
352 linux_shmid64
.shm_segsz
= linux_shmid
->shm_segsz
;
353 linux_shmid64
.shm_atime
= linux_shmid
->shm_atime
;
354 linux_shmid64
.shm_dtime
= linux_shmid
->shm_dtime
;
355 linux_shmid64
.shm_ctime
= linux_shmid
->shm_ctime
;
356 linux_shmid64
.shm_cpid
= linux_shmid
->shm_cpid
;
357 linux_shmid64
.shm_lpid
= linux_shmid
->shm_lpid
;
358 linux_shmid64
.shm_nattch
= linux_shmid
->shm_nattch
;
360 return (copyout(&linux_shmid64
, uaddr
, sizeof(linux_shmid64
)));
362 return (copyout(linux_shmid
, uaddr
, sizeof(*linux_shmid
)));
367 linux_shminfo_pushdown(l_int ver
, struct l_shminfo
*linux_shminfo
,
370 struct l_shminfo64 linux_shminfo64
;
372 if (ver
== LINUX_IPC_64
) {
373 bzero(&linux_shminfo64
, sizeof(linux_shminfo64
));
375 linux_shminfo64
.shmmax
= linux_shminfo
->shmmax
;
376 linux_shminfo64
.shmmin
= linux_shminfo
->shmmin
;
377 linux_shminfo64
.shmmni
= linux_shminfo
->shmmni
;
378 linux_shminfo64
.shmseg
= linux_shminfo
->shmseg
;
379 linux_shminfo64
.shmall
= linux_shminfo
->shmall
;
381 return (copyout(&linux_shminfo64
, uaddr
,
382 sizeof(linux_shminfo64
)));
384 return (copyout(linux_shminfo
, uaddr
, sizeof(*linux_shminfo
)));
392 linux_semop(struct linux_semop_args
*args
)
394 struct semop_args bsd_args
;
397 bsd_args
.sysmsg_result
= 0;
398 bsd_args
.semid
= args
->semid
;
399 bsd_args
.sops
= (struct sembuf
*)args
->tsops
;
400 bsd_args
.nsops
= args
->nsops
;
401 error
= sys_semop(&bsd_args
);
402 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
410 linux_semget(struct linux_semget_args
*args
)
412 struct semget_args bsd_args
;
415 bsd_args
.sysmsg_result
= 0;
416 bsd_args
.key
= args
->key
;
417 bsd_args
.nsems
= args
->nsems
;
418 bsd_args
.semflg
= args
->semflg
;
419 error
= sys_semget(&bsd_args
);
420 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
428 linux_semctl(struct linux_semctl_args
*args
)
430 struct l_semid_ds linux_semid
;
431 struct __semctl_args bsd_args
;
432 struct l_seminfo linux_seminfo
;
437 sg
= stackgap_init();
439 /* Make sure the arg parameter can be copied in. */
440 unptr
= stackgap_alloc(&sg
, sizeof(union semun
));
441 bcopy(&args
->arg
, unptr
, sizeof(union semun
));
443 bsd_args
.sysmsg_result
= 0;
444 bsd_args
.semid
= args
->semid
;
445 bsd_args
.semnum
= args
->semnum
;
446 bsd_args
.arg
= unptr
;
448 switch (args
->cmd
& ~LINUX_IPC_64
) {
450 bsd_args
.cmd
= IPC_RMID
;
453 bsd_args
.cmd
= GETNCNT
;
456 bsd_args
.cmd
= GETPID
;
459 bsd_args
.cmd
= GETVAL
;
462 bsd_args
.cmd
= GETZCNT
;
465 bsd_args
.cmd
= SETVAL
;
468 bsd_args
.cmd
= IPC_SET
;
469 error
= linux_semid_pullup(args
->cmd
& LINUX_IPC_64
,
470 &linux_semid
, (caddr_t
)args
->arg
.buf
);
473 unptr
->buf
= stackgap_alloc(&sg
, sizeof(struct semid_ds
));
474 linux_to_bsd_semid_ds(&linux_semid
, unptr
->buf
);
478 if ((args
->cmd
& ~LINUX_IPC_64
) == LINUX_IPC_STAT
)
479 bsd_args
.cmd
= IPC_STAT
;
481 bsd_args
.cmd
= SEM_STAT
;
482 unptr
->buf
= stackgap_alloc(&sg
, sizeof(struct semid_ds
));
483 error
= sys___semctl(&bsd_args
);
486 args
->sysmsg_result
= IXSEQ_TO_IPCID(bsd_args
.semid
,
487 unptr
->buf
->sem_perm
);
488 bsd_to_linux_semid_ds(unptr
->buf
, &linux_semid
);
489 error
= linux_semid_pushdown(args
->cmd
& LINUX_IPC_64
,
490 &linux_semid
, (caddr_t
)(args
->arg
.buf
));
492 args
->sysmsg_iresult
= ((args
->cmd
& ~LINUX_IPC_64
) == SEM_STAT
)
493 ? bsd_args
.sysmsg_result
: 0;
497 error
= copyin((caddr_t
)args
->arg
.buf
, &linux_seminfo
,
498 sizeof(linux_seminfo
) );
501 bcopy(&seminfo
, &linux_seminfo
, sizeof(linux_seminfo
) );
502 /* XXX BSD equivalent?
503 #define used_semids 10
505 linux_seminfo.semusz = used_semids;
506 linux_seminfo.semaem = used_sems;
508 error
= copyout((caddr_t
)&linux_seminfo
, (caddr_t
)args
->arg
.buf
,
509 sizeof(linux_seminfo
) );
512 args
->sysmsg_result
= seminfo
.semmni
;
513 return 0; /* No need for __semctl call */
515 bsd_args
.cmd
= GETALL
;
518 bsd_args
.cmd
= SETALL
;
521 uprintf("linux: 'ipc' type=%d not implemented\n", args
->cmd
& ~LINUX_IPC_64
);
524 error
= sys___semctl(&bsd_args
);
525 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
533 linux_msgsnd(struct linux_msgsnd_args
*args
)
535 struct msgsnd_args bsd_args
;
538 if ((l_long
)args
->msgsz
< 0 || args
->msgsz
> (l_long
)msginfo
.msgmax
)
540 bsd_args
.sysmsg_result
= 0;
541 bsd_args
.msqid
= args
->msqid
;
542 bsd_args
.msgp
= args
->msgp
;
543 bsd_args
.msgsz
= args
->msgsz
;
544 bsd_args
.msgflg
= args
->msgflg
;
545 error
= sys_msgsnd(&bsd_args
);
546 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
554 linux_msgrcv(struct linux_msgrcv_args
*args
)
556 struct msgrcv_args bsd_args
;
558 if ((l_long
)args
->msgsz
< 0 || args
->msgsz
> (l_long
)msginfo
.msgmax
)
560 bsd_args
.sysmsg_result
= 0;
561 bsd_args
.msqid
= args
->msqid
;
562 bsd_args
.msgp
= args
->msgp
;
563 bsd_args
.msgsz
= args
->msgsz
;
564 bsd_args
.msgtyp
= 0; /* XXX - args->msgtyp; */
565 bsd_args
.msgflg
= args
->msgflg
;
566 error
= sys_msgrcv(&bsd_args
);
567 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
575 linux_msgget(struct linux_msgget_args
*args
)
577 struct msgget_args bsd_args
;
580 bsd_args
.sysmsg_result
= 0;
581 bsd_args
.key
= args
->key
;
582 bsd_args
.msgflg
= args
->msgflg
;
583 error
= sys_msgget(&bsd_args
);
584 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
592 linux_msgctl(struct linux_msgctl_args
*args
)
594 struct msgctl_args bsd_args
;
595 struct l_msqid_ds linux_msqid
;
597 struct msqid_ds
*unptr
;
600 sg
= stackgap_init();
601 /* Make sure the arg parameter can be copied in. */
602 unptr
= stackgap_alloc(&sg
, sizeof(struct msqid_ds
));
603 bcopy(&args
->buf
, unptr
, sizeof(struct msqid_ds
));
605 bsd_cmd
= args
->cmd
& ~LINUX_IPC_64
;
606 bsd_args
.sysmsg_result
= 0;
607 bsd_args
.msqid
= args
->msqid
;
608 bsd_args
.cmd
= bsd_cmd
;
609 bsd_args
.buf
= unptr
;
612 case LINUX_MSG_INFO
: {
613 struct l_msginfo linux_msginfo
;
616 * XXX MSG_INFO uses the same data structure but returns different
617 * dynamic counters in msgpool, msgmap, and msgtql fields.
619 linux_msginfo
.msgpool
= (long)msginfo
.msgmni
*
620 (long)msginfo
.msgmnb
/ 1024L; /* XXX MSG_INFO. */
621 linux_msginfo
.msgmap
= msginfo
.msgmnb
; /* XXX MSG_INFO. */
622 linux_msginfo
.msgmax
= msginfo
.msgmax
;
623 linux_msginfo
.msgmnb
= msginfo
.msgmnb
;
624 linux_msginfo
.msgmni
= msginfo
.msgmni
;
625 linux_msginfo
.msgssz
= msginfo
.msgssz
;
626 linux_msginfo
.msgtql
= msginfo
.msgtql
; /* XXX MSG_INFO. */
627 linux_msginfo
.msgseg
= msginfo
.msgseg
;
628 error
= copyout(&linux_msginfo
, PTRIN(args
->buf
),
629 sizeof(linux_msginfo
));
631 args
->sysmsg_iresult
= msginfo
.msgmni
; /* XXX */
637 * TODO: implement this
638 * case LINUX_MSG_STAT:
645 error
= linux_msqid_pullup(args
->cmd
& LINUX_IPC_64
,
646 &linux_msqid
, (caddr_t
)(args
->buf
));
649 linux_to_bsd_msqid_ds(&linux_msqid
, unptr
);
661 error
= sys_msgctl(&bsd_args
);
663 if (bsd_cmd
!= LINUX_IPC_RMID
|| error
!= EINVAL
)
665 if (bsd_cmd
== LINUX_IPC_STAT
) {
666 bsd_to_linux_msqid_ds(bsd_args
.buf
, &linux_msqid
);
667 return (linux_msqid_pushdown(args
->cmd
& LINUX_IPC_64
,
668 &linux_msqid
, PTRIN(args
->buf
)));
670 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
671 return ((args
->cmd
== LINUX_IPC_RMID
&& error
== EINVAL
) ? 0 : error
);
682 linux_shmat(struct linux_shmat_args
*args
)
684 struct shmat_args bsd_args
;
687 bsd_args
.sysmsg_result
= 0;
688 bsd_args
.shmid
= args
->shmid
;
689 bsd_args
.shmaddr
= args
->shmaddr
;
690 bsd_args
.shmflg
= args
->shmflg
;
691 if ((error
= sys_shmat(&bsd_args
)))
694 if ((error
= copyout(&bsd_args
.sysmsg_lresult
, (caddr_t
)args
->raddr
, sizeof(l_ulong
))))
696 args
->sysmsg_result
= 0;
698 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
707 linux_shmdt(struct linux_shmdt_args
*args
)
709 struct shmdt_args bsd_args
;
712 bsd_args
.sysmsg_result
= 0;
713 bsd_args
.shmaddr
= args
->shmaddr
;
714 error
= sys_shmdt(&bsd_args
);
715 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
723 linux_shmget(struct linux_shmget_args
*args
)
725 struct shmget_args bsd_args
;
728 bsd_args
.sysmsg_result
= 0;
729 bsd_args
.key
= args
->key
;
730 bsd_args
.size
= args
->size
;
731 bsd_args
.shmflg
= args
->shmflg
;
732 error
= sys_shmget(&bsd_args
);
733 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
740 extern int shm_nused
;
742 linux_shmctl(struct linux_shmctl_args
*args
)
744 struct l_shmid_ds linux_shmid
;
745 struct l_shminfo linux_shminfo
;
746 struct l_shm_info linux_shm_info
;
747 struct shmctl_args bsd_args
;
749 caddr_t sg
= stackgap_init();
751 bsd_args
.sysmsg_result
= 0;
752 switch (args
->cmd
& ~LINUX_IPC_64
) {
755 bsd_args
.shmid
= args
->shmid
;
756 bsd_args
.cmd
= IPC_STAT
;
757 bsd_args
.buf
= (struct shmid_ds
*)stackgap_alloc(&sg
, sizeof(struct shmid_ds
));
758 if ((error
= sys_shmctl(&bsd_args
)))
760 bsd_to_linux_shmid_ds(bsd_args
.buf
, &linux_shmid
);
761 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
762 return (linux_shmid_pushdown(args
->cmd
& LINUX_IPC_64
,
763 &linux_shmid
, PTRIN(args
->buf
)));
766 if ((error
= linux_shmid_pullup(args
->cmd
& LINUX_IPC_64
,
767 &linux_shmid
, PTRIN(args
->buf
))))
769 bsd_args
.buf
= (struct shmid_ds
*)stackgap_alloc(&sg
, sizeof(struct shmid_ds
));
770 linux_to_bsd_shmid_ds(&linux_shmid
, bsd_args
.buf
);
771 bsd_args
.shmid
= args
->shmid
;
772 bsd_args
.cmd
= IPC_SET
;
775 bsd_args
.shmid
= args
->shmid
;
776 bsd_args
.cmd
= IPC_RMID
;
777 if (args
->buf
== NULL
)
780 if ((error
= linux_shmid_pullup(args
->cmd
& LINUX_IPC_64
,
781 &linux_shmid
, PTRIN(args
->buf
))))
783 bsd_args
.buf
= (struct shmid_ds
*)stackgap_alloc(&sg
, sizeof(struct shmid_ds
));
784 linux_to_bsd_shmid_ds(&linux_shmid
, bsd_args
.buf
);
788 bsd_to_linux_shminfo(&shminfo
, &linux_shminfo
);
789 return (linux_shminfo_pushdown(args
->cmd
& LINUX_IPC_64
,
790 &linux_shminfo
, PTRIN(args
->buf
)));
793 linux_shm_info
.used_ids
= shm_nused
;
794 linux_shm_info
.shm_tot
= 0;
795 linux_shm_info
.shm_rss
= 0;
796 linux_shm_info
.shm_swp
= 0;
797 linux_shm_info
.swap_attempts
= 0;
798 linux_shm_info
.swap_successes
= 0;
799 return copyout(&linux_shm_info
, PTRIN(args
->buf
),
800 sizeof(struct l_shm_info
));
803 case LINUX_SHM_UNLOCK
:
805 uprintf("linux: 'ipc' type=%d not implemented\n", args
->cmd
& ~LINUX_IPC_64
);
808 error
= sys_shmctl(&bsd_args
);
809 args
->sysmsg_result
= bsd_args
.sysmsg_result
;