Skip to content

Instantly share code, notes, and snippets.

@mwgamera
Created October 25, 2018 14:42
Show Gist options
  • Save mwgamera/295d3591c759df25722dfb03ecd47b19 to your computer and use it in GitHub Desktop.
Save mwgamera/295d3591c759df25722dfb03ecd47b19 to your computer and use it in GitHub Desktop.
/* settai -- update kernel's TAI-UTC offset from tzdata
* klg, Oct 2018 */
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/timex.h>
static void set_utctz(const char *tz) {
if (setenv("TZ", tz, 1) < 0) {
perror("setenv");
exit(EXIT_FAILURE);
}
tzset();
if (tzname[0][0] != 'U' || tzname[0][1] != 'T' ||
tzname[0][2] != 'C' || tzname[0][3] != 0) {
fprintf(stderr, "%s: Zone not set\n", tz);
exit(EXIT_FAILURE);
}
}
static int get_tzdtai(time_t t) {
struct tm *tm;
time_t tai;
set_utctz("posix/UTC");
if ((tm = gmtime(&t)) == NULL) {
perror("gmtime");
exit(EXIT_FAILURE);
}
set_utctz("right/UTC");
if ((tai = mktime(tm)) == (time_t)-1) {
perror("mktime");
exit(EXIT_FAILURE);
}
return tai - t + 10;
}
int main(int argc, char **argv) {
struct timex tx;
if (argc > 1) {
tx.constant = atoi(argv[1]);
}
else {
tx.modes = 0;
switch (ntp_adjtime(&tx)) {
case TIME_OOP:
fprintf(stderr, "Leap second in progress\n");
exit(EXIT_FAILURE);
case -1:
perror("ntp_adjtime");
exit(EXIT_FAILURE);
}
tx.constant = get_tzdtai(tx.time.tv_sec);
}
tx.modes = MOD_TAI;
if (ntp_adjtime(&tx) == -1) {
perror("ntp_adjtime");
exit(EXIT_FAILURE);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment