linux_ipc.c revision 13264
1/*-
2 * Copyright (c) 1994-1995 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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
16 *
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.
27 *
28 *  $Id: linux_ipc.c,v 1.4 1995/12/29 22:12:14 sos Exp $
29 */
30
31#include "opt_sysvipc.h"
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/sysproto.h>
36#include <sys/proc.h>
37#include <sys/shm.h>
38
39#include <i386/linux/linux.h>
40#include <i386/linux/sysproto.h>
41
42struct linux_ipc_perm {
43    linux_key_t key;
44    unsigned short uid;
45    unsigned short gid;
46    unsigned short cuid;
47    unsigned short cgid;
48    unsigned short mode;
49    unsigned short seq;
50};
51
52static void
53linux_to_bsd_ipc_perm(struct linux_ipc_perm *lpp, struct ipc_perm *bpp)
54{
55    bpp->key = lpp->key;
56    bpp->uid = lpp->uid;
57    bpp->gid = lpp->gid;
58    bpp->cuid = lpp->cuid;
59    bpp->cgid = lpp->cgid;
60    bpp->mode = lpp->mode;
61    bpp->seq = lpp->seq;
62}
63
64
65static void
66bsd_to_linux_ipc_perm(struct ipc_perm *bpp, struct linux_ipc_perm *lpp)
67{
68    lpp->key = bpp->key;
69    lpp->uid = bpp->uid;
70    lpp->gid = bpp->gid;
71    lpp->cuid = bpp->cuid;
72    lpp->cgid = bpp->cgid;
73    lpp->mode = bpp->mode;
74    lpp->seq = bpp->seq;
75}
76
77struct linux_shmid_ds {
78    struct linux_ipc_perm shm_perm;
79    int shm_segsz;
80    linux_time_t shm_atime;
81    linux_time_t shm_dtime;
82    linux_time_t shm_ctime;
83    ushort shm_cpid;
84    ushort shm_lpid;
85    short shm_nattch;
86    ushort private1;
87    void *private2;
88    void *private3;
89};
90
91static void
92linux_to_bsd_shmid_ds(struct linux_shmid_ds *lsp, struct shmid_ds *bsp)
93{
94    linux_to_bsd_ipc_perm(&lsp->shm_perm, &bsp->shm_perm);
95    bsp->shm_segsz = lsp->shm_segsz;
96    bsp->shm_lpid = lsp->shm_lpid;
97    bsp->shm_cpid = lsp->shm_cpid;
98    bsp->shm_nattch = lsp->shm_nattch;
99    bsp->shm_atime = lsp->shm_atime;
100    bsp->shm_dtime = lsp->shm_dtime;
101    bsp->shm_ctime = lsp->shm_ctime;
102    bsp->shm_internal = lsp->private3;	/* this goes (yet) SOS */
103}
104
105static void
106bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct linux_shmid_ds *lsp)
107{
108    bsd_to_linux_ipc_perm(&bsp->shm_perm, &lsp->shm_perm);
109    lsp->shm_segsz = bsp->shm_segsz;
110    lsp->shm_lpid = bsp->shm_lpid;
111    lsp->shm_cpid = bsp->shm_cpid;
112    lsp->shm_nattch = bsp->shm_nattch;
113    lsp->shm_atime = bsp->shm_atime;
114    lsp->shm_dtime = bsp->shm_dtime;
115    lsp->shm_ctime = bsp->shm_ctime;
116    lsp->private3 = bsp->shm_internal;	/* this goes (yet) SOS */
117}
118
119struct linux_ipc_args {
120    int what;
121    int arg1;
122    int arg2;
123    int arg3;
124    caddr_t ptr;
125};
126
127int
128linux_semop(struct proc *p, struct linux_ipc_args *args, int *retval)
129{
130    return ENOSYS;
131}
132
133int
134linux_semget(struct proc *p, struct linux_ipc_args *args, int *retval)
135{
136    return ENOSYS;
137}
138
139int
140linux_semctl(struct proc *p, struct linux_ipc_args *args, int *retval)
141{
142    return ENOSYS;
143}
144
145int
146linux_msgsnd(struct proc *p, struct linux_ipc_args *args, int *retval)
147{
148    struct msgsnd_args /* {
149	int     msqid;
150	void    *msgp;
151	size_t  msgsz;
152	int     msgflg;
153    } */ bsd_args;
154
155    bsd_args.msqid = args->arg1;
156    bsd_args.msgp = args->ptr;
157    bsd_args.msgsz = args->arg2;
158    bsd_args.msgflg = args->arg3;
159    return msgsnd(p, &bsd_args, retval);
160}
161
162int
163linux_msgrcv(struct proc *p, struct linux_ipc_args *args, int *retval)
164{
165    struct msgrcv_args /* {
166        int 	msqid;
167	void	*msgp;
168	size_t	msgsz;
169	long	msgtyp;
170	int	msgflg;
171    } */ bsd_args;
172
173    bsd_args.msqid = args->arg1;
174    bsd_args.msgp = args->ptr;
175    bsd_args.msgsz = args->arg2;
176    bsd_args.msgtyp = 0;
177    bsd_args.msgflg = args->arg3;
178    return msgrcv(p, &bsd_args, retval);
179}
180
181int
182linux_msgget(struct proc *p, struct linux_ipc_args *args, int *retval)
183{
184    struct msgget_args /* {
185	key_t	key;
186        int 	msgflg;
187    } */ bsd_args;
188
189    bsd_args.key = args->arg1;
190    bsd_args.msgflg = args->arg2;
191    return msgget(p, &bsd_args, retval);
192}
193
194int
195linux_msgctl(struct proc *p, struct linux_ipc_args *args, int *retval)
196{
197    struct msgctl_args /* {
198	int     msqid;
199	int     cmd;
200	struct	msqid_ds *buf;
201    } */ bsd_args;
202
203    bsd_args.msqid = args->arg1;
204    bsd_args.cmd = args->arg2;
205    bsd_args.buf = (struct msqid_ds *)args->ptr;
206    return msgctl(p, &bsd_args, retval);
207}
208
209int
210linux_shmat(struct proc *p, struct linux_ipc_args *args, int *retval)
211{
212    struct shmat_args /* {
213	int shmid;
214	void *shmaddr;
215	int shmflg;
216    } */ bsd_args;
217    int error;
218
219    bsd_args.shmid = args->arg1;
220    bsd_args.shmaddr = args->ptr;
221    bsd_args.shmflg = args->arg2;
222    if ((error = shmat(p, &bsd_args, retval)))
223	return error;
224    if ((error = copyout(retval, (caddr_t)args->arg3, sizeof(int))))
225	return error;
226    retval[0] = 0;
227    return 0;
228}
229
230int
231linux_shmdt(struct proc *p, struct linux_ipc_args *args, int *retval)
232{
233    struct shmdt_args /* {
234	void *shmaddr;
235    } */ bsd_args;
236
237    bsd_args.shmaddr = args->ptr;
238    return shmdt(p, &bsd_args, retval);
239}
240
241int
242linux_shmget(struct proc *p, struct linux_ipc_args *args, int *retval)
243{
244    struct shmget_args /* {
245	key_t key;
246	int size;
247	int shmflg;
248    } */ bsd_args;
249
250    bsd_args.key = args->arg1;
251    bsd_args.size = args->arg2;
252    bsd_args.shmflg = args->arg3;
253    return shmget(p, &bsd_args, retval);
254}
255
256int
257linux_shmctl(struct proc *p, struct linux_ipc_args *args, int *retval)
258{
259    struct shmid_ds bsd_shmid;
260    struct linux_shmid_ds linux_shmid;
261    struct shmctl_args /* {
262	int shmid;
263	int cmd;
264	struct shmid_ds *buf;
265    } */ bsd_args;
266    int error;
267
268    switch (args->arg2) {
269    case LINUX_IPC_STAT:
270	bsd_args.shmid = args->arg1;
271	bsd_args.cmd = IPC_STAT;
272	bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
273	if ((error = shmctl(p, &bsd_args, retval)))
274	    return error;
275	if ((error = copyin((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
276		    	    sizeof(struct shmid_ds))))
277	    return error;
278	bsd_to_linux_shmid_ds(&bsd_shmid, &linux_shmid);
279	return copyout((caddr_t)&linux_shmid, args->ptr, sizeof(linux_shmid));
280
281    case LINUX_IPC_SET:
282	if ((error = copyin(args->ptr, (caddr_t)&linux_shmid,
283		    	    sizeof(linux_shmid))))
284	    return error;
285	linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
286	bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
287	if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
288		     	     sizeof(struct shmid_ds))))
289	    return error;
290	bsd_args.shmid = args->arg1;
291	bsd_args.cmd = IPC_SET;
292	return shmctl(p, &bsd_args, retval);
293
294    case LINUX_IPC_RMID:
295	bsd_args.shmid = args->arg1;
296	bsd_args.cmd = IPC_RMID;
297	if ((error = copyin(args->ptr, (caddr_t)&linux_shmid,
298		    	    sizeof(linux_shmid))))
299	    return error;
300	linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
301	bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
302	if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
303		     	     sizeof(struct shmid_ds))))
304	    return error;
305	return shmctl(p, &bsd_args, retval);
306
307    case LINUX_IPC_INFO:
308    case LINUX_SHM_STAT:
309    case LINUX_SHM_INFO:
310    case LINUX_SHM_LOCK:
311    case LINUX_SHM_UNLOCK:
312    default:
313	uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what);
314	return EINVAL;
315    }
316}
317
318int
319linux_ipc(struct proc *p, struct linux_ipc_args *args, int *retval)
320{
321    switch (args->what) {
322    case LINUX_SEMOP:
323	return linux_semop(p, args, retval);
324    case LINUX_SEMGET:
325	return linux_semget(p, args, retval);
326    case LINUX_SEMCTL:
327	return linux_semctl(p, args, retval);
328    case LINUX_MSGSND:
329	return linux_msgsnd(p, args, retval);
330    case LINUX_MSGRCV:
331	return linux_msgrcv(p, args, retval);
332    case LINUX_MSGGET:
333	return linux_msgget(p, args, retval);
334    case LINUX_MSGCTL:
335	return linux_msgctl(p, args, retval);
336    case LINUX_SHMAT:
337	return linux_shmat(p, args, retval);
338    case LINUX_SHMDT:
339	return linux_shmdt(p, args, retval);
340    case LINUX_SHMGET:
341	return linux_shmget(p, args, retval);
342    case LINUX_SHMCTL:
343	return linux_shmctl(p, args, retval);
344    default:
345	uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what);
346	return ENOSYS;
347    }
348}
349