valeriyvdovin / rpms / systemd

Forked from rpms/systemd 4 years ago
Clone
923a60
From 8afe4259a8add0d042950015d34afc95a221ad96 Mon Sep 17 00:00:00 2001
923a60
From: Lennart Poettering <lennart@poettering.net>
923a60
Date: Wed, 6 Jul 2016 13:47:07 +0200
923a60
Subject: [PATCH] time-util: add parse_time(), which is like parse_sec() but
923a60
 allows specification of default time unit if none is specified
923a60
MIME-Version: 1.0
923a60
Content-Type: text/plain; charset=UTF-8
923a60
Content-Transfer-Encoding: 8bit
923a60
923a60
This is useful if we want to parse RLIMIT_RTTIME values where the common
923a60
UNIX syntax is without any units but refers to a non-second unit (µs in
923a60
this case), but where we want to allow specification of units.
923a60
923a60
Cherry-picked from: 519cffec890510f817740d07355e911b10c203b7
923a60
Related: #1351415
923a60
---
923a60
 src/shared/calendarspec.c |  4 ++--
923a60
 src/shared/time-util.c    | 34 ++++++++++++++++++++++------------
923a60
 src/shared/time-util.h    |  1 +
923a60
 src/test/test-time.c      | 23 +++++++++++++++++++++++
923a60
 src/test/test-unit-file.c |  6 +++---
923a60
 5 files changed, 51 insertions(+), 17 deletions(-)
923a60
923a60
diff --git a/src/shared/calendarspec.c b/src/shared/calendarspec.c
923a60
index 2fde3e107e..abbf0261e7 100644
923a60
--- a/src/shared/calendarspec.c
923a60
+++ b/src/shared/calendarspec.c
923a60
@@ -556,7 +556,7 @@ static int parse_date(const char **p, CalendarSpec *c) {
923a60
         return -EINVAL;
923a60
 }
923a60
 
