diff options
author | Lennart Poettering <lennart@poettering.net> | 2024-08-28 14:10:01 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2024-09-05 17:40:25 +0200 |
commit | 6f5cf41570776f489967d1a7de18260b2bc9acf9 (patch) | |
tree | 0c94612f28294ccf45e6f737c439d0f921c88cc2 /src/systemctl/systemctl-sysv-compat.c | |
parent | hwclock-util: the struct tm parameter is not a pure return parameter, it's al... (diff) | |
download | systemd-6f5cf41570776f489967d1a7de18260b2bc9acf9.tar.xz systemd-6f5cf41570776f489967d1a7de18260b2bc9acf9.zip |
time-util: rework localtime_or_gmtime() into localtime_or_gmtime_usec()
We typically want to deal in usec_t, hence let's change the prototype
accordingly, and do proper range checks. Also, make sure are not
confused by negative times.
Do something similar for mktime_or_timegm().
This is a more comprehensive alternative to #34065
Replaces: #34065
Diffstat (limited to 'src/systemctl/systemctl-sysv-compat.c')
-rw-r--r-- | src/systemctl/systemctl-sysv-compat.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/src/systemctl/systemctl-sysv-compat.c b/src/systemctl/systemctl-sysv-compat.c index 8ee16eb13f..cb9c43e3dc 100644 --- a/src/systemctl/systemctl-sysv-compat.c +++ b/src/systemctl/systemctl-sysv-compat.c @@ -58,6 +58,8 @@ int talk_initctl(char rl) { } int parse_shutdown_time_spec(const char *t, usec_t *ret) { + int r; + assert(t); assert(ret); @@ -73,9 +75,6 @@ int parse_shutdown_time_spec(const char *t, usec_t *ret) { } else { char *e = NULL; long hour, minute; - struct tm tm = {}; - time_t s; - usec_t n; errno = 0; hour = strtol(t, &e, 10); @@ -86,22 +85,26 @@ int parse_shutdown_time_spec(const char *t, usec_t *ret) { if (errno > 0 || *e != 0 || minute < 0 || minute > 59) return -EINVAL; - n = now(CLOCK_REALTIME); - s = (time_t) (n / USEC_PER_SEC); + usec_t n = now(CLOCK_REALTIME); + struct tm tm = {}; - assert_se(localtime_r(&s, &tm)); + r = localtime_or_gmtime_usec(n, /* utc= */ false, &tm); + if (r < 0) + return r; tm.tm_hour = (int) hour; tm.tm_min = (int) minute; tm.tm_sec = 0; - s = mktime(&tm); - assert(s >= 0); + usec_t s; + r = mktime_or_timegm_usec(&tm, /* utc= */ false, &s); + if (r < 0) + return r; - *ret = (usec_t) s * USEC_PER_SEC; + while (s <= n) + s += USEC_PER_DAY; - while (*ret <= n) - *ret += USEC_PER_DAY; + *ret = s; } return 0; |