xref: /freebsd/sys/compat/linux/linux_ipc.c (revision 8e6b01171e30297084bb0b4457c4183c2746aacc)
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.2 1995/06/07 21:27:57 sos Exp $
29  */
30 
31 #include <i386/linux/linux.h>
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/exec.h>
35 #include <sys/proc.h>
36 #include <sys/sem.h>
37 #include <sys/shm.h>
38 #include <sys/msg.h>
39 
40 #include <vm/vm.h>
41 
42 struct 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 
52 static void
53 linux_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 
65 static void
66 bsd_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 
77 struct 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 
91 static void
92 linux_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 
105 static void
106 bsd_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 
119 struct linux_ipc_args {
120     int what;
121     int arg1;
122     int arg2;
123     int arg3;
124     caddr_t ptr;
125 };
126 
127 int
128 linux_semop(struct proc *p, struct linux_ipc_args *args, int *retval)
129 {
130     return ENOSYS;
131 }
132 
133 int
134 linux_semget(struct proc *p, struct linux_ipc_args *args, int *retval)
135 {
136     return ENOSYS;
137 }
138 
139 int
140 linux_semctl(struct proc *p, struct linux_ipc_args *args, int *retval)
141 {
142     return ENOSYS;
143 }
144 
145 int
146 linux_msgsnd(struct proc *p, struct linux_ipc_args *args, int *retval)
147 {
148     return ENOSYS;
149 }
150 
151 int
152 linux_msgrcv(struct proc *p, struct linux_ipc_args *args, int *retval)
153 {
154     return ENOSYS;
155 }
156 
157 int
158 linux_msgget(struct proc *p, struct linux_ipc_args *args, int *retval)
159 {
160     return ENOSYS;
161 }
162 
163 int
164 linux_msgctl(struct proc *p, struct linux_ipc_args *args, int *retval)
165 {
166     return ENOSYS;
167 }
168 
169 int
170 linux_shmat(struct proc *p, struct linux_ipc_args *args, int *retval)
171 {
172     struct shmat_args {
173 	int shmid;
174 	void *shmaddr;
175 	int shmflg;
176     } bsd_args;
177     int error;
178 
179     bsd_args.shmid = args->arg1;
180     bsd_args.shmaddr = args->ptr;
181     bsd_args.shmflg = args->arg2;
182     if ((error = shmat(p, &bsd_args, retval)))
183 	return error;
184     if ((error = copyout(retval, (caddr_t)args->arg3, sizeof(int))))
185 	return error;
186     retval[0] = 0;
187     return 0;
188 }
189 
190 int
191 linux_shmdt(struct proc *p, struct linux_ipc_args *args, int *retval)
192 {
193     struct shmdt_args {
194 	void *shmaddr;
195     } bsd_args;
196 
197     bsd_args.shmaddr = args->ptr;
198     return shmdt(p, &bsd_args, retval);
199 }
200 
201 int
202 linux_shmget(struct proc *p, struct linux_ipc_args *args, int *retval)
203 {
204     struct shmget_args {
205 	key_t key;
206 	int size;
207 	int shmflg;
208     } bsd_args;
209 
210     bsd_args.key = args->arg1;
211     bsd_args.size = args->arg2;
212     bsd_args.shmflg = args->arg3;
213     return shmget(p, &bsd_args, retval);
214 }
215 
216 int
217 linux_shmctl(struct proc *p, struct linux_ipc_args *args, int *retval)
218 {
219     struct shmid_ds bsd_shmid;
220     struct linux_shmid_ds linux_shmid;
221     struct shmctl_args {
222 	int shmid;
223 	int cmd;
224 	struct shmid_ds *buf;
225     } bsd_args;
226     int error;
227 
228     switch (args->arg2) {
229     case LINUX_IPC_STAT:
230 	bsd_args.shmid = args->arg1;
231 	bsd_args.cmd = IPC_STAT;
232 	bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
233 	if ((error = shmctl(p, &bsd_args, retval)))
234 	    return error;
235 	if ((error = copyin((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
236 		    	    sizeof(struct shmid_ds))))
237 	    return error;
238 	bsd_to_linux_shmid_ds(&bsd_shmid, &linux_shmid);
239 	return copyout((caddr_t)&linux_shmid, args->ptr, sizeof(linux_shmid));
240 
241     case LINUX_IPC_SET:
242 	if ((error = copyin(args->ptr, (caddr_t)&linux_shmid,
243 		    	    sizeof(linux_shmid))))
244 	    return error;
245 	linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
246 	bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
247 	if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
248 		     	     sizeof(struct shmid_ds))))
249 	    return error;
250 	bsd_args.shmid = args->arg1;
251 	bsd_args.cmd = IPC_SET;
252 	return shmctl(p, &bsd_args, retval);
253 
254     case LINUX_IPC_RMID:
255 	bsd_args.shmid = args->arg1;
256 	bsd_args.cmd = IPC_RMID;
257 	if ((error = copyin(args->ptr, (caddr_t)&linux_shmid,
258 		    	    sizeof(linux_shmid))))
259 	    return error;
260 	linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
261 	bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
262 	if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
263 		     	     sizeof(struct shmid_ds))))
264 	    return error;
265 	return shmctl(p, &bsd_args, retval);
266 
267     case LINUX_IPC_INFO:
268     case LINUX_SHM_STAT:
269     case LINUX_SHM_INFO:
270     case LINUX_SHM_LOCK:
271     case LINUX_SHM_UNLOCK:
272     default:
273 	uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what);
274 	return EINVAL;
275     }
276 }
277 
278 int
279 linux_ipc(struct proc *p, struct linux_ipc_args *args, int *retval)
280 {
281     switch (args->what) {
282     case LINUX_SEMOP:
283 	return linux_semop(p, args, retval);
284     case LINUX_SEMGET:
285 	return linux_semget(p, args, retval);
286     case LINUX_SEMCTL:
287 	return linux_semctl(p, args, retval);
288     case LINUX_MSGSND:
289 	return linux_msgsnd(p, args, retval);
290     case LINUX_MSGRCV:
291 	return linux_msgrcv(p, args, retval);
292     case LINUX_MSGGET:
293 	return linux_msgget(p, args, retval);
294     case LINUX_MSGCTL:
295 	return linux_msgctl(p, args, retval);
296     case LINUX_SHMAT:
297 	return linux_shmat(p, args, retval);
298     case LINUX_SHMDT:
299 	return linux_shmdt(p, args, retval);
300     case LINUX_SHMGET:
301 	return linux_shmget(p, args, retval);
302     case LINUX_SHMCTL:
303 	return linux_shmctl(p, args, retval);
304     default:
305 	uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what);
306 	return ENOSYS;
307     }
308 }
309