/* * OpenBSD 3.5 semctl(2) with 16bit mode_t in struct ipcperm. */ int compat_35_sys___semctl(struct proc *p, void *v, register_t *retval) { struct compat_35_sys___semctl_args /* { syscallarg(int) semid; syscallarg(int) semnum; syscallarg(int) cmd; syscallarg(union semun *) arg; } */ *uap = v; union semun arg; int error = 0, cmd = SCARG(uap, cmd); switch (cmd) { case IPC_SET: case IPC_STAT: case GETALL: case SETVAL: case SETALL: error = copyin(SCARG(uap, arg), &arg, sizeof(arg)); break; } if (error == 0) { error = semctl1(p, SCARG(uap, semid), SCARG(uap, semnum), cmd, &arg, retval, semid_copyin, semid_copyout); } return (error); }
int ibcs2_sys_semsys(struct lwp *l, const struct ibcs2_sys_semsys_args *uap, register_t *retval) { #ifdef SYSVSEM /* { syscallarg(int) which; syscallarg(int) a2; syscallarg(int) a3; syscallarg(int) a4; syscallarg(int) a5; } */ struct semid_ds sembuf; struct ibcs2_semid_ds isembuf; void *pass_arg; int a5 = SCARG(uap, a5); int error; switch (SCARG(uap, which)) { case 0: /* semctl */ #define semctl_semid SCARG(uap, a2) #define semctl_semnum SCARG(uap, a3) #define semctl_cmd SCARG(uap, a4) #define semctl_arg ((union __semun *)&a5) pass_arg = get_semctl_arg(semctl_cmd, &sembuf, semctl_arg); if (semctl_cmd == IPC_SET) { error = copyin(semctl_arg->buf, &isembuf, sizeof isembuf); if (error != 0) return error; cvt_isemid2semid(&isembuf, &sembuf); } error = semctl1(l, semctl_semid, semctl_semnum, semctl_cmd, pass_arg, retval); if (error == 0 && semctl_cmd == IPC_STAT) { cvt_semid2isemid(&sembuf, &isembuf); error = copyout(&isembuf, semctl_arg->buf, sizeof(isembuf)); } return error; #undef semctl_semid #undef semctl_semnum #undef semctl_cmd #undef semctl_arg case 1: /* semget */ return compat_10_sys_semsys(l, (const void *)uap, retval); case 2: /* semop */ return compat_10_sys_semsys(l, (const void *)uap, retval); } #endif return EINVAL; }
int compat_14_sys___semctl(struct lwp *l, const struct compat_14_sys___semctl_args *uap, register_t *retval) { /* { syscallarg(int) semid; syscallarg(int) semnum; syscallarg(int) cmd; syscallarg(union __semun *) arg; } */ union __semun arg; struct semid_ds sembuf; struct semid_ds14 osembuf; int cmd, error; void *pass_arg; cmd = SCARG(uap, cmd); pass_arg = get_semctl_arg(cmd, &sembuf, &arg); if (pass_arg != NULL) { error = copyin(SCARG(uap, arg), &arg, sizeof(arg)); if (error) return (error); if (cmd == IPC_SET) { error = copyin(arg.buf, &osembuf, sizeof(osembuf)); if (error) return (error); __semid_ds14_to_native(&osembuf, &sembuf); } } error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd, pass_arg, retval); if (error == 0 && cmd == IPC_STAT) { __native_to_semid_ds14(&sembuf, &osembuf); error = copyout(&osembuf, arg.buf, sizeof(osembuf)); } return (error); }
int sys_____semctl50(struct lwp *l, const struct sys_____semctl50_args *uap, register_t *retval) { /* { syscallarg(int) semid; syscallarg(int) semnum; syscallarg(int) cmd; syscallarg(union __semun *) arg; } */ struct semid_ds sembuf; int cmd, error; void *pass_arg; union __semun karg; cmd = SCARG(uap, cmd); pass_arg = get_semctl_arg(cmd, &sembuf, &karg); if (pass_arg) { error = copyin(SCARG(uap, arg), &karg, sizeof(karg)); if (error) return error; if (cmd == IPC_SET) { error = copyin(karg.buf, &sembuf, sizeof(sembuf)); if (error) return (error); } } error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd, pass_arg, retval); if (error == 0 && cmd == IPC_STAT) error = copyout(&sembuf, karg.buf, sizeof(sembuf)); return (error); }
int do_netbsd32___semctl14(struct lwp *l, const struct netbsd32___semctl14_args *uap, register_t *retval, void *vkarg) { /* { syscallarg(int) semid; syscallarg(int) semnum; syscallarg(int) cmd; syscallarg(netbsd32_semunp_t) arg; } */ struct semid_ds sembuf; struct netbsd32_semid_ds sembuf32; int cmd, error; void *pass_arg; union __semun karg; union netbsd32_semun karg32; cmd = SCARG(uap, cmd); switch (cmd) { case IPC_SET: case IPC_STAT: pass_arg = &sembuf; break; case GETALL: case SETVAL: case SETALL: pass_arg = &karg; break; default: pass_arg = NULL; break; } if (pass_arg) { if (vkarg != NULL) karg32 = *(union netbsd32_semun *)vkarg; else { error = copyin(SCARG_P32(uap, arg), &karg32, sizeof(karg32)); if (error) return error; } if (pass_arg == &karg) { switch (cmd) { case GETALL: case SETALL: karg.array = NETBSD32PTR64(karg32.array); break; case SETVAL: karg.val = karg32.val; break; } } if (cmd == IPC_SET) { error = copyin(NETBSD32PTR64(karg32.buf), &sembuf32, sizeof(sembuf32)); if (error) return (error); netbsd32_to_semid_ds(&sembuf32, &sembuf); } } error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd, pass_arg, retval); if (error == 0 && cmd == IPC_STAT) { netbsd32_from_semid_ds(&sembuf, &sembuf32); error = copyout(&sembuf32, NETBSD32PTR64(karg32.buf), sizeof(sembuf32)); } return (error); }
static int linux32_semctl(struct lwp *l, const struct linux32_sys_ipc_args *uap, register_t *retval) { int lcmd, cmd, error; struct semid_ds bs; struct linux32_semid_ds ls; struct linux32_semid64_ds ls64; union linux32_semun lsem; union __semun bsem; void *buf = NULL; if ((error = copyin(SCARG_P32(uap, ptr), &lsem, sizeof lsem))) return error; lcmd = SCARG(uap, a3); switch (lcmd & ~LINUX32_IPC_64) { case LINUX32_IPC_RMID: cmd = IPC_RMID; break; case LINUX32_IPC_STAT: cmd = IPC_STAT; buf = &bs; break; case LINUX32_IPC_SET: if (lcmd & LINUX32_IPC_64) { error = copyin(NETBSD32PTR64(lsem.l_buf), &ls64, sizeof ls64); linux32_to_bsd_semid64_ds(&ls64, &bs); } else { error = copyin(NETBSD32PTR64(lsem.l_buf), &ls, sizeof ls); linux32_to_bsd_semid_ds(&ls, &bs); } if (error) return error; cmd = IPC_SET; buf = &bs; break; case LINUX32_GETVAL: cmd = GETVAL; break; case LINUX32_SETVAL: cmd = SETVAL; bsem.val = lsem.l_val; buf = &bsem; break; case LINUX32_GETPID: cmd = GETPID; break; case LINUX32_GETNCNT: cmd = GETNCNT; break; case LINUX32_GETZCNT: cmd = GETZCNT; break; case LINUX32_GETALL: cmd = GETALL; bsem.array = NETBSD32PTR64(lsem.l_array); buf = &bsem; break; case LINUX32_SETALL: cmd = SETALL; bsem.array = NETBSD32PTR64(lsem.l_array); buf = &bsem; break; default: return EINVAL; } error = semctl1(l, SCARG(uap, a1), SCARG(uap, a2), cmd, buf, retval); if (error) return error; switch (lcmd) { case LINUX32_IPC_STAT: bsd_to_linux32_semid_ds(&bs, &ls); error = copyout(&ls, NETBSD32PTR64(lsem.l_buf), sizeof ls); break; case LINUX32_IPC_STAT|LINUX32_IPC_64: bsd_to_linux32_semid64_ds(&bs, &ls64); error = copyout(&ls64, NETBSD32PTR64(lsem.l_buf), sizeof ls64); break; default: break; } return error; }