summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-05-29 12:55:33 +0200
committerSven Eden <yamakuzure@gmx.net>2018-08-24 16:47:08 +0200
commite5743c1e0d822766cdd20756ec48ee781c6a2aee (patch)
treefddded280c70f0b2780bd112668249dde3d32a3a /src/basic
parenteed5a7bdfdce83b00734d7d40fa29f271871acf7 (diff)
time-util: introduce common implementation of TFD_TIMER_CANCEL_ON_SET client code
We now use pretty much the same code at three places, let's unify that.
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/time-util.c24
-rw-r--r--src/basic/time-util.h2
2 files changed, 26 insertions, 0 deletions
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
index dc8db13c2..71d6179ef 100644
--- a/src/basic/time-util.c
+++ b/src/basic/time-util.c
@@ -1496,3 +1496,27 @@ bool in_utc_timezone(void) {
return timezone == 0 && daylight == 0;
}
+
+int time_change_fd(void) {
+
+ /* We only care for the cancellation event, hence we set the timeout to the latest possible value. */
+ static const struct itimerspec its = {
+ .it_value.tv_sec = TIME_T_MAX,
+ };
+
+ _cleanup_close_ int fd;
+
+ assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
+
+ /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever CLOCK_REALTIME makes a jump relative to
+ * CLOCK_MONOTONIC. */
+
+ fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
+ if (fd < 0)
+ return -errno;
+
+ if (timerfd_settime(fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0)
+ return -errno;
+
+ return TAKE_FD(fd);
+}
diff --git a/src/basic/time-util.h b/src/basic/time-util.h
index fec051109..94534794a 100644
--- a/src/basic/time-util.h
+++ b/src/basic/time-util.h
@@ -209,3 +209,5 @@ static inline usec_t usec_sub_signed(usec_t timestamp, int64_t delta) {
#else
#error "Yuck, time_t is neither 4 nor 8 bytes wide?"
#endif
+
+int time_change_fd(void);