1 /* $NetBSD: netbsd32_ipc.c,v 1.5 2003/01/18 08:28:26 thorpej 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.5 2003/01/18 08:28:26 thorpej 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 46 #include <sys/sa.h> 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 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 57 * 58 * This is BSD. We won't support System V IPC. 59 * Too much work. 60 * 61 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 62 */ 63 int 64 netbsd32___semctl14(l, v, retval) 65 struct lwp *l; 66 void *v; 67 register_t *retval; 68 { 69 #if 0 70 struct netbsd32___semctl_args /* { 71 syscallarg(int) semid; 72 syscallarg(int) semnum; 73 syscallarg(int) cmd; 74 syscallarg(netbsd32_semunu_t *) arg; 75 } */ *uap = v; 76 union netbsd32_semun sem32; 77 int semid = SCARG(uap, semid); 78 int semnum = SCARG(uap, semnum); 79 int cmd = SCARG(uap, cmd); 80 union netbsd32_semun *arg = (void*)NETBSD32PTR64(SCARG(uap, arg)); 81 union netbsd32_semun real_arg; 82 struct ucred *cred = p->p_ucred; 83 int i, rval, eval; 84 struct netbsd32_semid_ds sbuf; 85 struct semid_ds *semaptr; 86 87 semlock(p); 88 89 semid = IPCID_TO_IX(semid); 90 if (semid < 0 || semid >= seminfo.semmsl) 91 return(EINVAL); 92 93 semaptr = &sema[semid]; 94 if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || 95 semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid))) 96 return(EINVAL); 97 98 eval = 0; 99 rval = 0; 100 101 switch (cmd) { 102 case IPC_RMID: 103 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0) 104 return(eval); 105 semaptr->sem_perm.cuid = cred->cr_uid; 106 semaptr->sem_perm.uid = cred->cr_uid; 107 semtot -= semaptr->sem_nsems; 108 for (i = semaptr->_sem_base - sem; i < semtot; i++) 109 sem[i] = sem[i + semaptr->sem_nsems]; 110 for (i = 0; i < seminfo.semmni; i++) { 111 if ((sema[i].sem_perm.mode & SEM_ALLOC) && 112 sema[i]._sem_base > semaptr->_sem_base) 113 sema[i]._sem_base -= semaptr->sem_nsems; 114 } 115 semaptr->sem_perm.mode = 0; 116 semundo_clear(semid, -1); 117 wakeup((caddr_t)semaptr); 118 break; 119 120 case IPC_SET: 121 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M))) 122 return(eval); 123 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) 124 return(eval); 125 if ((eval = copyin((caddr_t)NETBSD32PTR64(real_arg.buf), 126 (caddr_t)&sbuf, sizeof(sbuf))) != 0) 127 return(eval); 128 semaptr->sem_perm.uid = sbuf.sem_perm.uid; 129 semaptr->sem_perm.gid = sbuf.sem_perm.gid; 130 semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) | 131 (sbuf.sem_perm.mode & 0777); 132 semaptr->sem_ctime = time.tv_sec; 133 break; 134 135 case IPC_STAT: 136 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) 137 return(eval); 138 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) 139 return(eval); 140 eval = copyout((caddr_t)semaptr, 141 (caddr_t)NETBSD32PTR64(real_arg.buf), 142 sizeof(struct semid_ds)); 143 break; 144 145 case GETNCNT: 146 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) 147 return(eval); 148 if (semnum < 0 || semnum >= semaptr->sem_nsems) 149 return(EINVAL); 150 rval = semaptr->_sem_base[semnum].semncnt; 151 break; 152 153 case GETPID: 154 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) 155 return(eval); 156 if (semnum < 0 || semnum >= semaptr->sem_nsems) 157 return(EINVAL); 158 rval = semaptr->_sem_base[semnum].sempid; 159 break; 160 161 case GETVAL: 162 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) 163 return(eval); 164 if (semnum < 0 || semnum >= semaptr->sem_nsems) 165 return(EINVAL); 166 rval = semaptr->_sem_base[semnum].semval; 167 break; 168 169 case GETALL: 170 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) 171 return(eval); 172 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) 173 return(eval); 174 for (i = 0; i < semaptr->sem_nsems; i++) { 175 eval = copyout((caddr_t)&semaptr->_sem_base[i].semval, 176 &real_arg.array[i], sizeof(real_arg.array[0])); 177 if (eval != 0) 178 break; 179 } 180 break; 181 182 case GETZCNT: 183 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) 184 return(eval); 185 if (semnum < 0 || semnum >= semaptr->sem_nsems) 186 return(EINVAL); 187 rval = semaptr->_sem_base[semnum].semzcnt; 188 break; 189 190 case SETVAL: 191 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) 192 return(eval); 193 if (semnum < 0 || semnum >= semaptr->sem_nsems) 194 return(EINVAL); 195 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) 196 return(eval); 197 semaptr->_sem_base[semnum].semval = real_arg.val; 198 semundo_clear(semid, semnum); 199 wakeup((caddr_t)semaptr); 200 break; 201 202 case SETALL: 203 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) 204 return(eval); 205 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) 206 return(eval); 207 for (i = 0; i < semaptr->sem_nsems; i++) { 208 eval = copyin(&real_arg.array[i], 209 (caddr_t)&semaptr->_sem_base[i].semval, 210 sizeof(real_arg.array[0])); 211 if (eval != 0) 212 break; 213 } 214 semundo_clear(semid, -1); 215 wakeup((caddr_t)semaptr); 216 break; 217 218 default: 219 return(EINVAL); 220 } 221 222 if (eval == 0) 223 *retval = rval; 224 return(eval); 225 #else 226 return (ENOSYS); 227 #endif 228 } 229 230 int 231 netbsd32_semget(l, v, retval) 232 struct lwp *l; 233 void *v; 234 register_t *retval; 235 { 236 struct netbsd32_semget_args /* { 237 syscallarg(netbsd32_key_t) key; 238 syscallarg(int) nsems; 239 syscallarg(int) semflg; 240 } */ *uap = v; 241 struct sys_semget_args ua; 242 243 NETBSD32TOX_UAP(key, key_t); 244 NETBSD32TO64_UAP(nsems); 245 NETBSD32TO64_UAP(semflg); 246 return (sys_semget(l, &ua, retval)); 247 } 248 249 int 250 netbsd32_semop(l, v, retval) 251 struct lwp *l; 252 void *v; 253 register_t *retval; 254 { 255 struct netbsd32_semop_args /* { 256 syscallarg(int) semid; 257 syscallarg(netbsd32_sembufp_t) sops; 258 syscallarg(netbsd32_size_t) nsops; 259 } */ *uap = v; 260 struct sys_semop_args ua; 261 262 NETBSD32TO64_UAP(semid); 263 NETBSD32TOP_UAP(sops, struct sembuf); 264 NETBSD32TOX_UAP(nsops, size_t); 265 return (sys_semop(l, &ua, retval)); 266 } 267 268 int 269 netbsd32_semconfig(l, v, retval) 270 struct lwp *l; 271 void *v; 272 register_t *retval; 273 { 274 struct netbsd32_semconfig_args /* { 275 syscallarg(int) flag; 276 } */ *uap = v; 277 struct sys_semconfig_args ua; 278 279 NETBSD32TO64_UAP(flag); 280 return (sys_semconfig(l, &ua, retval)); 281 } 282 #endif /* SYSVSEM */ 283 284 #if defined(SYSVMSG) 285 286 int 287 netbsd32___msgctl13(l, v, retval) 288 struct lwp *l; 289 void *v; 290 register_t *retval; 291 { 292 #if 0 293 struct netbsd32_msgctl_args /* { 294 syscallarg(int) msqid; 295 syscallarg(int) cmd; 296 syscallarg(netbsd32_msqid_dsp_t) buf; 297 } */ *uap = v; 298 struct sys_msgctl_args ua; 299 struct msqid_ds ds; 300 struct netbsd32_msqid_ds *ds32p; 301 int error; 302 303 NETBSD32TO64_UAP(msqid); 304 NETBSD32TO64_UAP(cmd); 305 ds32p = (struct netbsd32_msqid_ds *)NETBSD32PTR64(SCARG(uap, buf)); 306 if (ds32p) { 307 SCARG(&ua, buf) = NULL; 308 netbsd32_to_msqid_ds(ds32p, &ds); 309 } else 310 SCARG(&ua, buf) = NULL; 311 error = sys_msgctl(p, &ua, retval); 312 if (error) 313 return (error); 314 315 if (ds32p) 316 netbsd32_from_msqid_ds(&ds, ds32p); 317 return (0); 318 #else 319 return (ENOSYS); 320 #endif 321 } 322 323 int 324 netbsd32_msgget(l, v, retval) 325 struct lwp *l; 326 void *v; 327 register_t *retval; 328 { 329 #if 0 330 struct netbsd32_msgget_args /* { 331 syscallarg(netbsd32_key_t) key; 332 syscallarg(int) msgflg; 333 } */ *uap = v; 334 struct sys_msgget_args ua; 335 336 NETBSD32TOX_UAP(key, key_t); 337 NETBSD32TO64_UAP(msgflg); 338 return (sys_msgget(l, &ua, retval)); 339 #else 340 return (ENOSYS); 341 #endif 342 } 343 344 int 345 netbsd32_msgsnd(l, v, retval) 346 struct lwp *l; 347 void *v; 348 register_t *retval; 349 { 350 #if 0 351 struct netbsd32_msgsnd_args /* { 352 syscallarg(int) msqid; 353 syscallarg(const netbsd32_voidp) msgp; 354 syscallarg(netbsd32_size_t) msgsz; 355 syscallarg(int) msgflg; 356 } */ *uap = v; 357 struct sys_msgsnd_args ua; 358 359 NETBSD32TO64_UAP(msqid); 360 NETBSD32TOP_UAP(msgp, void); 361 NETBSD32TOX_UAP(msgsz, size_t); 362 NETBSD32TO64_UAP(msgflg); 363 return (sys_msgsnd(l, &ua, retval)); 364 #else 365 return (ENOSYS); 366 #endif 367 } 368 369 int 370 netbsd32_msgrcv(l, v, retval) 371 struct lwp *l; 372 void *v; 373 register_t *retval; 374 { 375 #if 0 376 struct netbsd32_msgrcv_args /* { 377 syscallarg(int) msqid; 378 syscallarg(netbsd32_voidp) msgp; 379 syscallarg(netbsd32_size_t) msgsz; 380 syscallarg(netbsd32_long) msgtyp; 381 syscallarg(int) msgflg; 382 } */ *uap = v; 383 struct sys_msgrcv_args ua; 384 ssize_t rt; 385 int error; 386 387 NETBSD32TO64_UAP(msqid); 388 NETBSD32TOP_UAP(msgp, void); 389 NETBSD32TOX_UAP(msgsz, size_t); 390 NETBSD32TOX_UAP(msgtyp, long); 391 NETBSD32TO64_UAP(msgflg); 392 error = sys_msgrcv(l, &ua, (register_t *)&rt); 393 *retval = rt; 394 return (error); 395 #else 396 return (ENOSYS); 397 #endif 398 } 399 #endif /* SYSVMSG */ 400 401 #if defined(SYSVSHM) 402 403 int 404 netbsd32_shmat(l, v, retval) 405 struct lwp *l; 406 void *v; 407 register_t *retval; 408 { 409 #if 0 410 struct netbsd32_shmat_args /* { 411 syscallarg(int) shmid; 412 syscallarg(const netbsd32_voidp) shmaddr; 413 syscallarg(int) shmflg; 414 } */ *uap = v; 415 struct sys_shmat_args ua; 416 void *rt; 417 int error; 418 419 NETBSD32TO64_UAP(shmid); 420 NETBSD32TOP_UAP(shmaddr, void); 421 NETBSD32TO64_UAP(shmflg); 422 error = sys_shmat(l, &ua, (register_t *)&rt); 423 *retval = rt; 424 return (error); 425 #else 426 return (ENOSYS); 427 #endif 428 } 429 430 int 431 netbsd32___shmctl13(l, v, retval) 432 struct lwp *l; 433 void *v; 434 register_t *retval; 435 { 436 #if 0 437 struct netbsd32_shmctl_args /* { 438 syscallarg(int) shmid; 439 syscallarg(int) cmd; 440 syscallarg(netbsd32_shmid_dsp_t) buf; 441 } */ *uap = v; 442 struct sys_shmctl_args ua; 443 struct shmid_ds ds; 444 struct netbsd32_shmid_ds *ds32p; 445 int error; 446 447 NETBSD32TO64_UAP(shmid); 448 NETBSD32TO64_UAP(cmd); 449 ds32p = (struct netbsd32_shmid_ds *)NETBSD32PTR64(SCARG(uap, buf)); 450 if (ds32p) { 451 SCARG(&ua, buf) = NULL; 452 netbsd32_to_shmid_ds(ds32p, &ds); 453 } else 454 SCARG(&ua, buf) = NULL; 455 error = sys_shmctl(p, &ua, retval); 456 if (error) 457 return (error); 458 459 if (ds32p) 460 netbsd32_from_shmid_ds(&ds, ds32p); 461 return (0); 462 #else 463 return (ENOSYS); 464 #endif 465 } 466 467 int 468 netbsd32_shmdt(l, v, retval) 469 struct lwp *l; 470 void *v; 471 register_t *retval; 472 { 473 #if 0 474 struct netbsd32_shmdt_args /* { 475 syscallarg(const netbsd32_voidp) shmaddr; 476 } */ *uap = v; 477 struct sys_shmdt_args ua; 478 479 NETBSD32TOP_UAP(shmaddr, const char); 480 return (sys_shmdt(l, &ua, retval)); 481 #else 482 return (ENOSYS); 483 #endif 484 } 485 486 int 487 netbsd32_shmget(l, v, retval) 488 struct lwp *l; 489 void *v; 490 register_t *retval; 491 { 492 #if 0 493 struct netbsd32_shmget_args /* { 494 syscallarg(netbsd32_key_t) key; 495 syscallarg(netbsd32_size_t) size; 496 syscallarg(int) shmflg; 497 } */ *uap = v; 498 struct sys_shmget_args ua; 499 500 NETBSD32TOX_UAP(key, key_t) 501 NETBSD32TOX_UAP(size, size_t) 502 NETBSD32TO64_UAP(shmflg); 503 return (sys_shmget(l, &ua, retval)); 504 #else 505 return (ENOSYS); 506 #endif 507 } 508 #endif /* SYSVSHM */ 509