static int linux32_shmctl(struct lwp *l, const struct linux32_sys_ipc_args *uap, register_t *retval) { int shmid, cmd, error; struct shmid_ds bs; struct linux32_shmid_ds ls; struct linux32_shmid64_ds ls64; shmid = SCARG(uap, a1); cmd = SCARG(uap, a2); switch (cmd & ~LINUX32_IPC_64) { case LINUX32_SHM_STAT: return ENOSYS; case LINUX32_IPC_STAT: error = shmctl1(l, shmid, IPC_STAT, &bs); if (error != 0) return error; if (cmd & LINUX32_IPC_64) { bsd_to_linux32_shmid64_ds(&bs, &ls64); error = copyout(&ls64, SCARG_P32(uap, ptr), sizeof ls64); } else { bsd_to_linux32_shmid_ds(&bs, &ls); error = copyout(&ls, SCARG_P32(uap, ptr), sizeof ls); } return error; case LINUX32_IPC_SET: if (cmd & LINUX32_IPC_64) { error = copyin(SCARG_P32(uap, ptr), &ls64, sizeof ls64); linux32_to_bsd_shmid64_ds(&ls64, &bs); } else { error = copyin(SCARG_P32(uap, ptr), &ls, sizeof ls); linux32_to_bsd_shmid_ds(&ls, &bs); } if (error != 0) return error; return shmctl1(l, shmid, IPC_SET, &bs); case LINUX32_IPC_RMID: return shmctl1(l, shmid, IPC_RMID, NULL); case LINUX32_SHM_LOCK: return shmctl1(l, shmid, SHM_LOCK, NULL); case LINUX32_SHM_UNLOCK: return shmctl1(l, shmid, SHM_UNLOCK, NULL); case LINUX32_IPC_INFO: case LINUX32_SHM_INFO: return ENOSYS; default: return EINVAL; } }
int netbsd32___shmctl13(struct lwp *l, const struct netbsd32___shmctl13_args *uap, register_t *retval) { /* { syscallarg(int) shmid; syscallarg(int) cmd; syscallarg(netbsd32_shmid_dsp_t) buf; } */ struct shmid_ds ds; struct netbsd32_shmid_ds ds32; int error, cmd; cmd = SCARG(uap, cmd); if (cmd == IPC_SET) { error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32)); if (error) return error; netbsd32_to_shmid_ds(&ds32, &ds); } error = shmctl1(l, SCARG(uap, shmid), cmd, (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL); if (error == 0 && cmd == IPC_STAT) { netbsd32_from_shmid_ds(&ds, &ds32); error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32)); } return error; }
int sys_shmctl(struct proc *p, void *v, register_t *retval) { struct sys_shmctl_args /* { syscallarg(int) shmid; syscallarg(int) cmd; syscallarg(struct shmid_ds *) buf; } */ *uap = v; return (shmctl1(p, SCARG(uap, shmid), SCARG(uap, cmd), (caddr_t)SCARG(uap, buf), copyin, copyout)); }
int ibcs2_sys_shmsys(struct lwp *l, const struct ibcs2_sys_shmsys_args *uap, register_t *retval) { #ifdef SYSVSHM /* { syscallarg(int) which; syscallarg(int) a2; syscallarg(int) a3; syscallarg(int) a4; } */ struct shmid_ds shmbuf; struct ibcs2_shmid_ds *isp, ishmbuf; int cmd, error; switch (SCARG(uap, which)) { case 0: /* shmat */ break; case 1: /* shmctl */ cmd = SCARG(uap, a3); isp = (struct ibcs2_shmid_ds *)SCARG(uap, a4); if (cmd == IPC_SET) { error = copyin(isp, &ishmbuf, sizeof(ishmbuf)); if (error) return error; cvt_ishmid2shmid(&ishmbuf, &shmbuf); } error = shmctl1(l, SCARG(uap, a2), cmd, (cmd == IPC_SET || cmd == IPC_STAT) ? &shmbuf : NULL); if (error == 0 && cmd == IPC_STAT) { cvt_shmid2ishmid(&shmbuf, &ishmbuf); error = copyout(&ishmbuf, isp, sizeof(ishmbuf)); } return error; case 2: /* shmdt */ break; case 3: /* shmget */ break; default: return EINVAL; } return compat_10_sys_shmsys(l, (const void *)uap, retval); #else return EINVAL; #endif }