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