xref: /netbsd-src/sys/compat/netbsd32/netbsd32_ipc.c (revision b7ae68fde0d8ef1c03714e8bbb1ee7c6118ea93b)
1 /*	$NetBSD: netbsd32_ipc.c,v 1.9 2006/07/23 22:06:09 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.9 2006/07/23 22:06:09 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/sa.h>
48 #include <sys/syscallargs.h>
49 #include <sys/proc.h>
50 
51 #include <compat/netbsd32/netbsd32.h>
52 #include <compat/netbsd32/netbsd32_syscallargs.h>
53 #include <compat/netbsd32/netbsd32_conv.h>
54 
55 #if defined(SYSVSEM)
56 int
57 netbsd32___semctl14(l, v, retval)
58 	struct lwp *l;
59 	void *v;
60 	register_t *retval;
61 {
62 	struct netbsd32___semctl14_args /* {
63 		syscallarg(int) semid;
64 		syscallarg(int) semnum;
65 		syscallarg(int) cmd;
66 		syscallarg(netbsd32_semunp_t) arg;
67 	} */ *uap = v;
68 	struct semid_ds sembuf;
69 	struct netbsd32_semid_ds sembuf32;
70 	int cmd, error;
71 	void *pass_arg;
72 	union __semun karg;
73 	union netbsd32_semun karg32;
74 
75 	cmd = SCARG(uap, cmd);
76 
77 	switch (cmd) {
78 	case IPC_SET:
79 	case IPC_STAT:
80 		pass_arg = &sembuf;
81 		break;
82 
83 	case GETALL:
84 	case SETVAL:
85 	case SETALL:
86 		pass_arg = &karg;
87 		break;
88 	default:
89 		pass_arg = NULL;
90 		break;
91 	}
92 
93 	if (pass_arg) {
94 		error = copyin(NETBSD32PTR64(SCARG(uap, arg)), &karg32,
95 		    sizeof(karg32));
96 		if (error)
97 			return error;
98 		if (pass_arg == &karg) {
99 			switch (cmd) {
100 			case GETALL:
101 			case SETALL:
102 				karg.array = NETBSD32PTR64(karg32.array);
103 				break;
104 			case SETVAL:
105 				karg.val = karg32.val;
106 				break;
107 			}
108 		}
109 		if (cmd == IPC_SET) {
110 			error = copyin(NETBSD32PTR64(karg32.buf), &sembuf32,
111 			    sizeof(sembuf32));
112 			if (error)
113 				return (error);
114 			netbsd32_to_semid_ds(&sembuf32, &sembuf);
115 		}
116 	}
117 
118 	error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd,
119 	    pass_arg, retval);
120 
121 	if (error == 0 && cmd == IPC_STAT) {
122 		netbsd32_from_semid_ds(&sembuf, &sembuf32);
123 		error = copyout(&sembuf32, NETBSD32PTR64(karg32.buf),
124 		    sizeof(sembuf32));
125 	}
126 
127 	return (error);
128 }
129 
130 int
131 netbsd32_semget(l, v, retval)
132 	struct lwp *l;
133 	void *v;
134 	register_t *retval;
135 {
136 	struct netbsd32_semget_args /* {
137 		syscallarg(netbsd32_key_t) key;
138 		syscallarg(int) nsems;
139 		syscallarg(int) semflg;
140 	} */ *uap = v;
141 	struct sys_semget_args ua;
142 
143 	NETBSD32TOX_UAP(key, key_t);
144 	NETBSD32TO64_UAP(nsems);
145 	NETBSD32TO64_UAP(semflg);
146 	return (sys_semget(l, &ua, retval));
147 }
148 
149 int
150 netbsd32_semop(l, v, retval)
151 	struct lwp *l;
152 	void *v;
153 	register_t *retval;
154 {
155 	struct netbsd32_semop_args /* {
156 		syscallarg(int) semid;
157 		syscallarg(netbsd32_sembufp_t) sops;
158 		syscallarg(netbsd32_size_t) nsops;
159 	} */ *uap = v;
160 	struct sys_semop_args ua;
161 
162 	NETBSD32TO64_UAP(semid);
163 	NETBSD32TOP_UAP(sops, struct sembuf);
164 	NETBSD32TOX_UAP(nsops, size_t);
165 	return (sys_semop(l, &ua, retval));
166 }
167 
168 int
169 netbsd32_semconfig(l, v, retval)
170 	struct lwp *l;
171 	void *v;
172 	register_t *retval;
173 {
174 	struct netbsd32_semconfig_args /* {
175 		syscallarg(int) flag;
176 	} */ *uap = v;
177 	struct sys_semconfig_args ua;
178 
179 	NETBSD32TO64_UAP(flag);
180 	return (sys_semconfig(l, &ua, retval));
181 }
182 #endif /* SYSVSEM */
183 
184 #if defined(SYSVMSG)
185 
186 int
187 netbsd32___msgctl13(l, v, retval)
188 	struct lwp *l;
189 	void *v;
190 	register_t *retval;
191 {
192 	struct netbsd32___msgctl13_args /* {
193 		syscallarg(int) msqid;
194 		syscallarg(int) cmd;
195 		syscallarg(netbsd32_msqid_dsp_t) buf;
196 	} */ *uap = v;
197 	struct msqid_ds ds;
198 	struct netbsd32_msqid_ds ds32;
199 	int error, cmd;
200 
201 	cmd = SCARG(uap, cmd);
202 	if (cmd == IPC_SET) {
203 		error = copyin(NETBSD32PTR64(SCARG(uap, buf)), &ds32,
204 		    sizeof(ds32));
205 		if (error)
206 			return error;
207 		netbsd32_to_msqid_ds(&ds32, &ds);
208 	}
209 
210 	error = msgctl1(l, SCARG(uap, msqid), cmd,
211 	    (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);
212 
213 	if (error == 0 && cmd == IPC_STAT) {
214 		netbsd32_from_msqid_ds(&ds, &ds32);
215 		error = copyout(&ds32, NETBSD32PTR64(SCARG(uap, buf)),
216 		    sizeof(ds32));
217 	}
218 
219 	return error;
220 }
221 
222 int
223 netbsd32_msgget(l, v, retval)
224 	struct lwp *l;
225 	void *v;
226 	register_t *retval;
227 {
228 	struct netbsd32_msgget_args /* {
229 		syscallarg(netbsd32_key_t) key;
230 		syscallarg(int) msgflg;
231 	} */ *uap = v;
232 	struct sys_msgget_args ua;
233 
234 	NETBSD32TOX_UAP(key, key_t);
235 	NETBSD32TO64_UAP(msgflg);
236 	return sys_msgget(l, &ua, retval);
237 }
238 
239 static int
240 netbsd32_msgsnd_fetch_type(const void *src, void *dst, size_t size)
241 {
242 	netbsd32_long l32;
243 	long *l = dst;
244 	int error;
245 
246 	KASSERT(size == sizeof(netbsd32_long));
247 
248 	error = copyin(src, &l32, sizeof(l32));
249 	if (!error)
250 		*l = l32;
251 	return error;
252 }
253 
254 int
255 netbsd32_msgsnd(l, v, retval)
256 	struct lwp *l;
257 	void *v;
258 	register_t *retval;
259 {
260 	struct netbsd32_msgsnd_args /* {
261 		syscallarg(int) msqid;
262 		syscallarg(const netbsd32_voidp) msgp;
263 		syscallarg(netbsd32_size_t) msgsz;
264 		syscallarg(int) msgflg;
265 	} */ *uap = v;
266 
267 	return msgsnd1(l, SCARG(uap, msqid),
268 	    NETBSD32PTR64(SCARG(uap, msgp)), SCARG(uap, msgsz),
269 	    SCARG(uap, msgflg), sizeof(netbsd32_long),
270 	    netbsd32_msgsnd_fetch_type);
271 }
272 
273 static int
274 netbsd32_msgrcv_put_type(const void *src, void *dst, size_t size)
275 {
276 	netbsd32_long l32;
277 	const long *l = src;
278 
279 	KASSERT(size == sizeof(netbsd32_long));
280 
281 	l32 = (netbsd32_long)(*l);
282 	return copyout(&l32, dst, sizeof(l32));
283 }
284 
285 int
286 netbsd32_msgrcv(l, v, retval)
287 	struct lwp *l;
288 	void *v;
289 	register_t *retval;
290 {
291 	struct netbsd32_msgrcv_args /* {
292 		syscallarg(int) msqid;
293 		syscallarg(netbsd32_voidp) msgp;
294 		syscallarg(netbsd32_size_t) msgsz;
295 		syscallarg(netbsd32_long) msgtyp;
296 		syscallarg(int) msgflg;
297 	} */ *uap = v;
298 
299 	return msgrcv1(l, SCARG(uap, msqid),
300 	    NETBSD32PTR64(SCARG(uap, msgp)), SCARG(uap, msgsz),
301 	    SCARG(uap, msgtyp), SCARG(uap, msgflg), sizeof(netbsd32_long),
302 	    netbsd32_msgrcv_put_type, retval);
303 }
304 #endif /* SYSVMSG */
305 
306 #if defined(SYSVSHM)
307 
308 int
309 netbsd32_shmat(l, v, retval)
310 	struct lwp *l;
311 	void *v;
312 	register_t *retval;
313 {
314 	struct netbsd32_shmat_args /* {
315 		syscallarg(int) shmid;
316 		syscallarg(const netbsd32_voidp) shmaddr;
317 		syscallarg(int) shmflg;
318 	} */ *uap = v;
319 	struct sys_shmat_args ua;
320 
321 	NETBSD32TO64_UAP(shmid);
322 	NETBSD32TOP_UAP(shmaddr, void);
323 	NETBSD32TO64_UAP(shmflg);
324 	return sys_shmat(l, &ua, retval);
325 }
326 
327 int
328 netbsd32___shmctl13(l, v, retval)
329 	struct lwp *l;
330 	void *v;
331 	register_t *retval;
332 {
333 	struct netbsd32___shmctl13_args /* {
334 		syscallarg(int) shmid;
335 		syscallarg(int) cmd;
336 		syscallarg(netbsd32_shmid_dsp_t) buf;
337 	} */ *uap = v;
338 	struct shmid_ds ds;
339 	struct netbsd32_shmid_ds ds32;
340 	int error, cmd;
341 
342 	cmd = SCARG(uap, cmd);
343 	if (cmd == IPC_SET) {
344 		error = copyin(NETBSD32PTR64(SCARG(uap, buf)), &ds32,
345 		    sizeof(ds32));
346 		if (error)
347 			return error;
348 		netbsd32_to_shmid_ds(&ds32, &ds);
349 	}
350 
351 	error = shmctl1(l, SCARG(uap, shmid), cmd,
352 	    (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);
353 
354 	if (error == 0 && cmd == IPC_STAT) {
355 		netbsd32_from_shmid_ds(&ds, &ds32);
356 		error = copyout(&ds32, NETBSD32PTR64(SCARG(uap, buf)),
357 		    sizeof(ds32));
358 	}
359 
360 	return error;
361 }
362 
363 int
364 netbsd32_shmdt(l, v, retval)
365 	struct lwp *l;
366 	void *v;
367 	register_t *retval;
368 {
369 	struct netbsd32_shmdt_args /* {
370 		syscallarg(const netbsd32_voidp) shmaddr;
371 	} */ *uap = v;
372 	struct sys_shmdt_args ua;
373 
374 	NETBSD32TOP_UAP(shmaddr, const char);
375 	return (sys_shmdt(l, &ua, retval));
376 }
377 
378 int
379 netbsd32_shmget(l, v, retval)
380 	struct lwp *l;
381 	void *v;
382 	register_t *retval;
383 {
384 	struct netbsd32_shmget_args /* {
385 		syscallarg(netbsd32_key_t) key;
386 		syscallarg(netbsd32_size_t) size;
387 		syscallarg(int) shmflg;
388 	} */ *uap = v;
389 	struct sys_shmget_args ua;
390 
391 	NETBSD32TOX_UAP(key, key_t)
392 	NETBSD32TOX_UAP(size, size_t)
393 	NETBSD32TO64_UAP(shmflg);
394 	return (sys_shmget(l, &ua, retval));
395 }
396 #endif /* SYSVSHM */
397