fe47a8b52e30ed45fd7cdb4432430e963e5d7fae
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>
39 #include <arch_linux/linux.h>
40 #include <arch_linux/linux_proto.h>
41 #include "linux_ipc.h"
42 #include "linux_util.h"
67 l_ulong shm_tot
; /* total allocated shm */
68 l_ulong shm_rss
; /* total resident shm */
69 l_ulong shm_swp
; /* total swapped shm */
70 l_ulong swap_attempts
;
71 l_ulong swap_successes
;
88 linux_to_bsd_ipc_perm(struct l_ipc_perm
*lpp
, struct ipc_perm
*bpp
)
93 bpp
->cuid
= lpp
->cuid
;
94 bpp
->cgid
= lpp
->cgid
;
95 bpp
->mode
= lpp
->mode
;
103 bsd_to_linux_ipc_perm(struct ipc_perm
*bpp
, struct l_ipc_perm
*lpp
)
108 lpp
->cuid
= bpp
->cuid
;
109 lpp
->cgid
= bpp
->cgid
;
110 lpp
->mode
= bpp
->mode
;
115 struct l_ipc_perm sem_perm
;
120 void *sem_pending_last
;
126 struct l_ipc_perm shm_perm
;
143 linux_to_bsd_semid_ds(struct l_semid_ds
*lsp
, struct semid_ds
*bsp
)
145 linux_to_bsd_ipc_perm(&lsp
->sem_perm
, &bsp
->sem_perm
);
146 bsp
->sem_otime
= lsp
->sem_otime
;
147 bsp
->sem_ctime
= lsp
->sem_ctime
;
148 bsp
->sem_nsems
= lsp
->sem_nsems
;
149 bsp
->sem_base
= lsp
->sem_base
;
156 bsd_to_linux_semid_ds(struct semid_ds
*bsp
, struct l_semid_ds
*lsp
)
158 bsd_to_linux_ipc_perm(&bsp
->sem_perm
, &lsp
->sem_perm
);
159 lsp
->sem_otime
= bsp
->sem_otime
;
160 lsp
->sem_ctime
= bsp
->sem_ctime
;
161 lsp
->sem_nsems
= bsp
->sem_nsems
;
162 lsp
->sem_base
= bsp
->sem_base
;
169 linux_to_bsd_shmid_ds(struct l_shmid_ds
*lsp
, struct shmid_ds
*bsp
)
171 linux_to_bsd_ipc_perm(&lsp
->shm_perm
, &bsp
->shm_perm
);
172 bsp
->shm_segsz
= lsp
->shm_segsz
;
173 bsp
->shm_lpid
= lsp
->shm_lpid
;
174 bsp
->shm_cpid
= lsp
->shm_cpid
;
175 bsp
->shm_nattch
= lsp
->shm_nattch
;
176 bsp
->shm_atime
= lsp
->shm_atime
;
177 bsp
->shm_dtime
= lsp
->shm_dtime
;
178 bsp
->shm_ctime
= lsp
->shm_ctime
;
179 bsp
->shm_internal
= lsp
->private3
; /* this goes (yet) SOS */
186 bsd_to_linux_shmid_ds(struct shmid_ds
*bsp
, struct l_shmid_ds
*lsp
)
188 bsd_to_linux_ipc_perm(&bsp
->shm_perm
, &lsp
->shm_perm
);
189 lsp
->shm_segsz
= bsp
->shm_segsz
;
190 lsp
->shm_lpid
= bsp
->shm_lpid
;
191 lsp
->shm_cpid
= bsp
->shm_cpid
;
192 lsp
->shm_nattch
= bsp
->shm_nattch
;
193 lsp
->shm_atime
= bsp
->shm_atime
;
194 lsp
->shm_dtime
= bsp
->shm_dtime
;
195 lsp
->shm_ctime
= bsp
->shm_ctime
;
196 lsp
->private3
= bsp
->shm_internal
; /* this goes (yet) SOS */
203 linux_semop(struct linux_semop_args
*args
)
205 struct semop_args bsd_args
;
208 bsd_args
.sysmsg_result
= 0;
209 bsd_args
.semid
= args
->semid
;
210 bsd_args
.sops
= (struct sembuf
*)args
->tsops
;
211 bsd_args
.nsops
= args
->nsops
;
212 error
= sys_semop(&bsd_args
);
213 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
221 linux_semget(struct linux_semget_args
*args
)
223 struct semget_args bsd_args
;
226 bsd_args
.sysmsg_result
= 0;
227 bsd_args
.key
= args
->key
;
228 bsd_args
.nsems
= args
->nsems
;
229 bsd_args
.semflg
= args
->semflg
;
230 error
= sys_semget(&bsd_args
);
231 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
239 linux_semctl(struct linux_semctl_args
*args
)
241 struct l_semid_ds linux_semid
;
242 struct __semctl_args bsd_args
;
243 struct l_seminfo linux_seminfo
;
248 sg
= stackgap_init();
250 /* Make sure the arg parameter can be copied in. */
251 unptr
= stackgap_alloc(&sg
, sizeof(union semun
));
252 bcopy(&args
->arg
, unptr
, sizeof(union semun
));
254 bsd_args
.sysmsg_result
= 0;
255 bsd_args
.semid
= args
->semid
;
256 bsd_args
.semnum
= args
->semnum
;
257 bsd_args
.arg
= unptr
;
261 bsd_args
.cmd
= IPC_RMID
;
264 bsd_args
.cmd
= GETNCNT
;
267 bsd_args
.cmd
= GETPID
;
270 bsd_args
.cmd
= GETVAL
;
273 bsd_args
.cmd
= GETZCNT
;
276 bsd_args
.cmd
= SETVAL
;
279 bsd_args
.cmd
= IPC_SET
;
280 error
= copyin((caddr_t
)args
->arg
.buf
, &linux_semid
,
281 sizeof(linux_semid
));
284 unptr
->buf
= stackgap_alloc(&sg
, sizeof(struct semid_ds
));
285 linux_to_bsd_semid_ds(&linux_semid
, unptr
->buf
);
288 bsd_args
.cmd
= IPC_STAT
;
289 unptr
->buf
= stackgap_alloc(&sg
, sizeof(struct semid_ds
));
290 error
= sys___semctl(&bsd_args
);
293 args
->sysmsg_result
= IXSEQ_TO_IPCID(bsd_args
.semid
,
294 unptr
->buf
->sem_perm
);
295 bsd_to_linux_semid_ds(unptr
->buf
, &linux_semid
);
296 return copyout(&linux_semid
, (caddr_t
)args
->arg
.buf
,
297 sizeof(linux_semid
));
300 error
= copyin((caddr_t
)args
->arg
.buf
, &linux_seminfo
,
301 sizeof(linux_seminfo
) );
304 bcopy(&seminfo
, &linux_seminfo
, sizeof(linux_seminfo
) );
305 /* XXX BSD equivalent?
306 #define used_semids 10
308 linux_seminfo.semusz = used_semids;
309 linux_seminfo.semaem = used_sems;
311 error
= copyout((caddr_t
)&linux_seminfo
, (caddr_t
)args
->arg
.buf
,
312 sizeof(linux_seminfo
) );
315 args
->sysmsg_result
= seminfo
.semmni
;
316 return 0; /* No need for __semctl call */
322 uprintf("linux: 'ipc' typ=%d not implemented\n", args
->cmd
);
325 error
= sys___semctl(&bsd_args
);
326 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
334 linux_msgsnd(struct linux_msgsnd_args
*args
)
336 struct msgsnd_args bsd_args
;
339 bsd_args
.sysmsg_result
= 0;
340 bsd_args
.msqid
= args
->msqid
;
341 bsd_args
.msgp
= args
->msgp
;
342 bsd_args
.msgsz
= args
->msgsz
;
343 bsd_args
.msgflg
= args
->msgflg
;
344 error
= sys_msgsnd(&bsd_args
);
345 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
353 linux_msgrcv(struct linux_msgrcv_args
*args
)
355 struct msgrcv_args bsd_args
;
358 bsd_args
.sysmsg_result
= 0;
359 bsd_args
.msqid
= args
->msqid
;
360 bsd_args
.msgp
= args
->msgp
;
361 bsd_args
.msgsz
= args
->msgsz
;
362 bsd_args
.msgtyp
= 0; /* XXX - args->msgtyp; */
363 bsd_args
.msgflg
= args
->msgflg
;
364 error
= sys_msgrcv(&bsd_args
);
365 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
373 linux_msgget(struct linux_msgget_args
*args
)
375 struct msgget_args bsd_args
;
378 bsd_args
.sysmsg_result
= 0;
379 bsd_args
.key
= args
->key
;
380 bsd_args
.msgflg
= args
->msgflg
;
381 error
= sys_msgget(&bsd_args
);
382 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
390 linux_msgctl(struct linux_msgctl_args
*args
)
392 struct msgctl_args bsd_args
;
395 bsd_args
.sysmsg_result
= 0;
396 bsd_args
.msqid
= args
->msqid
;
397 bsd_args
.cmd
= args
->cmd
;
398 bsd_args
.buf
= (struct msqid_ds
*)args
->buf
;
399 error
= sys_msgctl(&bsd_args
);
400 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
401 return ((args
->cmd
== LINUX_IPC_RMID
&& error
== EINVAL
) ? 0 : error
);
408 linux_shmat(struct linux_shmat_args
*args
)
410 struct shmat_args bsd_args
;
413 bsd_args
.sysmsg_result
= 0;
414 bsd_args
.shmid
= args
->shmid
;
415 bsd_args
.shmaddr
= args
->shmaddr
;
416 bsd_args
.shmflg
= args
->shmflg
;
417 if ((error
= sys_shmat(&bsd_args
)))
420 if ((error
= copyout(&bsd_args
.sysmsg_lresult
, (caddr_t
)args
->raddr
, sizeof(l_ulong
))))
422 args
->sysmsg_result
= 0;
424 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
433 linux_shmdt(struct linux_shmdt_args
*args
)
435 struct shmdt_args bsd_args
;
438 bsd_args
.sysmsg_result
= 0;
439 bsd_args
.shmaddr
= args
->shmaddr
;
440 error
= sys_shmdt(&bsd_args
);
441 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
449 linux_shmget(struct linux_shmget_args
*args
)
451 struct shmget_args bsd_args
;
454 bsd_args
.sysmsg_result
= 0;
455 bsd_args
.key
= args
->key
;
456 bsd_args
.size
= args
->size
;
457 bsd_args
.shmflg
= args
->shmflg
;
458 error
= sys_shmget(&bsd_args
);
459 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
467 linux_shmctl(struct linux_shmctl_args
*args
)
469 struct l_shmid_ds linux_shmid
;
470 struct shmctl_args bsd_args
;
472 caddr_t sg
= stackgap_init();
474 bsd_args
.sysmsg_result
= 0;
477 bsd_args
.shmid
= args
->shmid
;
478 bsd_args
.cmd
= IPC_STAT
;
479 bsd_args
.buf
= (struct shmid_ds
*)stackgap_alloc(&sg
, sizeof(struct shmid_ds
));
480 if ((error
= sys_shmctl(&bsd_args
)))
482 bsd_to_linux_shmid_ds(bsd_args
.buf
, &linux_shmid
);
483 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
484 return copyout(&linux_shmid
, (caddr_t
)args
->buf
, sizeof(linux_shmid
));
487 if ((error
= copyin((caddr_t
)args
->buf
, &linux_shmid
,
488 sizeof(linux_shmid
))))
490 bsd_args
.buf
= (struct shmid_ds
*)stackgap_alloc(&sg
, sizeof(struct shmid_ds
));
491 linux_to_bsd_shmid_ds(&linux_shmid
, bsd_args
.buf
);
492 bsd_args
.shmid
= args
->shmid
;
493 bsd_args
.cmd
= IPC_SET
;
496 bsd_args
.shmid
= args
->shmid
;
497 bsd_args
.cmd
= IPC_RMID
;
498 if (args
->buf
== NULL
)
501 if ((error
= copyin((caddr_t
)args
->buf
, &linux_shmid
,
502 sizeof(linux_shmid
))))
504 bsd_args
.buf
= (struct shmid_ds
*)stackgap_alloc(&sg
, sizeof(struct shmid_ds
));
505 linux_to_bsd_shmid_ds(&linux_shmid
, bsd_args
.buf
);
512 case LINUX_SHM_UNLOCK
:
514 uprintf("linux: 'ipc' typ=%d not implemented\n", args
->cmd
);
517 error
= sys_shmctl(&bsd_args
);
518 args
->sysmsg_result
= bsd_args
.sysmsg_result
;