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