diff options
| author | Michael Biebl <biebl@debian.org> | 2019-12-18 18:29:24 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2019-12-18 18:29:24 +0100 |
| commit | 28028b26b3371756811e95d894f709f4b1207c00 (patch) | |
| tree | 6fe7316fd743b51042db47601a8ef8814b3134ac /shared/systemd/src/basic/time-util.c | |
| parent | e22609983008e1a669196ad64ba3a59ae8c76e0d (diff) | |
New upstream version 1.22.0 upstream/1.22.0
Diffstat (limited to 'shared/systemd/src/basic/time-util.c')
| -rw-r--r-- | shared/systemd/src/basic/time-util.c | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/shared/systemd/src/basic/time-util.c b/shared/systemd/src/basic/time-util.c index aa790023..4411127a 100644 --- a/shared/systemd/src/basic/time-util.c +++ b/shared/systemd/src/basic/time-util.c @@ -6,9 +6,7 @@ #include <errno.h> #include <limits.h> #include <stdlib.h> -#include <string.h> #include <sys/mman.h> -#include <sys/stat.h> #include <sys/time.h> #include <sys/timerfd.h> #include <sys/timex.h> @@ -839,8 +837,12 @@ int parse_timestamp(const char *t, usec_t *usec) { } if (r == 0) { bool with_tz = true; + char *colon_tz; - if (setenv("TZ", tz, 1) != 0) { + /* tzset(3) says $TZ should be prefixed with ":" if we reference timezone files */ + colon_tz = strjoina(":", tz); + + if (setenv("TZ", colon_tz, 1) != 0) { shared->return_value = negative_errno(); _exit(EXIT_FAILURE); } @@ -1196,7 +1198,10 @@ bool ntp_synced(void) { if (adjtimex(&txc) < 0) return false; - if (txc.status & STA_UNSYNC) + /* Consider the system clock synchronized if the reported maximum error is smaller than the maximum + * value (16 seconds). Ignore the STA_UNSYNC flag as it may have been set to prevent the kernel from + * touching the RTC. */ + if (txc.maxerror >= 16000000) return false; return true; @@ -1262,6 +1267,7 @@ int get_timezones(char ***ret) { } strv_sort(zones); + strv_uniq(zones); } else if (errno != ENOENT) return -errno; @@ -1282,6 +1288,10 @@ bool timezone_is_valid(const char *name, int log_level) { if (isempty(name)) return false; + /* Always accept "UTC" as valid timezone, since it's the fallback, even if user has no timezones installed. */ + if (streq(name, "UTC")) + return true; + if (name[0] == '/') return false; @@ -1388,13 +1398,22 @@ bool clock_supported(clockid_t clock) { } #if 0 /* NM_IGNORED */ -int get_timezone(char **tz) { +int get_timezone(char **ret) { _cleanup_free_ char *t = NULL; const char *e; char *z; int r; r = readlink_malloc("/etc/localtime", &t); + if (r == -ENOENT) { + /* If the symlink does not exist, assume "UTC", like glibc does*/ + z = strdup("UTC"); + if (!z) + return -ENOMEM; + + *ret = z; + return 0; + } if (r < 0) return r; /* returns EINVAL if not a symlink */ @@ -1409,7 +1428,7 @@ int get_timezone(char **tz) { if (!z) return -ENOMEM; - *tz = z; + *ret = z; return 0; } @@ -1421,8 +1440,8 @@ struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc) { return utc ? gmtime_r(t, tm) : localtime_r(t, tm); } -unsigned long usec_to_jiffies(usec_t u) { - static thread_local unsigned long hz = 0; +static uint32_t sysconf_clock_ticks_cached(void) { + static thread_local uint32_t hz = 0; long r; if (hz == 0) { @@ -1432,7 +1451,17 @@ unsigned long usec_to_jiffies(usec_t u) { hz = r; } - return DIV_ROUND_UP(u , USEC_PER_SEC / hz); + return hz; +} + +uint32_t usec_to_jiffies(usec_t u) { + uint32_t hz = sysconf_clock_ticks_cached(); + return DIV_ROUND_UP(u, USEC_PER_SEC / hz); +} + +usec_t jiffies_to_usec(uint32_t j) { + uint32_t hz = sysconf_clock_ticks_cached(); + return DIV_ROUND_UP(j * USEC_PER_SEC, hz); } usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) { |