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