xref: /netbsd-src/sys/compat/netbsd32/netbsd32_ipc.c (revision de2138164cd16145ee5fd4d0aef1e8f952c1a9fb)
1 /*	$NetBSD: netbsd32_ipc.c,v 1.10 2007/02/09 21:55:22 ad Exp $	*/
2 
3 /*
4  * Copyright (c) 1998, 2001 Matthew R. Green
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: netbsd32_ipc.c,v 1.10 2007/02/09 21:55:22 ad Exp $");
33 
34 #if defined(_KERNEL_OPT)
35 #include "opt_sysv.h"
36 #endif
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/ipc.h>
41 #include <sys/msg.h>
42 #include <sys/sem.h>
43 #include <sys/shm.h>
44 #include <sys/mount.h>
45 #include <sys/dirent.h>
46 
47 #include <sys/syscallargs.h>
48 #include <sys/proc.h>
49 
50 #include <compat/netbsd32/netbsd32.h>
51 #include <compat/netbsd32/netbsd32_syscallargs.h>
52 #include <compat/netbsd32/netbsd32_conv.h>
53 
54 #if defined(SYSVSEM)
55 int
56 netbsd32___semctl14(l, v, retval)
57 	struct lwp *l;
58 	void *v;
59 	register_t *retval;
60 {
61 	struct netbsd32___semctl14_args /* {
62 		syscallarg(int) semid;
63 		syscallarg(int) semnum;
64 		syscallarg(int) cmd;
65 		syscallarg(netbsd32_semunp_t) arg;
66 	} */ *uap = v;
67 	struct semid_ds sembuf;
68 	struct netbsd32_semid_ds sembuf32;
69 	int cmd, error;
70 	void *pass_arg;
71 	union __semun karg;
72 	union netbsd32_semun karg32;
73 
74 	cmd = SCARG(uap, cmd);
75 
76 	switch (cmd) {
77 	case IPC_SET:
78 	case IPC_STAT:
79 		pass_arg = &sembuf;
80 		break;
81 
82 	case GETALL:
83 	case SETVAL:
84 	case SETALL:
85 		pass_arg = &karg;
86 		break;
87 	default:
88 		pass_arg = NULL;
89 		break;
90 	}
91 
92 	if (pass_arg) {
93 		error = copyin(NETBSD32PTR64(SCARG(uap, arg)), &karg32,
94 		    sizeof(karg32));
95 		if (error)
96 			return error;
97 		if (pass_arg == &karg) {
98 			switch (cmd) {
99 			case GETALL:
100 			case SETALL:
101 				karg.array = NETBSD32PTR64(karg32.array);
102 				break;
103 			case SETVAL:
104 				karg.val = karg32.val;
105 				break;
106 			}
107 		}
108 		if (cmd == IPC_SET) {
109 			error = copyin(NETBSD32PTR64(karg32.buf), &sembuf32,
110 			    sizeof(sembuf32));
111 			if (error)
112 				return (error);
113 			netbsd32_to_semid_ds(&sembuf32, &sembuf);
114 		}
115 	}
116 
117 	error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd,
118 	    pass_arg, retval);
119 
120 	if (error == 0 && cmd == IPC_STAT) {
121 		netbsd32_from_semid_ds(&sembuf, &sembuf32);
122 		error = copyout(&sembuf32, NETBSD32PTR64(karg32.buf),
123 		    sizeof(sembuf32));
124 	}
125 
126 	return (error);
127 }
128 
129 int
130 netbsd32_semget(l, v, retval)
131 	struct lwp *l;
132 	void *v;
133 	register_t *retval;
134 {
135 	struct netbsd32_semget_args /* {
136 		syscallarg(netbsd32_key_t) key;
137 		syscallarg(int) nsems;
138 		syscallarg(int) semflg;
139 	} */ *uap = v;
140 	struct sys_semget_args ua;
141 
142 	NETBSD32TOX_UAP(key, key_t);
143 	NETBSD32TO64_UAP(nsems);
144 	NETBSD32TO64_UAP(semflg);
145 	return (sys_semget(l, &ua, retval));
146 }
147 
148 int
149 netbsd32_semop(l, v, retval)
150 	struct lwp *l;
151 	void *v;
152 	register_t *retval;
153 {
154 	struct netbsd32_semop_args /* {
155 		syscallarg(int) semid;
156 		syscallarg(netbsd32_sembufp_t) sops;
157 		syscallarg(netbsd32_size_t) nsops;
158 	} */ *uap = v;
159 	struct sys_semop_args ua;
160 
161 	NETBSD32TO64_UAP(semid);
162 	NETBSD32TOP_UAP(sops, struct sembuf);
163 	NETBSD32TOX_UAP(nsops, size_t);
164 	return (sys_semop(l, &ua, retval));
165 }
166 
167 int
168 netbsd32_semconfig(l, v, retval)
169 	struct lwp *l;
170 	void *v;
171 	register_t *retval;
172 {
173 	struct netbsd32_semconfig_args /* {
174 		syscallarg(int) flag;
175 	} */ *uap = v;
176 	struct sys_semconfig_args ua;
177 
178 	NETBSD32TO64_UAP(flag);
179 	return (sys_semconfig(l, &ua, retval));
180 }
181 #endif /* SYSVSEM */
182 
183 #if defined(SYSVMSG)
184 
185 int
186 netbsd32___msgctl13(l, v, retval)
187 	struct lwp *l;
188 	void *v;
189 	register_t *retval;
190 {
191 	struct netbsd32___msgctl13_args /* {
192 		syscallarg(int) msqid;
193 		syscallarg(int) cmd;
194 		syscallarg(netbsd32_msqid_dsp_t) buf;
195 	} */ *uap = v;
196 	struct msqid_ds ds;
197 	struct netbsd32_msqid_ds ds32;
198 	int error, cmd;
199 
200 	cmd = SCARG(uap, cmd);
201 	if (cmd == IPC_SET) {
202 		error = copyin(NETBSD32PTR64(SCARG(uap, buf)), &ds32,
203 		    sizeof(ds32));
204 		if (error)
205 			return error;
206 		netbsd32_to_msqid_ds(&ds32, &ds);
207 	}
208 
209 	error = msgctl1(l, SCARG(uap, msqid), cmd,
210 	    (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);
211 
212 	if (error == 0 && cmd == IPC_STAT) {
213 		netbsd32_from_msqid_ds(&ds, &ds32);
214 		error = copyout(&ds32, NETBSD32PTR64(SCARG(uap, buf)),
215 		    sizeof(ds32));
216 	}
217 
218 	return error;
219 }
220 
221 int
222 netbsd32_msgget(l, v, retval)
223 	struct lwp *l;
224 	void *v;
225 	register_t *retval;
226 {
227 	struct netbsd32_msgget_args /* {
228 		syscallarg(netbsd32_key_t) key;
229 		syscallarg(int) msgflg;
230 	} */ *uap = v;
231 	struct sys_msgget_args ua;
232 
233 	NETBSD32TOX_UAP(key, key_t);
234 	NETBSD32TO64_UAP(msgflg);
235 	return sys_msgget(l, &ua, retval);
236 }
237 
238 static int
239 netbsd32_msgsnd_fetch_type(const void *src, void *dst, size_t size)
240 {
241 	netbsd32_long l32;
242 	long *l = dst;
243 	int error;
244 
245 	KASSERT(size == sizeof(netbsd32_long));
246 
247 	error = copyin(src, &l32, sizeof(l32));
248 	if (!error)
249 		*l = l32;
250 	return error;
251 }
252 
253 int
254 netbsd32_msgsnd(l, v, retval)
255 	struct lwp *l;
256 	void *v;
257 	register_t *retval;
258 {
259 	struct netbsd32_msgsnd_args /* {
260 		syscallarg(int) msqid;
261 		syscallarg(const netbsd32_voidp) msgp;
262 		syscallarg(netbsd32_size_t) msgsz;
263 		syscallarg(int) msgflg;
264 	} */ *uap = v;
265 
266 	return msgsnd1(l, SCARG(uap, msqid),
267 	    NETBSD32PTR64(SCARG(uap, msgp)), SCARG(uap, msgsz),
268 	    SCARG(uap, msgflg), sizeof(netbsd32_long),
269 	    netbsd32_msgsnd_fetch_type);
270 }
271 
272 static int
273 netbsd32_msgrcv_put_type(const void *src, void *dst, size_t size)
274 {
275 	netbsd32_long l32;
276 	const long *l = src;
277 
278 	KASSERT(size == sizeof(netbsd32_long));
279 
280 	l32 = (netbsd32_long)(*l);
281 	return copyout(&l32, dst, sizeof(l32));
282 }
283 
284 int
285 netbsd32_msgrcv(l, v, retval)
286 	struct lwp *l;
287 	void *v;
288 	register_t *retval;
289 {
290 	struct netbsd32_msgrcv_args /* {
291 		syscallarg(int) msqid;
292 		syscallarg(netbsd32_voidp) msgp;
293 		syscallarg(netbsd32_size_t) msgsz;
294 		syscallarg(netbsd32_long) msgtyp;
295 		syscallarg(int) msgflg;
296 	} */ *uap = v;
297 
298 	return msgrcv1(l, SCARG(uap, msqid),
299 	    NETBSD32PTR64(SCARG(uap, msgp)), SCARG(uap, msgsz),
300 	    SCARG(uap, msgtyp), SCARG(uap, msgflg), sizeof(netbsd32_long),
301 	    netbsd32_msgrcv_put_type, retval);
302 }
303 #endif /* SYSVMSG */
304 
305 #if defined(SYSVSHM)
306 
307 int
308 netbsd32_shmat(l, v, retval)
309 	struct lwp *l;
310 	void *v;
311 	register_t *retval;
312 {
313 	struct netbsd32_shmat_args /* {
314 		syscallarg(int) shmid;
315 		syscallarg(const netbsd32_voidp) shmaddr;
316 		syscallarg(int) shmflg;
317 	} */ *uap = v;
318 	struct sys_shmat_args ua;
319 
320 	NETBSD32TO64_UAP(shmid);
321 	NETBSD32TOP_UAP(shmaddr, void);
322 	NETBSD32TO64_UAP(shmflg);
323 	return sys_shmat(l, &ua, retval);
324 }
325 
326 int
327 netbsd32___shmctl13(l, v, retval)
328 	struct lwp *l;
329 	void *v;
330 	register_t *retval;
331 {
332 	struct netbsd32___shmctl13_args /* {
333 		syscallarg(int) shmid;
334 		syscallarg(int) cmd;
335 		syscallarg(netbsd32_shmid_dsp_t) buf;
336 	} */ *uap = v;
337 	struct shmid_ds ds;
338 	struct netbsd32_shmid_ds ds32;
339 	int error, cmd;
340 
341 	cmd = SCARG(uap, cmd);
342 	if (cmd == IPC_SET) {
343 		error = copyin(NETBSD32PTR64(SCARG(uap, buf)), &ds32,
344 		    sizeof(ds32));
345 		if (error)
346 			return error;
347 		netbsd32_to_shmid_ds(&ds32, &ds);
348 	}
349 
350 	error = shmctl1(l, SCARG(uap, shmid), cmd,
351 	    (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);
352 
353 	if (error == 0 && cmd == IPC_STAT) {
354 		netbsd32_from_shmid_ds(&ds, &ds32);
355 		error = copyout(&ds32, NETBSD32PTR64(SCARG(uap, buf)),
356 		    sizeof(ds32));
357 	}
358 
359 	return error;
360 }
361 
362 int
363 netbsd32_shmdt(l, v, retval)
364 	struct lwp *l;
365 	void *v;
366 	register_t *retval;
367 {
368 	struct netbsd32_shmdt_args /* {
369 		syscallarg(const netbsd32_voidp) shmaddr;
370 	} */ *uap = v;
371 	struct sys_shmdt_args ua;
372 
373 	NETBSD32TOP_UAP(shmaddr, const char);
374 	return (sys_shmdt(l, &ua, retval));
375 }
376 
377 int
378 netbsd32_shmget(l, v, retval)
379 	struct lwp *l;
380 	void *v;
381 	register_t *retval;
382 {
383 	struct netbsd32_shmget_args /* {
384 		syscallarg(netbsd32_key_t) key;
385 		syscallarg(netbsd32_size_t) size;
386 		syscallarg(int) shmflg;
387 	} */ *uap = v;
388 	struct sys_shmget_args ua;
389 
390 	NETBSD32TOX_UAP(key, key_t)
391 	NETBSD32TOX_UAP(size, size_t)
392 	NETBSD32TO64_UAP(shmflg);
393 	return (sys_shmget(l, &ua, retval));
394 }
395 #endif /* SYSVSHM */
396