| 1 | #include <time.h> |
| 2 | #include <errno.h> |
| 3 | #include "syscall.h" |
| 4 | |
| 5 | #define IS32BIT(x) !((x)+0x80000000ULL>>32) |
| 6 | #define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) |
| 7 | |
| 8 | int __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem) |
| 9 | { |
| 10 | 	if (clk == CLOCK_THREAD_CPUTIME_ID) return EINVAL; |
| 11 | #ifdef SYS_clock_nanosleep_time64 |
| 12 | 	time_t s = req->tv_sec; |
| 13 | 	long ns = req->tv_nsec; |
| 14 | 	int r = -ENOSYS; |
| 15 | 	if (SYS_clock_nanosleep == SYS_clock_nanosleep_time64 || !IS32BIT(s)) |
| 16 | 		r = __syscall_cp(SYS_clock_nanosleep_time64, clk, flags, |
| 17 | 			((long long[]){s, ns}), rem); |
| 18 | 	if (SYS_clock_nanosleep == SYS_clock_nanosleep_time64 || r!=-ENOSYS) |
| 19 | 		return -r; |
| 20 | 	long long extra = s - CLAMP(s); |
| 21 | 	long ts32[2] = { CLAMP(s), ns }; |
| 22 | 	if (clk == CLOCK_REALTIME && !flags) |
| 23 | 		r = __syscall_cp(SYS_nanosleep, &ts32, &ts32); |
| 24 | 	else |
| 25 | 		r = __syscall_cp(SYS_clock_nanosleep, clk, flags, &ts32, &ts32); |
| 26 | 	if (r==-EINTR && rem && !(flags & TIMER_ABSTIME)) { |
| 27 | 		rem->tv_sec = ts32[0] + extra; |
| 28 | 		rem->tv_nsec = ts32[1]; |
| 29 | 	} |
| 30 | 	return -r; |
| 31 | #else |
| 32 | 	if (clk == CLOCK_REALTIME && !flags) |
| 33 | 		return -__syscall_cp(SYS_nanosleep, req, rem); |
| 34 | 	return -__syscall_cp(SYS_clock_nanosleep, clk, flags, req, rem); |
| 35 | #endif |
| 36 | } |
| 37 | |
| 38 | weak_alias(__clock_nanosleep, clock_nanosleep); |