Search code examples
c++linuxtimezonedstntp

How to detect change of system time in Linux?


Is there a way to get notified when there is update to the system time from a time-server or due to DST change? I am after an API/system call or equivalent.

It is part of my effort to optimise generating a value for something similar to SQL NOW() to an hour granularity, without using SQL.


Solution

  • You can use timerfd_create(2) to create a timer, then mark it with the TFD_TIMER_CANCEL_ON_SET option when setting it. Set it for an implausible time in the future and then block on it (with poll/select etc.) - if the system time changes then the timer will be cancelled, which you can detect.

    (this is how systemd does it)

    e.g.:

    #include <sys/timerfd.h>
    #include <limits.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
    
    int main(void) {
            int fd = timerfd_create(CLOCK_REALTIME, 0);
            timerfd_settime(fd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET,
                            &(struct itimerspec){ .it_value = { .tv_sec = INT_MAX } },
                            NULL);
            printf("Waiting\n");
            char buffer[10];
            if (-1 == read(fd, &buffer, 10)) {
                    if (errno == ECANCELED)
                            printf("Timer cancelled - system clock changed\n");
                    else
                            perror("error");
            }
            close(fd);
            return 0;
    }