Add millisecord parsing support to conf parser. Immediate usage of this function is to parse bond options such as MIIMonitor, UpDelayMSec, DownDelayMSec which is represented in milli seconds. --- src/shared/conf-parser.c | 1 + src/shared/conf-parser.h | 1 + src/shared/time-util.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++ src/shared/time-util.h | 8 ++++ 4 files changed, 118 insertions(+)
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index 1f40986..07e8c76 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -451,6 +451,7 @@ DEFINE_PARSER(unsigned, unsigned, safe_atou) DEFINE_PARSER(double, double, safe_atod) DEFINE_PARSER(nsec, nsec_t, parse_nsec) DEFINE_PARSER(sec, usec_t, parse_sec) +DEFINE_PARSER(msec, msec_t, parse_msec) int config_parse_iec_size(const char* unit, const char *filename, diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index 3e2c784..671e207 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -106,6 +106,7 @@ int config_parse_path(const char *unit, const char *filename, unsigned line, con int config_parse_strv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_sec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_nsec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_msec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_log_facility(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_log_level(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/shared/time-util.c b/src/shared/time-util.c index fc79c56..58d8a67 100644 --- a/src/shared/time-util.c +++ b/src/shared/time-util.c @@ -816,6 +816,114 @@ int parse_nsec(const char *t, nsec_t *nsec) { return 0; } +int parse_msec(const char *t, msec_t *msec) { + static const struct { + const char *suffix; + msec_t msec; + } table[] = { + { "seconds", MSEC_PER_SEC }, + { "second", MSEC_PER_SEC }, + { "sec", MSEC_PER_SEC }, + { "s", MSEC_PER_SEC }, + { "minutes", MSEC_PER_MINUTE }, + { "minute", MSEC_PER_MINUTE }, + { "min", MSEC_PER_MINUTE }, + { "months", MSEC_PER_MONTH }, + { "month", MSEC_PER_MONTH }, + { "m", MSEC_PER_MINUTE }, + { "hours", MSEC_PER_HOUR }, + { "hour", MSEC_PER_HOUR }, + { "hr", MSEC_PER_HOUR }, + { "h", MSEC_PER_HOUR }, + { "days", MSEC_PER_DAY }, + { "day", MSEC_PER_DAY }, + { "d", MSEC_PER_DAY }, + { "weeks", MSEC_PER_WEEK }, + { "week", MSEC_PER_WEEK }, + { "w", MSEC_PER_WEEK }, + { "years", MSEC_PER_YEAR }, + { "year", MSEC_PER_YEAR }, + { "y", MSEC_PER_YEAR }, + { "", 1ULL }, /* default is msec */ + }; + + const char *p; + msec_t r = 0; + bool something = false; + + assert(t); + assert(msec); + + p = t; + for (;;) { + long long l, z = 0; + char *e; + unsigned i, n = 0; + + p += strspn(p, WHITESPACE); + + if (*p == 0) { + if (!something) + return -EINVAL; + + break; + } + + errno = 0; + l = strtoll(p, &e, 10); + + if (errno > 0) + return -errno; + + if (l < 0) + return -ERANGE; + + if (*e == '.') { + char *b = e + 1; + + errno = 0; + z = strtoll(b, &e, 10); + if (errno > 0) + return -errno; + + if (z < 0) + return -ERANGE; + + if (e == b) + return -EINVAL; + + n = e - b; + + } else if (e == p) + return -EINVAL; + + e += strspn(e, WHITESPACE); + + for (i = 0; i < ELEMENTSOF(table); i++) + if (startswith(e, table[i].suffix)) { + msec_t k = (msec_t) z * table[i].msec; + + for (; n > 0; n--) + k /= 10; + + r += (msec_t) l * table[i].msec + k; + p = e + strlen(table[i].suffix); + + something = true; + break; + } + + if (i >= ELEMENTSOF(table)) + return -EINVAL; + + } + + *msec = r; + + return 0; +} + + bool ntp_synced(void) { struct timex txc = {}; diff --git a/src/shared/time-util.h b/src/shared/time-util.h index 792cd27..3969df8 100644 --- a/src/shared/time-util.h +++ b/src/shared/time-util.h @@ -26,6 +26,7 @@ typedef uint64_t usec_t; typedef uint64_t nsec_t; +typedef uint64_t msec_t; #define NSEC_FMT "%" PRIu64 #define USEC_FMT "%" PRIu64 @@ -46,16 +47,22 @@ typedef struct dual_timestamp { #define USEC_PER_MINUTE ((usec_t) (60ULL*USEC_PER_SEC)) #define NSEC_PER_MINUTE ((usec_t) (60ULL*NSEC_PER_SEC)) +#define MSEC_PER_MINUTE ((usec_t) (60ULL*MSEC_PER_SEC)) #define USEC_PER_HOUR ((usec_t) (60ULL*USEC_PER_MINUTE)) #define NSEC_PER_HOUR ((usec_t) (60ULL*NSEC_PER_MINUTE)) +#define MSEC_PER_HOUR ((usec_t) (60ULL*MSEC_PER_MINUTE)) #define USEC_PER_DAY ((usec_t) (24ULL*USEC_PER_HOUR)) #define NSEC_PER_DAY ((usec_t) (24ULL*NSEC_PER_HOUR)) +#define MSEC_PER_DAY ((usec_t) (24ULL*MSEC_PER_HOUR)) #define USEC_PER_WEEK ((usec_t) (7ULL*USEC_PER_DAY)) #define NSEC_PER_WEEK ((usec_t) (7ULL*NSEC_PER_DAY)) +#define MSEC_PER_WEEK ((usec_t) (7ULL*MSEC_PER_DAY)) #define USEC_PER_MONTH ((usec_t) (2629800ULL*USEC_PER_SEC)) #define NSEC_PER_MONTH ((usec_t) (2629800ULL*NSEC_PER_SEC)) +#define MSEC_PER_MONTH ((usec_t) (2629800ULL*MSEC_PER_SEC)) #define USEC_PER_YEAR ((usec_t) (31557600ULL*USEC_PER_SEC)) #define NSEC_PER_YEAR ((usec_t) (31557600ULL*NSEC_PER_SEC)) +#define MSEC_PER_YEAR ((usec_t) (31557600ULL*MSEC_PER_SEC)) #define FORMAT_TIMESTAMP_MAX ((4*4+1)+11+9+4+1) /* weekdays can be unicode */ #define FORMAT_TIMESTAMP_WIDTH 28 /* when outputting, assume this width */ @@ -93,6 +100,7 @@ int parse_timestamp(const char *t, usec_t *usec); int parse_sec(const char *t, usec_t *usec); int parse_nsec(const char *t, nsec_t *nsec); +int parse_msec(const char *t, msec_t *msec); bool ntp_synced(void); -- 1.9.3 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel