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
;
85 linux_to_bsd_ipc_perm(struct l_ipc_perm
*lpp
, struct ipc_perm
*bpp
)
90 bpp
->cuid
= lpp
->cuid
;
91 bpp
->cgid
= lpp
->cgid
;
92 bpp
->mode
= lpp
->mode
;
98 bsd_to_linux_ipc_perm(struct ipc_perm
*bpp
, struct l_ipc_perm
*lpp
)
103 lpp
->cuid
= bpp
->cuid
;
104 lpp
->cgid
= bpp
->cgid
;
105 lpp
->mode
= bpp
->mode
;
110 struct l_ipc_perm sem_perm
;
115 void *sem_pending_last
;
121 struct l_ipc_perm shm_perm
;
135 linux_to_bsd_semid_ds(struct l_semid_ds
*lsp
, struct semid_ds
*bsp
)
137 linux_to_bsd_ipc_perm(&lsp
->sem_perm
, &bsp
->sem_perm
);
138 bsp
->sem_otime
= lsp
->sem_otime
;
139 bsp
->sem_ctime
= lsp
->sem_ctime
;
140 bsp
->sem_nsems
= lsp
->sem_nsems
;
141 bsp
->sem_base
= lsp
->sem_base
;
145 bsd_to_linux_semid_ds(struct semid_ds
*bsp
, struct l_semid_ds
*lsp
)
147 bsd_to_linux_ipc_perm(&bsp
->sem_perm
, &lsp
->sem_perm
);
148 lsp
->sem_otime
= bsp
->sem_otime
;
149 lsp
->sem_ctime
= bsp
->sem_ctime
;
150 lsp
->sem_nsems
= bsp
->sem_nsems
;
151 lsp
->sem_base
= bsp
->sem_base
;
155 linux_to_bsd_shmid_ds(struct l_shmid_ds
*lsp
, struct shmid_ds
*bsp
)
157 linux_to_bsd_ipc_perm(&lsp
->shm_perm
, &bsp
->shm_perm
);
158 bsp
->shm_segsz
= lsp
->shm_segsz
;
159 bsp
->shm_lpid
= lsp
->shm_lpid
;
160 bsp
->shm_cpid
= lsp
->shm_cpid
;
161 bsp
->shm_nattch
= lsp
->shm_nattch
;
162 bsp
->shm_atime
= lsp
->shm_atime
;
163 bsp
->shm_dtime
= lsp
->shm_dtime
;
164 bsp
->shm_ctime
= lsp
->shm_ctime
;
165 bsp
->shm_internal
= lsp
->private3
; /* this goes (yet) SOS */
169 bsd_to_linux_shmid_ds(struct shmid_ds
*bsp
, struct l_shmid_ds
*lsp
)
171 bsd_to_linux_ipc_perm(&bsp
->shm_perm
, &lsp
->shm_perm
);
172 lsp
->shm_segsz
= bsp
->shm_segsz
;
173 lsp
->shm_lpid
= bsp
->shm_lpid
;
174 lsp
->shm_cpid
= bsp
->shm_cpid
;
175 lsp
->shm_nattch
= bsp
->shm_nattch
;
176 lsp
->shm_atime
= bsp
->shm_atime
;
177 lsp
->shm_dtime
= bsp
->shm_dtime
;
178 lsp
->shm_ctime
= bsp
->shm_ctime
;
179 lsp
->private3
= bsp
->shm_internal
; /* this goes (yet) SOS */
183 linux_semop(struct linux_semop_args
*args
)
185 struct semop_args bsd_args
;
188 bsd_args
.sysmsg_result
= 0;
189 bsd_args
.semid
= args
->semid
;
190 bsd_args
.sops
= (struct sembuf
*)args
->tsops
;
191 bsd_args
.nsops
= args
->nsops
;
192 error
= sys_semop(&bsd_args
);
193 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
198 linux_semget(struct linux_semget_args
*args
)
200 struct semget_args bsd_args
;
203 bsd_args
.sysmsg_result
= 0;
204 bsd_args
.key
= args
->key
;
205 bsd_args
.nsems
= args
->nsems
;
206 bsd_args
.semflg
= args
->semflg
;
207 error
= sys_semget(&bsd_args
);
208 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
213 linux_semctl(struct linux_semctl_args
*args
)
215 struct l_semid_ds linux_semid
;
216 struct __semctl_args bsd_args
;
217 struct l_seminfo linux_seminfo
;
222 sg
= stackgap_init();
224 /* Make sure the arg parameter can be copied in. */
225 unptr
= stackgap_alloc(&sg
, sizeof(union semun
));
226 bcopy(&args
->arg
, unptr
, sizeof(union semun
));
228 bsd_args
.sysmsg_result
= 0;
229 bsd_args
.semid
= args
->semid
;
230 bsd_args
.semnum
= args
->semnum
;
231 bsd_args
.arg
= unptr
;
235 bsd_args
.cmd
= IPC_RMID
;
238 bsd_args
.cmd
= GETNCNT
;
241 bsd_args
.cmd
= GETPID
;
244 bsd_args
.cmd
= GETVAL
;
247 bsd_args
.cmd
= GETZCNT
;
250 bsd_args
.cmd
= SETVAL
;
253 bsd_args
.cmd
= IPC_SET
;
254 error
= copyin((caddr_t
)args
->arg
.buf
, &linux_semid
,
255 sizeof(linux_semid
));
258 unptr
->buf
= stackgap_alloc(&sg
, sizeof(struct semid_ds
));
259 linux_to_bsd_semid_ds(&linux_semid
, unptr
->buf
);
262 bsd_args
.cmd
= IPC_STAT
;
263 unptr
->buf
= stackgap_alloc(&sg
, sizeof(struct semid_ds
));
264 error
= sys___semctl(&bsd_args
);
267 args
->sysmsg_result
= IXSEQ_TO_IPCID(bsd_args
.semid
,
268 unptr
->buf
->sem_perm
);
269 bsd_to_linux_semid_ds(unptr
->buf
, &linux_semid
);
270 return copyout(&linux_semid
, (caddr_t
)args
->arg
.buf
,
271 sizeof(linux_semid
));
274 error
= copyin((caddr_t
)args
->arg
.buf
, &linux_seminfo
,
275 sizeof(linux_seminfo
) );
278 bcopy(&seminfo
, &linux_seminfo
, sizeof(linux_seminfo
) );
279 /* XXX BSD equivalent?
280 #define used_semids 10
282 linux_seminfo.semusz = used_semids;
283 linux_seminfo.semaem = used_sems;
285 error
= copyout((caddr_t
)&linux_seminfo
, (caddr_t
)args
->arg
.buf
,
286 sizeof(linux_seminfo
) );
289 args
->sysmsg_result
= seminfo
.semmni
;
290 return 0; /* No need for __semctl call */
296 uprintf("linux: 'ipc' typ=%d not implemented\n", args
->cmd
);
299 error
= sys___semctl(&bsd_args
);
300 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
305 linux_msgsnd(struct linux_msgsnd_args
*args
)
307 struct msgsnd_args bsd_args
;
310 bsd_args
.sysmsg_result
= 0;
311 bsd_args
.msqid
= args
->msqid
;
312 bsd_args
.msgp
= args
->msgp
;
313 bsd_args
.msgsz
= args
->msgsz
;
314 bsd_args
.msgflg
= args
->msgflg
;
315 error
= sys_msgsnd(&bsd_args
);
316 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
321 linux_msgrcv(struct linux_msgrcv_args
*args
)
323 struct msgrcv_args bsd_args
;
326 bsd_args
.sysmsg_result
= 0;
327 bsd_args
.msqid
= args
->msqid
;
328 bsd_args
.msgp
= args
->msgp
;
329 bsd_args
.msgsz
= args
->msgsz
;
330 bsd_args
.msgtyp
= 0; /* XXX - args->msgtyp; */
331 bsd_args
.msgflg
= args
->msgflg
;
332 error
= sys_msgrcv(&bsd_args
);
333 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
338 linux_msgget(struct linux_msgget_args
*args
)
340 struct msgget_args bsd_args
;
343 bsd_args
.sysmsg_result
= 0;
344 bsd_args
.key
= args
->key
;
345 bsd_args
.msgflg
= args
->msgflg
;
346 error
= sys_msgget(&bsd_args
);
347 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
352 linux_msgctl(struct linux_msgctl_args
*args
)
354 struct msgctl_args bsd_args
;
357 bsd_args
.sysmsg_result
= 0;
358 bsd_args
.msqid
= args
->msqid
;
359 bsd_args
.cmd
= args
->cmd
;
360 bsd_args
.buf
= (struct msqid_ds
*)args
->buf
;
361 error
= sys_msgctl(&bsd_args
);
362 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
363 return ((args
->cmd
== LINUX_IPC_RMID
&& error
== EINVAL
) ? 0 : error
);
367 linux_shmat(struct linux_shmat_args
*args
)
369 struct shmat_args bsd_args
;
372 bsd_args
.sysmsg_result
= 0;
373 bsd_args
.shmid
= args
->shmid
;
374 bsd_args
.shmaddr
= args
->shmaddr
;
375 bsd_args
.shmflg
= args
->shmflg
;
376 if ((error
= sys_shmat(&bsd_args
)))
379 if ((error
= copyout(&bsd_args
.sysmsg_lresult
, (caddr_t
)args
->raddr
, sizeof(l_ulong
))))
381 args
->sysmsg_result
= 0;
383 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
389 linux_shmdt(struct linux_shmdt_args
*args
)
391 struct shmdt_args bsd_args
;
394 bsd_args
.sysmsg_result
= 0;
395 bsd_args
.shmaddr
= args
->shmaddr
;
396 error
= sys_shmdt(&bsd_args
);
397 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
402 linux_shmget(struct linux_shmget_args
*args
)
404 struct shmget_args bsd_args
;
407 bsd_args
.sysmsg_result
= 0;
408 bsd_args
.key
= args
->key
;
409 bsd_args
.size
= args
->size
;
410 bsd_args
.shmflg
= args
->shmflg
;
411 error
= sys_shmget(&bsd_args
);
412 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
417 linux_shmctl(struct linux_shmctl_args
*args
)
419 struct l_shmid_ds linux_shmid
;
420 struct shmctl_args bsd_args
;
422 caddr_t sg
= stackgap_init();
424 bsd_args
.sysmsg_result
= 0;
427 bsd_args
.shmid
= args
->shmid
;
428 bsd_args
.cmd
= IPC_STAT
;
429 bsd_args
.buf
= (struct shmid_ds
*)stackgap_alloc(&sg
, sizeof(struct shmid_ds
));
430 if ((error
= sys_shmctl(&bsd_args
)))
432 bsd_to_linux_shmid_ds(bsd_args
.buf
, &linux_shmid
);
433 args
->sysmsg_result
= bsd_args
.sysmsg_result
;
434 return copyout(&linux_shmid
, (caddr_t
)args
->buf
, sizeof(linux_shmid
));
437 if ((error
= copyin((caddr_t
)args
->buf
, &linux_shmid
,
438 sizeof(linux_shmid
))))
440 bsd_args
.buf
= (struct shmid_ds
*)stackgap_alloc(&sg
, sizeof(struct shmid_ds
));
441 linux_to_bsd_shmid_ds(&linux_shmid
, bsd_args
.buf
);
442 bsd_args
.shmid
= args
->shmid
;
443 bsd_args
.cmd
= IPC_SET
;
446 bsd_args
.shmid
= args
->shmid
;
447 bsd_args
.cmd
= IPC_RMID
;
448 if (args
->buf
== NULL
)
451 if ((error
= copyin((caddr_t
)args
->buf
, &linux_shmid
,
452 sizeof(linux_shmid
))))
454 bsd_args
.buf
= (struct shmid_ds
*)stackgap_alloc(&sg
, sizeof(struct shmid_ds
));
455 linux_to_bsd_shmid_ds(&linux_shmid
, bsd_args
.buf
);
462 case LINUX_SHM_UNLOCK
:
464 uprintf("linux: 'ipc' typ=%d not implemented\n", args
->cmd
);
467 error
= sys_shmctl(&bsd_args
);
468 args
->sysmsg_result
= bsd_args
.sysmsg_result
;