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 */
Cache object: fbab0ab11322da70b8fa5831fd84d2ea
|