From ff69484a1faa82bb7b7929de2c6673f1f7e7b2cc Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Tue, 19 Sep 2017 17:00:56 +0200 Subject: [PATCH 1/3] time-util: fix shadowing of timezone timezone was shadowing timezone from time.h which leads to a buildbreak since systemd is built with -Werror --- src/basic/time-util.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/basic/time-util.c b/src/basic/time-util.c index 00979bfe59..defb2766e2 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -883,16 +883,16 @@ typedef struct ParseTimestampResult { } ParseTimestampResult; int parse_timestamp(const char *t, usec_t *usec) { - char *last_space, *timezone = NULL; + char *last_space, *tz = NULL; ParseTimestampResult *shared, tmp; int r; pid_t pid; last_space = strrchr(t, ' '); if (last_space != NULL && timezone_is_valid(last_space + 1)) - timezone = last_space + 1; + tz = last_space + 1; - if (timezone == NULL || endswith_no_case(t, " UTC")) + if (tz == NULL || endswith_no_case(t, " UTC")) return parse_timestamp_impl(t, usec, false); t = strndupa(t, last_space - t); @@ -910,7 +910,7 @@ int parse_timestamp(const char *t, usec_t *usec) { } if (pid == 0) { - if (setenv("TZ", timezone, 1) != 0) { + if (setenv("TZ", tz, 1) != 0) { shared->return_value = negative_errno(); _exit(EXIT_FAILURE); } From 3fd4929b960776b5368222688cecabd6ec958f7b Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 20 Sep 2017 14:47:49 +0200 Subject: [PATCH 2/3] time-util: correctly handle the timezone when parsing The timezone was cut off the string once the timezone was not UTC. If it is not UTC but a other timezone that matches tzname[0] or tzname[1], then we can leave it to the impl function to parse that correctly. If not we can just fallback to whatever is the current timezone is in the given t_timezone. This should fix the testuite and tests. --- src/basic/time-util.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/basic/time-util.c b/src/basic/time-util.c index defb2766e2..bcfa42714d 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -895,8 +895,6 @@ int parse_timestamp(const char *t, usec_t *usec) { if (tz == NULL || endswith_no_case(t, " UTC")) return parse_timestamp_impl(t, usec, false); - t = strndupa(t, last_space - t); - shared = mmap(NULL, sizeof *shared, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); if (shared == MAP_FAILED) return negative_errno(); @@ -910,6 +908,8 @@ int parse_timestamp(const char *t, usec_t *usec) { } if (pid == 0) { + bool with_tz = true; + if (setenv("TZ", tz, 1) != 0) { shared->return_value = negative_errno(); _exit(EXIT_FAILURE); @@ -917,7 +917,15 @@ int parse_timestamp(const char *t, usec_t *usec) { tzset(); - shared->return_value = parse_timestamp_impl(t, &shared->usec, true); + /* If there is a timezone that matches the tzname fields, leave the parsing to the implementation. + * Otherwise just cut it off */ + with_tz = !STR_IN_SET(tz, tzname[0], tzname[1]); + + /*cut off the timezone if we dont need it*/ + if (with_tz) + t = strndupa(t, last_space - t); + + shared->return_value = parse_timestamp_impl(t, &shared->usec, with_tz); _exit(EXIT_SUCCESS); } From 214cc95d7bfd6bd22a17c2ac1ab84e31d2e82640 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 20 Sep 2017 19:26:13 +0200 Subject: [PATCH 3/3] time-util: mktime_or_timegm are changing the struct tm after that wm_day etc. seems to be changed. Moving the check infront of the mktime_or_timegm fixes that. --- src/basic/time-util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/basic/time-util.c b/src/basic/time-util.c index bcfa42714d..f67467c5bd 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -849,11 +849,11 @@ parse_usec: } from_tm: - x = mktime_or_timegm(&tm, utc); - if (x < 0) + if (weekday >= 0 && tm.tm_wday != weekday) return -EINVAL; - if (weekday >= 0 && tm.tm_wday != weekday) + x = mktime_or_timegm(&tm, utc); + if (x < 0) return -EINVAL; ret = (usec_t) x * USEC_PER_SEC + x_usec;