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