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