1 /* $NetBSD: netbsd32_ipc.c,v 1.3 2001/11/13 02:09:06 lukem 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.3 2001/11/13 02:09:06 lukem 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*)(u_long)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)(u_long)real_arg.buf, (caddr_t)&sbuf, 125 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, (caddr_t)(u_long)real_arg.buf, 140 sizeof(struct semid_ds)); 141 break; 142 143 case GETNCNT: 144 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) 145 return(eval); 146 if (semnum < 0 || semnum >= semaptr->sem_nsems) 147 return(EINVAL); 148 rval = semaptr->_sem_base[semnum].semncnt; 149 break; 150 151 case GETPID: 152 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) 153 return(eval); 154 if (semnum < 0 || semnum >= semaptr->sem_nsems) 155 return(EINVAL); 156 rval = semaptr->_sem_base[semnum].sempid; 157 break; 158 159 case GETVAL: 160 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) 161 return(eval); 162 if (semnum < 0 || semnum >= semaptr->sem_nsems) 163 return(EINVAL); 164 rval = semaptr->_sem_base[semnum].semval; 165 break; 166 167 case GETALL: 168 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) 169 return(eval); 170 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) 171 return(eval); 172 for (i = 0; i < semaptr->sem_nsems; i++) { 173 eval = copyout((caddr_t)&semaptr->_sem_base[i].semval, 174 &real_arg.array[i], sizeof(real_arg.array[0])); 175 if (eval != 0) 176 break; 177 } 178 break; 179 180 case GETZCNT: 181 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) 182 return(eval); 183 if (semnum < 0 || semnum >= semaptr->sem_nsems) 184 return(EINVAL); 185 rval = semaptr->_sem_base[semnum].semzcnt; 186 break; 187 188 case SETVAL: 189 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) 190 return(eval); 191 if (semnum < 0 || semnum >= semaptr->sem_nsems) 192 return(EINVAL); 193 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) 194 return(eval); 195 semaptr->_sem_base[semnum].semval = real_arg.val; 196 semundo_clear(semid, semnum); 197 wakeup((caddr_t)semaptr); 198 break; 199 200 case SETALL: 201 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) 202 return(eval); 203 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) 204 return(eval); 205 for (i = 0; i < semaptr->sem_nsems; i++) { 206 eval = copyin(&real_arg.array[i], 207 (caddr_t)&semaptr->_sem_base[i].semval, 208 sizeof(real_arg.array[0])); 209 if (eval != 0) 210 break; 211 } 212 semundo_clear(semid, -1); 213 wakeup((caddr_t)semaptr); 214 break; 215 216 default: 217 return(EINVAL); 218 } 219 220 if (eval == 0) 221 *retval = rval; 222 return(eval); 223 #else 224 return (ENOSYS); 225 #endif 226 } 227 228 int 229 netbsd32_semget(p, v, retval) 230 struct proc *p; 231 void *v; 232 register_t *retval; 233 { 234 struct netbsd32_semget_args /* { 235 syscallarg(netbsd32_key_t) key; 236 syscallarg(int) nsems; 237 syscallarg(int) semflg; 238 } */ *uap = v; 239 struct sys_semget_args ua; 240 241 NETBSD32TOX_UAP(key, key_t); 242 NETBSD32TO64_UAP(nsems); 243 NETBSD32TO64_UAP(semflg); 244 return (sys_semget(p, &ua, retval)); 245 } 246 247 int 248 netbsd32_semop(p, v, retval) 249 struct proc *p; 250 void *v; 251 register_t *retval; 252 { 253 struct netbsd32_semop_args /* { 254 syscallarg(int) semid; 255 syscallarg(netbsd32_sembufp_t) sops; 256 syscallarg(netbsd32_size_t) nsops; 257 } */ *uap = v; 258 struct sys_semop_args ua; 259 260 NETBSD32TO64_UAP(semid); 261 NETBSD32TOP_UAP(sops, struct sembuf); 262 NETBSD32TOX_UAP(nsops, size_t); 263 return (sys_semop(p, &ua, retval)); 264 } 265 266 int 267 netbsd32_semconfig(p, v, retval) 268 struct proc *p; 269 void *v; 270 register_t *retval; 271 { 272 struct netbsd32_semconfig_args /* { 273 syscallarg(int) flag; 274 } */ *uap = v; 275 struct sys_semconfig_args ua; 276 277 NETBSD32TO64_UAP(flag); 278 return (sys_semconfig(p, &ua, retval)); 279 } 280 #endif /* SYSVSEM */ 281 282 #if defined(SYSVMSG) 283 284 int 285 netbsd32___msgctl13(p, v, retval) 286 struct proc *p; 287 void *v; 288 register_t *retval; 289 { 290 #if 0 291 struct netbsd32_msgctl_args /* { 292 syscallarg(int) msqid; 293 syscallarg(int) cmd; 294 syscallarg(netbsd32_msqid_dsp_t) buf; 295 } */ *uap = v; 296 struct sys_msgctl_args ua; 297 struct msqid_ds ds; 298 struct netbsd32_msqid_ds *ds32p; 299 int error; 300 301 NETBSD32TO64_UAP(msqid); 302 NETBSD32TO64_UAP(cmd); 303 ds32p = (struct netbsd32_msqid_ds *)(u_long)SCARG(uap, buf); 304 if (ds32p) { 305 SCARG(&ua, buf) = NULL; 306 netbsd32_to_msqid_ds(ds32p, &ds); 307 } else 308 SCARG(&ua, buf) = NULL; 309 error = sys_msgctl(p, &ua, retval); 310 if (error) 311 return (error); 312 313 if (ds32p) 314 netbsd32_from_msqid_ds(&ds, ds32p); 315 return (0); 316 #else 317 return (ENOSYS); 318 #endif 319 } 320 321 int 322 netbsd32_msgget(p, v, retval) 323 struct proc *p; 324 void *v; 325 register_t *retval; 326 { 327 #if 0 328 struct netbsd32_msgget_args /* { 329 syscallarg(netbsd32_key_t) key; 330 syscallarg(int) msgflg; 331 } */ *uap = v; 332 struct sys_msgget_args ua; 333 334 NETBSD32TOX_UAP(key, key_t); 335 NETBSD32TO64_UAP(msgflg); 336 return (sys_msgget(p, &ua, retval)); 337 #else 338 return (ENOSYS); 339 #endif 340 } 341 342 int 343 netbsd32_msgsnd(p, v, retval) 344 struct proc *p; 345 void *v; 346 register_t *retval; 347 { 348 #if 0 349 struct netbsd32_msgsnd_args /* { 350 syscallarg(int) msqid; 351 syscallarg(const netbsd32_voidp) msgp; 352 syscallarg(netbsd32_size_t) msgsz; 353 syscallarg(int) msgflg; 354 } */ *uap = v; 355 struct sys_msgsnd_args ua; 356 357 NETBSD32TO64_UAP(msqid); 358 NETBSD32TOP_UAP(msgp, void); 359 NETBSD32TOX_UAP(msgsz, size_t); 360 NETBSD32TO64_UAP(msgflg); 361 return (sys_msgsnd(p, &ua, retval)); 362 #else 363 return (ENOSYS); 364 #endif 365 } 366 367 int 368 netbsd32_msgrcv(p, v, retval) 369 struct proc *p; 370 void *v; 371 register_t *retval; 372 { 373 #if 0 374 struct netbsd32_msgrcv_args /* { 375 syscallarg(int) msqid; 376 syscallarg(netbsd32_voidp) msgp; 377 syscallarg(netbsd32_size_t) msgsz; 378 syscallarg(netbsd32_long) msgtyp; 379 syscallarg(int) msgflg; 380 } */ *uap = v; 381 struct sys_msgrcv_args ua; 382 ssize_t rt; 383 int error; 384 385 NETBSD32TO64_UAP(msqid); 386 NETBSD32TOP_UAP(msgp, void); 387 NETBSD32TOX_UAP(msgsz, size_t); 388 NETBSD32TOX_UAP(msgtyp, long); 389 NETBSD32TO64_UAP(msgflg); 390 error = sys_msgrcv(p, &ua, (register_t *)&rt); 391 *retval = rt; 392 return (error); 393 #else 394 return (ENOSYS); 395 #endif 396 } 397 #endif /* SYSVMSG */ 398 399 #if defined(SYSVSHM) 400 401 int 402 netbsd32_shmat(p, v, retval) 403 struct proc *p; 404 void *v; 405 register_t *retval; 406 { 407 #if 0 408 struct netbsd32_shmat_args /* { 409 syscallarg(int) shmid; 410 syscallarg(const netbsd32_voidp) shmaddr; 411 syscallarg(int) shmflg; 412 } */ *uap = v; 413 struct sys_shmat_args ua; 414 void *rt; 415 int error; 416 417 NETBSD32TO64_UAP(shmid); 418 NETBSD32TOP_UAP(shmaddr, void); 419 NETBSD32TO64_UAP(shmflg); 420 error = sys_shmat(p, &ua, (register_t *)&rt); 421 *retval = rt; 422 return (error); 423 #else 424 return (ENOSYS); 425 #endif 426 } 427 428 int 429 netbsd32___shmctl13(p, v, retval) 430 struct proc *p; 431 void *v; 432 register_t *retval; 433 { 434 #if 0 435 struct netbsd32_shmctl_args /* { 436 syscallarg(int) shmid; 437 syscallarg(int) cmd; 438 syscallarg(netbsd32_shmid_dsp_t) buf; 439 } */ *uap = v; 440 struct sys_shmctl_args ua; 441 struct shmid_ds ds; 442 struct netbsd32_shmid_ds *ds32p; 443 int error; 444 445 NETBSD32TO64_UAP(shmid); 446 NETBSD32TO64_UAP(cmd); 447 ds32p = (struct netbsd32_shmid_ds *)(u_long)SCARG(uap, buf); 448 if (ds32p) { 449 SCARG(&ua, buf) = NULL; 450 netbsd32_to_shmid_ds(ds32p, &ds); 451 } else 452 SCARG(&ua, buf) = NULL; 453 error = sys_shmctl(p, &ua, retval); 454 if (error) 455 return (error); 456 457 if (ds32p) 458 netbsd32_from_shmid_ds(&ds, ds32p); 459 return (0); 460 #else 461 return (ENOSYS); 462 #endif 463 } 464 465 int 466 netbsd32_shmdt(p, v, retval) 467 struct proc *p; 468 void *v; 469 register_t *retval; 470 { 471 #if 0 472 struct netbsd32_shmdt_args /* { 473 syscallarg(const netbsd32_voidp) shmaddr; 474 } */ *uap = v; 475 struct sys_shmdt_args ua; 476 477 NETBSD32TOP_UAP(shmaddr, const char); 478 return (sys_shmdt(p, &ua, retval)); 479 #else 480 return (ENOSYS); 481 #endif 482 } 483 484 int 485 netbsd32_shmget(p, v, retval) 486 struct proc *p; 487 void *v; 488 register_t *retval; 489 { 490 #if 0 491 struct netbsd32_shmget_args /* { 492 syscallarg(netbsd32_key_t) key; 493 syscallarg(netbsd32_size_t) size; 494 syscallarg(int) shmflg; 495 } */ *uap = v; 496 struct sys_shmget_args ua; 497 498 NETBSD32TOX_UAP(key, key_t) 499 NETBSD32TOX_UAP(size, size_t) 500 NETBSD32TO64_UAP(shmflg); 501 return (sys_shmget(p, &ua, retval)); 502 #else 503 return (ENOSYS); 504 #endif 505 } 506 #endif /* SYSVSHM */ 507