On Sun, Feb 8, 2026 at 7:17 PM Richard Henderson < [email protected]> wrote:
> On 2/9/26 05:26, Warner Losh wrote: > > From: Stacey Son <[email protected]> > > > > Add implementation of __semctl(2) syscall for System V semaphore control > > operations. Handles command translation, endianness conversion for > GETVAL/ > > SETVAL, and array/structure conversions for > GETALL/SETALL/IPC_STAT/IPC_SET. > > > > Signed-off-by: Stacey Son <[email protected]> > > Signed-off-by: Warner Losh <[email protected]> > > --- > > bsd-user/bsd-misc.h | 115 > ++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 115 insertions(+) > > > > diff --git a/bsd-user/bsd-misc.h b/bsd-user/bsd-misc.h > > index cba0b2ec92..d3ce01a2a3 100644 > > --- a/bsd-user/bsd-misc.h > > +++ b/bsd-user/bsd-misc.h > > @@ -106,6 +106,121 @@ static inline abi_long do_bsd_semop(int semid, > abi_long ptr, unsigned nsops) > > return semop(semid, sops, nsops); > > } > > > > +/* __semctl(2) */ > > +static inline abi_long do_bsd___semctl(int semid, int semnum, int > target_cmd, > > + abi_ptr un_ptr) > > +{ > > + void *target_un; > > + union semun arg; > > + struct semid_ds dsarg; > > + unsigned short *array = NULL; > > + int host_cmd; > > + abi_long ret = 0; > > + abi_long err; > > + abi_ulong target_array, target_buffer; > > + > > + switch (target_cmd) { > > + case TARGET_GETVAL: > > + host_cmd = GETVAL; > > + break; > > + > > + case TARGET_SETVAL: > > + host_cmd = SETVAL; > > + break; > > + > > + case TARGET_GETALL: > > + host_cmd = GETALL; > > + break; > > + > > + case TARGET_SETALL: > > + host_cmd = SETALL; > > + break; > > + > > + case TARGET_IPC_STAT: > > + host_cmd = IPC_STAT; > > + break; > > + > > + case TARGET_IPC_SET: > > + host_cmd = IPC_SET; > > + break; > > + > > + case TARGET_IPC_RMID: > > + host_cmd = IPC_RMID; > > + break; > > + > > + case TARGET_GETPID: > > + host_cmd = GETPID; > > + break; > > + > > + case TARGET_GETNCNT: > > + host_cmd = GETNCNT; > > + break; > > + > > + case TARGET_GETZCNT: > > + host_cmd = GETZCNT; > > + break; > > + > > + default: > > + return -TARGET_EINVAL; > > + } > > + > > + /* > > + * Unlike Linux and the semctl system call, we take a pointer > > + * to the union arg here. > > + */ > > + target_un = lock_user(VERIFY_READ, un_ptr, sizeof(union > target_semun), 0); > > Missing an unlock. > Oh! Right you are... I'm surprised we don't have the annotated so clang tells me when I make a mistake like this.... Fixed in v3. Warner > r~ > > > + > > + switch (host_cmd) { > > + case GETVAL: > > + case SETVAL: > > + __get_user(arg.val, (abi_int *)target_un); > > + ret = get_errno(semctl(semid, semnum, host_cmd, arg)); > > + break; > > + > > + case GETALL: > > + case SETALL: > > + __get_user(target_array, (abi_ulong *)target_un); > > + err = target_to_host_semarray(semid, &array, target_array); > > + if (is_error(err)) { > > + return err; > > + } > > + arg.array = array; > > + ret = get_errno(semctl(semid, semnum, host_cmd, arg)); > > + err = host_to_target_semarray(semid, target_array, &array); > > + if (is_error(err)) { > > + return err; > > + } > > + break; > > + > > + case IPC_STAT: > > + case IPC_SET: > > + __get_user(target_buffer, (abi_ulong *)target_un); > > + err = target_to_host_semid_ds(&dsarg, target_buffer); > > + if (is_error(err)) { > > + return err; > > + } > > + arg.buf = &dsarg; > > + ret = get_errno(semctl(semid, semnum, host_cmd, arg)); > > + err = host_to_target_semid_ds(target_buffer, &dsarg); > > + if (is_error(err)) { > > + return err; > > + } > > + break; > > + > > + case IPC_RMID: > > + case GETPID: > > + case GETNCNT: > > + case GETZCNT: > > + ret = get_errno(semctl(semid, semnum, host_cmd, NULL)); > > + break; > > + > > + default: > > + ret = -TARGET_EINVAL; > > + break; > > + } > > + return ret; > > +} > > + > > /* getdtablesize(2) */ > > static inline abi_long do_bsd_getdtablesize(void) > > { > > > > >
