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