923a60
-static int parse_time(const char **p, CalendarSpec *c) {
923a60
+static int parse_calendar_time(const char **p, CalendarSpec *c) {
923a60
         CalendarComponent *h = NULL, *m = NULL, *s = NULL;
923a60
         const char *t;
923a60
         int r;
923a60
@@ -789,7 +789,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
923a60
                 if (r < 0)
923a60
                         goto fail;
923a60
 
923a60
-                r = parse_time(&p, c);
923a60
+                r = parse_calendar_time(&p, c);
923a60
                 if (r < 0)
923a60
                         goto fail;
923a60
 
923a60
diff --git a/src/shared/time-util.c b/src/shared/time-util.c
923a60
index 1c36c577c4..c001f52def 100644
923a60
--- a/src/shared/time-util.c
923a60
+++ b/src/shared/time-util.c
923a60
@@ -613,7 +613,8 @@ finish:
923a60
         return 0;
923a60
 }
923a60
 
923a60
-int parse_sec(const char *t, usec_t *usec) {
923a60
+int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
923a60
+
923a60
         static const struct {
923a60
                 const char *suffix;
923a60
                 usec_t usec;
923a60
@@ -645,7 +646,6 @@ int parse_sec(const char *t, usec_t *usec) {
923a60
                 { "y", USEC_PER_YEAR },
923a60
                 { "usec", 1ULL },
923a60
                 { "us", 1ULL },
923a60
-                { "", USEC_PER_SEC }, /* default is sec */
923a60
         };
923a60
 
923a60
         const char *p, *s;
923a60
@@ -654,6 +654,7 @@ int parse_sec(const char *t, usec_t *usec) {
923a60
 
923a60
         assert(t);
923a60
         assert(usec);
923a60
+        assert(default_unit > 0);
923a60
 
923a60
         p = t;
923a60
 
923a60
@@ -672,6 +673,7 @@ int parse_sec(const char *t, usec_t *usec) {
923a60
                 long long l, z = 0;
923a60
                 char *e;
923a60
                 unsigned i, n = 0;
923a60
+                usec_t multiplier, k;
923a60
 
923a60
                 p += strspn(p, WHITESPACE);
923a60
 
923a60
@@ -714,21 +716,24 @@ int parse_sec(const char *t, usec_t *usec) {
923a60
 
923a60
                 for (i = 0; i < ELEMENTSOF(table); i++)
923a60
                         if (startswith(e, table[i].suffix)) {
923a60
-                                usec_t k = (usec_t) z * table[i].usec;
923a60
-
923a60
-                                for (; n > 0; n--)
923a60
-                                        k /= 10;
923a60
-
923a60
-                                r += (usec_t) l * table[i].usec + k;
923a60
+                                multiplier = table[i].usec;
923a60
                                 p = e + strlen(table[i].suffix);
923a60
-
923a60
-                                something = true;
923a60
                                 break;
923a60
                         }
923a60
 
923a60
-                if (i >= ELEMENTSOF(table))
923a60
-                        return -EINVAL;
923a60
+                if (i >= ELEMENTSOF(table)) {
923a60
+                        multiplier = default_unit;
923a60
+                        p = e;
923a60
+                }
923a60
+
923a60
+                something = true;
923a60
+
923a60
+                k = (usec_t) z * multiplier;
923a60
+
923a60
+                for (; n > 0; n--)
923a60
+                        k /= 10;
923a60
 
923a60
+                r += (usec_t) l * multiplier + k;
923a60
         }
923a60
 
923a60
         *usec = r;
923a60
@@ -736,6 +741,11 @@ int parse_sec(const char *t, usec_t *usec) {
923a60
         return 0;
923a60
 }
923a60
 
923a60
+
923a60
+int parse_sec(const char *t, usec_t *usec) {
923a60
+        return parse_time(t, usec, USEC_PER_SEC);
923a60
+}
923a60
+
923a60
 int parse_nsec(const char *t, nsec_t *nsec) {
923a60
         static const struct {
923a60
                 const char *suffix;
923a60
diff --git a/src/shared/time-util.h b/src/shared/time-util.h
923a60
index fca8a4db9b..f2789142fe 100644
923a60
--- a/src/shared/time-util.h
923a60
+++ b/src/shared/time-util.h
923a60
@@ -99,6 +99,7 @@ void dual_timestamp_deserialize(const char *value, dual_timestamp *t);
923a60
 int parse_timestamp(const char *t, usec_t *usec);
923a60
 
923a60
 int parse_sec(const char *t, usec_t *usec);
923a60
+int parse_time(const char *t, usec_t *usec, usec_t default_unit);
923a60
 int parse_nsec(const char *t, nsec_t *nsec);
923a60
 
923a60
 bool ntp_synced(void);
923a60
diff --git a/src/test/test-time.c b/src/test/test-time.c
923a60
index 3840fff061..820e4aaee2 100644
923a60
--- a/src/test/test-time.c
923a60
+++ b/src/test/test-time.c
923a60
@@ -57,6 +57,28 @@ static void test_parse_sec(void) {
923a60
         assert_se(parse_sec(".3 infinity", &u) < 0);
923a60
 }
923a60
 
923a60
+static void test_parse_time(void) {
923a60
+        usec_t u;
923a60
+
923a60
+        assert_se(parse_time("5", &u, 1) >= 0);
923a60
+        assert_se(u == 5);
923a60
+
923a60
+        assert_se(parse_time("5", &u, USEC_PER_MSEC) >= 0);
923a60
+        assert_se(u == 5 * USEC_PER_MSEC);
923a60
+
923a60
+        assert_se(parse_time("5", &u, USEC_PER_SEC) >= 0);
923a60
+        assert_se(u == 5 * USEC_PER_SEC);
923a60
+
923a60
+        assert_se(parse_time("5s", &u, 1) >= 0);
923a60
+        assert_se(u == 5 * USEC_PER_SEC);
923a60
+
923a60
+        assert_se(parse_time("5s", &u, USEC_PER_SEC) >= 0);
923a60
+        assert_se(u == 5 * USEC_PER_SEC);
923a60
+
923a60
+        assert_se(parse_time("5s", &u, USEC_PER_MSEC) >= 0);
923a60
+        assert_se(u == 5 * USEC_PER_SEC);
923a60
+}
923a60
+
923a60
 static void test_parse_nsec(void) {
923a60
         nsec_t u;
923a60
 
923a60
@@ -161,6 +183,7 @@ static void test_get_timezones(void) {
923a60
 
923a60
 int main(int argc, char *argv[]) {
923a60
         test_parse_sec();
923a60
+        test_parse_time();
923a60
         test_parse_nsec();
923a60
         test_format_timespan(1);
923a60
         test_format_timespan(USEC_PER_MSEC);
923a60
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
923a60
index d151737960..87c81ccd71 100644
923a60
--- a/src/test/test-unit-file.c
923a60
+++ b/src/test/test-unit-file.c
923a60
@@ -559,7 +559,7 @@ static void test_config_parse_rlimit(void) {
923a60
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == RLIM_INFINITY);
923a60
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max);
923a60
 
923a60
-        rl[RLIMIT_NOFILE] = free(rl[RLIMIT_NOFILE]);
923a60
+        free(rl[RLIMIT_NOFILE]);
923a60
         assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "56", rl, NULL) >= 0);
923a60
         assert_se(rl[RLIMIT_CPU]);
923a60
         assert_se(rl[RLIMIT_CPU]->rlim_cur == 56);
923a60
@@ -580,7 +580,7 @@ static void test_config_parse_rlimit(void) {
923a60
         assert_se(rl[RLIMIT_CPU]->rlim_cur == 2);
923a60
         assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
923a60
 
923a60
-        rl[RLIMIT_CPU] = free(rl[RLIMIT_CPU]);
923a60
+        free(rl[RLIMIT_CPU]);
923a60
 
923a60
         assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "58", rl, NULL) >= 0);
923a60
         assert_se(rl[RLIMIT_RTTIME]);
923a60
@@ -602,7 +602,7 @@ static void test_config_parse_rlimit(void) {
923a60
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 2345 * USEC_PER_MSEC);
923a60
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
923a60
 
923a60
-        rl[RLIMIT_RTTIME] = free(rl[RLIMIT_RTTIME]);
923a60
+        free(rl[RLIMIT_RTTIME]);
923a60
 }
923a60
 
923a60
 int main(int argc, char *argv[]) {