xref: /netbsd-src/sys/compat/netbsd32/netbsd32_ipc.c (revision 74809f044aa1c34df701bf79c7bfb9794896fdf8)
1 /*	$NetBSD: netbsd32_ipc.c,v 1.15 2008/05/29 14:51:26 mrg 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  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: netbsd32_ipc.c,v 1.15 2008/05/29 14:51:26 mrg Exp $");
31 
32 #if defined(_KERNEL_OPT)
33 #include "opt_sysv.h"
34 #endif
35 
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/ipc.h>
39 #include <sys/msg.h>
40 #include <sys/sem.h>
41 #include <sys/shm.h>
42 #include <sys/mount.h>
43 #include <sys/dirent.h>
44 
45 #include <sys/syscallargs.h>
46 #include <sys/proc.h>
47 
48 #include <compat/netbsd32/netbsd32.h>
49 #include <compat/netbsd32/netbsd32_syscallargs.h>
50 #include <compat/netbsd32/netbsd32_conv.h>
51 
52 #if defined(SYSVSEM)
53 
54 int
55 netbsd32___semctl14(struct lwp *l, const struct netbsd32___semctl14_args *uap, register_t *retval)
56 {
57 	return do_netbsd32___semctl14(l, uap, retval, NULL);
58 }
59 
60 int
61 do_netbsd32___semctl14(struct lwp *l, const struct netbsd32___semctl14_args *uap, register_t *retval, void *vkarg)
62 {
63 	/* {
64 		syscallarg(int) semid;
65 		syscallarg(int) semnum;
66 		syscallarg(int) cmd;
67 		syscallarg(netbsd32_semunp_t) arg;
68 	} */
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 		if (vkarg != NULL)
96 			karg32 = *(union netbsd32_semun *)vkarg;
97 		else {
98 			error = copyin(SCARG_P32(uap, arg), &karg32,
99 					sizeof(karg32));
100 			if (error)
101 				return error;
102 		}
103 		if (pass_arg == &karg) {
104 			switch (cmd) {
105 			case GETALL:
106 			case SETALL:
107 				karg.array = NETBSD32PTR64(karg32.array);
108 				break;
109 			case SETVAL:
110 				karg.val = karg32.val;
111 				break;
112 			}
113 		}
114 		if (cmd == IPC_SET) {
115 			error = copyin(NETBSD32PTR64(karg32.buf), &sembuf32,
116 			    sizeof(sembuf32));
117 			if (error)
118 				return (error);
119 			netbsd32_to_semid_ds(&sembuf32, &sembuf);
120 		}
121 	}
122 
123 	error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd,
124 	    pass_arg, retval);
125 
126 	if (error == 0 && cmd == IPC_STAT) {
127 		netbsd32_from_semid_ds(&sembuf, &sembuf32);
128 		error = copyout(&sembuf32, NETBSD32PTR64(karg32.buf),
129 		    sizeof(sembuf32));
130 	}
131 
132 	return (error);
133 }
134 
135 int
136 netbsd32_semget(struct lwp *l, const struct netbsd32_semget_args *uap, register_t *retval)
137 {
138 	/* {
139 		syscallarg(netbsd32_key_t) key;
140 		syscallarg(int) nsems;
141 		syscallarg(int) semflg;
142 	} */
143 	struct sys_semget_args ua;
144 
145 	NETBSD32TOX_UAP(key, key_t);
146 	NETBSD32TO64_UAP(nsems);
147 	NETBSD32TO64_UAP(semflg);
148 	return (sys_semget(l, &ua, retval));
149 }
150 
151 int
152 netbsd32_semop(struct lwp *l, const struct netbsd32_semop_args *uap, register_t *retval)
153 {
154 	/* {
155 		syscallarg(int) semid;
156 		syscallarg(netbsd32_sembufp_t) sops;
157 		syscallarg(netbsd32_size_t) nsops;
158 	} */
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(struct lwp *l, const struct netbsd32_semconfig_args *uap, register_t *retval)
169 {
170 	/* {
171 		syscallarg(int) flag;
172 	} */
173 	struct sys_semconfig_args ua;
174 
175 	NETBSD32TO64_UAP(flag);
176 	return (sys_semconfig(l, &ua, retval));
177 }
178 #endif /* SYSVSEM */
179 
180 #if defined(SYSVMSG)
181 
182 int
183 netbsd32___msgctl13(struct lwp *l, const struct netbsd32___msgctl13_args *uap, register_t *retval)
184 {
185 	/* {
186 		syscallarg(int) msqid;
187 		syscallarg(int) cmd;
188 		syscallarg(netbsd32_msqid_dsp_t) buf;
189 	} */
190 	struct msqid_ds ds;
191 	struct netbsd32_msqid_ds ds32;
192 	int error, cmd;
193 
194 	cmd = SCARG(uap, cmd);
195 	if (cmd == IPC_SET) {
196 		error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32));
197 		if (error)
198 			return error;
199 		netbsd32_to_msqid_ds(&ds32, &ds);
200 	}
201 
202 	error = msgctl1(l, SCARG(uap, msqid), cmd,
203 	    (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);
204 
205 	if (error == 0 && cmd == IPC_STAT) {
206 		netbsd32_from_msqid_ds(&ds, &ds32);
207 		error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32));
208 	}
209 
210 	return error;
211 }
212 
213 int
214 netbsd32_msgget(struct lwp *l, const struct netbsd32_msgget_args *uap, register_t *retval)
215 {
216 	/* {
217 		syscallarg(netbsd32_key_t) key;
218 		syscallarg(int) msgflg;
219 	} */
220 	struct sys_msgget_args ua;
221 
222 	NETBSD32TOX_UAP(key, key_t);
223 	NETBSD32TO64_UAP(msgflg);
224 	return sys_msgget(l, &ua, retval);
225 }
226 
227 static int
228 netbsd32_msgsnd_fetch_type(const void *src, void *dst, size_t size)
229 {
230 	netbsd32_long l32;
231 	long *l = dst;
232 	int error;
233 
234 	KASSERT(size == sizeof(netbsd32_long));
235 
236 	error = copyin(src, &l32, sizeof(l32));
237 	if (!error)
238 		*l = l32;
239 	return error;
240 }
241 
242 int
243 netbsd32_msgsnd(struct lwp *l, const struct netbsd32_msgsnd_args *uap, register_t *retval)
244 {
245 	/* {
246 		syscallarg(int) msqid;
247 		syscallarg(const netbsd32_voidp) msgp;
248 		syscallarg(netbsd32_size_t) msgsz;
249 		syscallarg(int) msgflg;
250 	} */
251 
252 	return msgsnd1(l, SCARG(uap, msqid),
253 	    SCARG_P32(uap, msgp), SCARG(uap, msgsz),
254 	    SCARG(uap, msgflg), sizeof(netbsd32_long),
255 	    netbsd32_msgsnd_fetch_type);
256 }
257 
258 static int
259 netbsd32_msgrcv_put_type(const void *src, void *dst, size_t size)
260 {
261 	netbsd32_long l32;
262 	const long *l = src;
263 
264 	KASSERT(size == sizeof(netbsd32_long));
265 
266 	l32 = (netbsd32_long)(*l);
267 	return copyout(&l32, dst, sizeof(l32));
268 }
269 
270 int
271 netbsd32_msgrcv(struct lwp *l, const struct netbsd32_msgrcv_args *uap, register_t *retval)
272 {
273 	/* {
274 		syscallarg(int) msqid;
275 		syscallarg(netbsd32_voidp) msgp;
276 		syscallarg(netbsd32_size_t) msgsz;
277 		syscallarg(netbsd32_long) msgtyp;
278 		syscallarg(int) msgflg;
279 	} */
280 
281 	return msgrcv1(l, SCARG(uap, msqid),
282 	    SCARG_P32(uap, msgp), SCARG(uap, msgsz),
283 	    SCARG(uap, msgtyp), SCARG(uap, msgflg), sizeof(netbsd32_long),
284 	    netbsd32_msgrcv_put_type, retval);
285 }
286 #endif /* SYSVMSG */
287 
288 #if defined(SYSVSHM)
289 
290 int
291 netbsd32_shmat(struct lwp *l, const struct netbsd32_shmat_args *uap, register_t *retval)
292 {
293 	/* {
294 		syscallarg(int) shmid;
295 		syscallarg(const netbsd32_voidp) shmaddr;
296 		syscallarg(int) shmflg;
297 	} */
298 	struct sys_shmat_args ua;
299 
300 	NETBSD32TO64_UAP(shmid);
301 	NETBSD32TOP_UAP(shmaddr, void);
302 	NETBSD32TO64_UAP(shmflg);
303 	return sys_shmat(l, &ua, retval);
304 }
305 
306 int
307 netbsd32___shmctl13(struct lwp *l, const struct netbsd32___shmctl13_args *uap, register_t *retval)
308 {
309 	/* {
310 		syscallarg(int) shmid;
311 		syscallarg(int) cmd;
312 		syscallarg(netbsd32_shmid_dsp_t) buf;
313 	} */
314 	struct shmid_ds ds;
315 	struct netbsd32_shmid_ds ds32;
316 	int error, cmd;
317 
318 	cmd = SCARG(uap, cmd);
319 	if (cmd == IPC_SET) {
320 		error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32));
321 		if (error)
322 			return error;
323 		netbsd32_to_shmid_ds(&ds32, &ds);
324 	}
325 
326 	error = shmctl1(l, SCARG(uap, shmid), cmd,
327 	    (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);
328 
329 	if (error == 0 && cmd == IPC_STAT) {
330 		netbsd32_from_shmid_ds(&ds, &ds32);
331 		error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32));
332 	}
333 
334 	return error;
335 }
336 
337 int
338 netbsd32_shmdt(struct lwp *l, const struct netbsd32_shmdt_args *uap, register_t *retval)
339 {
340 	/* {
341 		syscallarg(const netbsd32_voidp) shmaddr;
342 	} */
343 	struct sys_shmdt_args ua;
344 
345 	NETBSD32TOP_UAP(shmaddr, const char);
346 	return (sys_shmdt(l, &ua, retval));
347 }
348 
349 int
350 netbsd32_shmget(struct lwp *l, const struct netbsd32_shmget_args *uap, register_t *retval)
351 {
352 	/* {
353 		syscallarg(netbsd32_key_t) key;
354 		syscallarg(netbsd32_size_t) size;
355 		syscallarg(int) shmflg;
356 	} */
357 	struct sys_shmget_args ua;
358 
359 	NETBSD32TOX_UAP(key, key_t)
360 	NETBSD32TOX_UAP(size, size_t)
361 	NETBSD32TO64_UAP(shmflg);
362 	return (sys_shmget(l, &ua, retval));
363 }
364 #endif /* SYSVSHM */
365