summaryrefslogtreecommitdiffstats
path: root/src/systemctl/systemctl-sysv-compat.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2024-08-28 14:10:01 +0200
committerLennart Poettering <lennart@poettering.net>2024-09-05 17:40:25 +0200
commit6f5cf41570776f489967d1a7de18260b2bc9acf9 (patch)
tree0c94612f28294ccf45e6f737c439d0f921c88cc2 /src/systemctl/systemctl-sysv-compat.c
parenthwclock-util: the struct tm parameter is not a pure return parameter, it's al... (diff)
downloadsystemd-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.c25
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;