From db7aefbcd9674072eb20304f1ca65403ffbdbd8f Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Thu, 16 Jan 2020 21:49:34 -0800 Subject: WIP Signed-off-by: Alistair Francis --- sysdeps/unix/sysv/linux/bits/sem.h | 12 ++++++++++++ sysdeps/unix/sysv/linux/semctl.c | 27 +++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/sysdeps/unix/sysv/linux/bits/sem.h b/sysdeps/unix/sysv/linux/bits/sem.h index e0f4155c67..6ea5a69969 100644 --- a/sysdeps/unix/sysv/linux/bits/sem.h +++ b/sysdeps/unix/sysv/linux/bits/sem.h @@ -57,6 +57,18 @@ struct semid_ds __syscall_ulong_t __glibc_reserved4; }; +struct __semid_ds32 { + struct ipc_perm sem_perm; /* operation permission struct */ + __syscall_ulong_t sem_otime; /* last semop() time */ + __syscall_ulong_t sem_otime_high; /* last semop() time high */ + __syscall_ulong_t sem_ctime; /* last time changed by semctl() */ + __syscall_ulong_t sem_ctime_high; /* last time changed by semctl() high */ + __syscall_ulong_t sem_nsems; /* number of semaphores in set */ + __syscall_ulong_t __glibc_reserved3; + __syscall_ulong_t __glibc_reserved4; +}; + + /* The user should define a union like the following to use it for arguments for `semctl'. diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c index 0c3eb0932f..22fce7a770 100644 --- a/sysdeps/unix/sysv/linux/semctl.c +++ b/sysdeps/unix/sysv/linux/semctl.c @@ -28,6 +28,7 @@ union semun { int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ + struct __semid_ds32 *buf32; unsigned short int *array; /* array for GETALL & SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */ }; @@ -43,12 +44,30 @@ union semun static int semctl_syscall (int semid, int semnum, int cmd, union semun arg) { -#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS - return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, - arg.array); +#if __TIMESZIE == 64 && __WORDSIZE == 32 + int ret; +# ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS + ret = INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, + arg.array); +# else + ret = INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64, + SEMCTL_ARG_ADDRESS (arg)); +# endif + if (ret == 0) + { + arg.buf.sem_ctime = arg.buf32.sem_ctime + arg.buf32.sem_ctime_high; + arg.buf.sem_otime = arg.buf32.sem_otime + arg.buf32.sem_otime_high; + } + return ret; #else +# ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS + return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, + arg.array); +# else return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64, - SEMCTL_ARG_ADDRESS (arg)); + SEMCTL_ARG_ADDRESS (arg)); +# endif + #endif } -- cgit v1.2.3