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