aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2015-11-09 17:26:52 +0100
committerMattias Andrée <maandree@operamail.com>2015-11-09 17:26:52 +0100
commitf0d9e04e62e0749d55c04ad3b68aa6fa8824d2cf (patch)
tree16ae243ff1c59a5b17d5f404bc5803bbfcfa65ee
parentonly one timers is necessary (diff)
downloadsleep-until-f0d9e04e62e0749d55c04ad3b68aa6fa8824d2cf.tar.gz
sleep-until-f0d9e04e62e0749d55c04ad3b68aa6fa8824d2cf.tar.bz2
sleep-until-f0d9e04e62e0749d55c04ad3b68aa6fa8824d2cf.tar.xz
fix errors + perform sleep
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r--src/sleep-until.c41
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;
}