mirror of https://git.musl-libc.org/git/musl
Browse Source
time64 syscall is used only if it's the only one defined for the arch, or if the requested timeout does not fit in 32 bits. on current 32-bit archs where time_t is a 32-bit type, this makes it statically unreachable. on 64-bit archs, there is no change to the code after preprocessing. on current 32-bit archs, the time is passed via an intermediate copy to remove the assumption that time_t is a 32-bit type. to avoid duplicating SYS_ipc/SYS_semtimedop choice logic, the code for 32-bit archs "falls through" after updating the timeout argument ts to point to a [compound literal] array of longs. in preparation for "time64-only" 32-bit archs, an extra case is added for neither SYS_ipc nor the non-time64 SYS_semtimedop existing; the ENOSYS failure path here should never be reachable, and is added just in case a compiler can't see that it's not reachable, to avoid spurious static analysis complaints.master
1 changed files with 24 additions and 2 deletions
@ -1,13 +1,35 @@ |
|||
#define _GNU_SOURCE |
|||
#include <sys/sem.h> |
|||
#include <errno.h> |
|||
#include "syscall.h" |
|||
#include "ipc.h" |
|||
|
|||
#define IS32BIT(x) !((x)+0x80000000ULL>>32) |
|||
#define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) |
|||
|
|||
#if !defined(SYS_semtimedop) && !defined(SYS_ipc) |
|||
#define NO_TIME32 1 |
|||
#else |
|||
#define NO_TIME32 0 |
|||
#endif |
|||
|
|||
int semtimedop(int id, struct sembuf *buf, size_t n, const struct timespec *ts) |
|||
{ |
|||
#ifndef SYS_ipc |
|||
#ifdef SYS_semtimedop_time64 |
|||
time_t s = ts ? ts->tv_sec : 0; |
|||
long ns = ts ? ts->tv_nsec : 0; |
|||
int r = -ENOSYS; |
|||
if (NO_TIME32 || !IS32BIT(s)) |
|||
r = __syscall(SYS_semtimedop_time64, id, buf, n, |
|||
ts ? ((long long[]){s, ns}) : 0); |
|||
if (NO_TIME32 || r!=-ENOSYS) return __syscall_ret(r); |
|||
ts = ts ? (void *)(long[]){CLAMP(s), ns} : 0; |
|||
#endif |
|||
#if defined(SYS_ipc) |
|||
return syscall(SYS_ipc, IPCOP_semtimedop, id, n, 0, buf, ts); |
|||
#elif defined(SYS_semtimedop) |
|||
return syscall(SYS_semtimedop, id, buf, n, ts); |
|||
#else |
|||
return syscall(SYS_ipc, IPCOP_semtimedop, id, n, 0, buf, ts); |
|||
return __syscall_ret(-ENOSYS); |
|||
#endif |
|||
} |
|||
|
|||
Loading…
Reference in new issue