]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/basic/time-util.c
tree-wide: drop stat.h or statfs.h when stat-util.h is included
[thirdparty/systemd.git] / src / basic / time-util.c
index 5dc3a7990ba35cea2a41c18b5b75d4c30a86deb7..837948c253301a39737908a1ec352bcc73dbcdd5 100644 (file)
@@ -4,9 +4,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>
 #include <unistd.h>
 
 #include "alloc-util.h"
-#include "def.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "fs-util.h"
 #include "io-util.h"
 #include "log.h"
 #include "macro.h"
+#include "missing_timerfd.h"
 #include "parse-util.h"
 #include "path-util.h"
 #include "process-util.h"
-#include "serialize.h"
 #include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
@@ -268,13 +265,12 @@ static char *format_timestamp_internal(
 
         assert(buf);
 
-        if (l <
-            3 +                  /* week day */
-            1 + 10 +             /* space and date */
-            1 + 8 +              /* space and time */
-            (us ? 1 + 6 : 0) +   /* "." and microsecond part */
-            1 + 1 +              /* space and shortest possible zone */
-            1)
+        if (l < (size_t) (3 +                  /* week day */
+                          1 + 10 +             /* space and date */
+                          1 + 8 +              /* space and time */
+                          (us ? 1 + 6 : 0) +   /* "." and microsecond part */
+                          1 + 1 +              /* space and shortest possible zone */
+                          1))
                 return NULL; /* Not enough space even for the shortest form. */
         if (t <= 0 || t == USEC_INFINITY)
                 return NULL; /* Timestamp is unset */
@@ -576,7 +572,6 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
          */
 
         assert(t);
-        assert(usec);
 
         if (t[0] == '@' && !with_tz)
                 return parse_sec(t + 1, usec);
@@ -804,8 +799,8 @@ finish:
         else
                 return -EINVAL;
 
-        *usec = ret;
-
+        if (usec)
+                *usec = ret;
         return 0;
 }
 
@@ -862,7 +857,7 @@ int parse_timestamp(const char *t, usec_t *usec) {
         if (munmap(shared, sizeof *shared) != 0)
                 return negative_errno();
 
-        if (tmp.return_value == 0)
+        if (tmp.return_value == 0 && usec)
                 *usec = tmp.usec;
 
         return tmp.return_value;
@@ -924,7 +919,6 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
         bool something = false;
 
         assert(t);
-        assert(usec);
         assert(default_unit > 0);
 
         p = t;
@@ -936,7 +930,8 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
                 if (*s != 0)
                         return -EINVAL;
 
-                *usec = USEC_INFINITY;
+                if (usec)
+                        *usec = USEC_INFINITY;
                 return 0;
         }
 
@@ -1008,8 +1003,8 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
                 }
         }
 
-        *usec = r;
-
+        if (usec)
+                *usec = r;
         return 0;
 }
 
@@ -1032,6 +1027,15 @@ int parse_sec_fix_0(const char *t, usec_t *ret) {
         return r;
 }
 
+int parse_sec_def_infinity(const char *t, usec_t *ret) {
+        t += strspn(t, WHITESPACE);
+        if (isempty(t)) {
+                *ret = USEC_INFINITY;
+                return 0;
+        }
+        return parse_sec(t, ret);
+}
+
 static const char* extract_nsec_multiplier(const char *p, nsec_t *multiplier) {
         static const struct {
                 const char *suffix;
@@ -1185,7 +1189,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;
@@ -1199,14 +1206,14 @@ int get_timezones(char ***ret) {
 
         assert(ret);
 
-        zones = strv_new("UTC", NULL);
+        zones = strv_new("UTC");
         if (!zones)
                 return -ENOMEM;
 
         n_allocated = 2;
         n_zones = 1;
 
-        f = fopen("/usr/share/zoneinfo/zone.tab", "re");
+        f = fopen("/usr/share/zoneinfo/zone1970.tab", "re");
         if (f) {
                 for (;;) {
                         _cleanup_free_ char *line = NULL;
@@ -1385,9 +1392,7 @@ int get_timezone(char **tz) {
         if (r < 0)
                 return r; /* returns EINVAL if not a symlink */
 
-        e = path_startswith(t, "/usr/share/zoneinfo/");
-        if (!e)
-                e = path_startswith(t, "../usr/share/zoneinfo/");
+        e = PATH_STARTSWITH_SET(t, "/usr/share/zoneinfo/", "../usr/share/zoneinfo/");
         if (!e)
                 return -EINVAL;
 
@@ -1410,8 +1415,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) {
@@ -1421,7 +1426,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) {