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