timerfd.c raw

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