diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/sleep-until.c | 41 | 
1 files changed, 36 insertions, 5 deletions
| diff --git a/src/sleep-until.c b/src/sleep-until.c index 6b21cba..6177e80 100644 --- a/src/sleep-until.c +++ b/src/sleep-until.c @@ -19,7 +19,10 @@  #include <sys/timerfd.h>  #include <string.h>  #include <stdlib.h> - +#include <stdint.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h>  int main(int argc, char* argv[]) @@ -28,13 +31,14 @@ int main(int argc, char* argv[])    char float_part[10];    struct itimerspec value;    struct itimerspec largest_value; -  int i; +  int i, fd = -1; +  uint64_t _expirations;    if (argc < 2)      return 0;    argv0 = argv[0]; -  argc--, argv--; +  argc--, argv++;    memset(&value, 0, sizeof(value));    float_part[9] = '\0'; @@ -65,12 +69,39 @@ int main(int argc, char* argv[])  	largest_value = value;        else if (value.it_value.tv_sec > largest_value.it_value.tv_sec)  	largest_value = value; -      else if (value.it_value.tv_nsec > largest_value.it_value.tv_nsec) -	largest_value = value; +      else if (value.it_value.tv_sec == largest_value.it_value.tv_sec) +	if (value.it_value.tv_nsec > largest_value.it_value.tv_nsec) +	  largest_value = value;      } +  fd = timerfd_create(CLOCK_REALTIME, 0); +  if (fd < 0) +    goto fail; +  if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &largest_value, NULL)) +    goto fail; +  for (;;) +    { +      if (clock_gettime(CLOCK_REALTIME, &(value.it_value))) +	goto fail; +      if (value.it_value.tv_sec > largest_value.it_value.tv_sec) +        break; +      if (value.it_value.tv_sec == largest_value.it_value.tv_sec) +	if (value.it_value.tv_nsec >= largest_value.it_value.tv_nsec) +	  break; +      if (read(fd, &_expirations, 8) < 8) +	{ +	  if (errno == EINTR) +	    continue; +	  goto fail; +	} +    } +  close(fd);    return 0; + fail: +  perror(argv0); +  if (fd >= 0)  close(fd); +  return 1;  } | 
