xref: /aosp_15_r20/external/musl/src/linux/timerfd.c (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
1*c9945492SAndroid Build Coastguard Worker #include <sys/timerfd.h>
2*c9945492SAndroid Build Coastguard Worker #include <errno.h>
3*c9945492SAndroid Build Coastguard Worker #include "syscall.h"
4*c9945492SAndroid Build Coastguard Worker 
5*c9945492SAndroid Build Coastguard Worker #define IS32BIT(x) !((x)+0x80000000ULL>>32)
6*c9945492SAndroid Build Coastguard Worker 
timerfd_create(int clockid,int flags)7*c9945492SAndroid Build Coastguard Worker int timerfd_create(int clockid, int flags)
8*c9945492SAndroid Build Coastguard Worker {
9*c9945492SAndroid Build Coastguard Worker 	return syscall(SYS_timerfd_create, clockid, flags);
10*c9945492SAndroid Build Coastguard Worker }
11*c9945492SAndroid Build Coastguard Worker 
timerfd_settime(int fd,int flags,const struct itimerspec * new,struct itimerspec * old)12*c9945492SAndroid Build Coastguard Worker int timerfd_settime(int fd, int flags, const struct itimerspec *new, struct itimerspec *old)
13*c9945492SAndroid Build Coastguard Worker {
14*c9945492SAndroid Build Coastguard Worker #ifdef SYS_timerfd_settime64
15*c9945492SAndroid Build Coastguard Worker 	time_t is = new->it_interval.tv_sec, vs = new->it_value.tv_sec;
16*c9945492SAndroid Build Coastguard Worker 	long ins = new->it_interval.tv_nsec, vns = new->it_value.tv_nsec;
17*c9945492SAndroid Build Coastguard Worker 	int r = -ENOSYS;
18*c9945492SAndroid Build Coastguard Worker 	if (SYS_timerfd_settime == SYS_timerfd_settime64
19*c9945492SAndroid Build Coastguard Worker 	    || !IS32BIT(is) || !IS32BIT(vs) || (sizeof(time_t)>4 && old))
20*c9945492SAndroid Build Coastguard Worker 		r = __syscall(SYS_timerfd_settime64, fd, flags,
21*c9945492SAndroid Build Coastguard Worker 			((long long[]){is, ins, vs, vns}), old);
22*c9945492SAndroid Build Coastguard Worker 	if (SYS_timerfd_settime == SYS_timerfd_settime64 || r!=-ENOSYS)
23*c9945492SAndroid Build Coastguard Worker 		return __syscall_ret(r);
24*c9945492SAndroid Build Coastguard Worker 	if (!IS32BIT(is) || !IS32BIT(vs))
25*c9945492SAndroid Build Coastguard Worker 		return __syscall_ret(-ENOTSUP);
26*c9945492SAndroid Build Coastguard Worker 	long old32[4];
27*c9945492SAndroid Build Coastguard Worker 	r = __syscall(SYS_timerfd_settime, fd, flags,
28*c9945492SAndroid Build Coastguard Worker 		((long[]){is, ins, vs, vns}), old32);
29*c9945492SAndroid Build Coastguard Worker 	if (!r && old) {
30*c9945492SAndroid Build Coastguard Worker 		old->it_interval.tv_sec = old32[0];
31*c9945492SAndroid Build Coastguard Worker 		old->it_interval.tv_nsec = old32[1];
32*c9945492SAndroid Build Coastguard Worker 		old->it_value.tv_sec = old32[2];
33*c9945492SAndroid Build Coastguard Worker 		old->it_value.tv_nsec = old32[3];
34*c9945492SAndroid Build Coastguard Worker 	}
35*c9945492SAndroid Build Coastguard Worker 	return __syscall_ret(r);
36*c9945492SAndroid Build Coastguard Worker #endif
37*c9945492SAndroid Build Coastguard Worker 	return syscall(SYS_timerfd_settime, fd, flags, new, old);
38*c9945492SAndroid Build Coastguard Worker }
39*c9945492SAndroid Build Coastguard Worker 
timerfd_gettime(int fd,struct itimerspec * cur)40*c9945492SAndroid Build Coastguard Worker int timerfd_gettime(int fd, struct itimerspec *cur)
41*c9945492SAndroid Build Coastguard Worker {
42*c9945492SAndroid Build Coastguard Worker #ifdef SYS_timerfd_gettime64
43*c9945492SAndroid Build Coastguard Worker 	int r = -ENOSYS;
44*c9945492SAndroid Build Coastguard Worker 	if (sizeof(time_t) > 4)
45*c9945492SAndroid Build Coastguard Worker 		r = __syscall(SYS_timerfd_gettime64, fd, cur);
46*c9945492SAndroid Build Coastguard Worker 	if (SYS_timerfd_gettime == SYS_timerfd_gettime64 || r!=-ENOSYS)
47*c9945492SAndroid Build Coastguard Worker 		return __syscall_ret(r);
48*c9945492SAndroid Build Coastguard Worker 	long cur32[4];
49*c9945492SAndroid Build Coastguard Worker 	r = __syscall(SYS_timerfd_gettime, fd, cur32);
50*c9945492SAndroid Build Coastguard Worker 	if (!r) {
51*c9945492SAndroid Build Coastguard Worker 		cur->it_interval.tv_sec = cur32[0];
52*c9945492SAndroid Build Coastguard Worker 		cur->it_interval.tv_nsec = cur32[1];
53*c9945492SAndroid Build Coastguard Worker 		cur->it_value.tv_sec = cur32[2];
54*c9945492SAndroid Build Coastguard Worker 		cur->it_value.tv_nsec = cur32[3];
55*c9945492SAndroid Build Coastguard Worker 	}
56*c9945492SAndroid Build Coastguard Worker 	return __syscall_ret(r);
57*c9945492SAndroid Build Coastguard Worker #endif
58*c9945492SAndroid Build Coastguard Worker 	return syscall(SYS_timerfd_gettime, fd, cur);
59*c9945492SAndroid Build Coastguard Worker }
60