summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/conf-parser.c25
-rw-r--r--src/shared/conf-parser.h1
-rw-r--r--src/shared/util.c67
-rw-r--r--src/shared/util.h8
4 files changed, 100 insertions, 1 deletions
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index 65035e4c6a..724bcf00c9 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -817,6 +817,31 @@ int config_parse_usec(
return 0;
}
+int config_parse_nsec(
+ const char *filename,
+ unsigned line,
+ const char *section,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ nsec_t *nsec = data;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (parse_nsec(rvalue, nsec) < 0) {
+ log_error("[%s:%u] Failed to parse time value, ignoring: %s", filename, line, rvalue);
+ return 0;
+ }
+
+ return 0;
+}
+
int config_parse_mode(
const char *filename,
unsigned line,
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
index d37029f083..9e5f81d56b 100644
--- a/src/shared/conf-parser.h
+++ b/src/shared/conf-parser.h
@@ -102,6 +102,7 @@ int config_parse_path(const char *filename, unsigned line, const char *section,
int config_parse_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_path_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_usec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_nsec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
diff --git a/src/shared/util.c b/src/shared/util.c
index 70b159f8c3..9db2a6b2a2 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -2707,7 +2707,7 @@ int parse_usec(const char *t, usec_t *usec) {
{ "m", USEC_PER_MINUTE },
{ "usec", 1ULL },
{ "us", 1ULL },
- { "", USEC_PER_SEC },
+ { "", USEC_PER_SEC }, /* default is sec */
};
const char *p;
@@ -2753,6 +2753,71 @@ int parse_usec(const char *t, usec_t *usec) {
return 0;
}
+int parse_nsec(const char *t, nsec_t *nsec) {
+ static const struct {
+ const char *suffix;
+ nsec_t nsec;
+ } table[] = {
+ { "sec", NSEC_PER_SEC },
+ { "s", NSEC_PER_SEC },
+ { "min", NSEC_PER_MINUTE },
+ { "hr", NSEC_PER_HOUR },
+ { "h", NSEC_PER_HOUR },
+ { "d", NSEC_PER_DAY },
+ { "w", NSEC_PER_WEEK },
+ { "msec", NSEC_PER_MSEC },
+ { "ms", NSEC_PER_MSEC },
+ { "m", NSEC_PER_MINUTE },
+ { "usec", NSEC_PER_USEC },
+ { "us", NSEC_PER_USEC },
+ { "nsec", 1ULL },
+ { "ns", 1ULL },
+ { "", 1ULL }, /* default is nsec */
+ };
+
+ const char *p;
+ nsec_t r = 0;
+
+ assert(t);
+ assert(nsec);
+
+ p = t;
+ do {
+ long long l;
+ char *e;
+ unsigned i;
+
+ errno = 0;
+ l = strtoll(p, &e, 10);
+
+ if (errno != 0)
+ return -errno;
+
+ if (l < 0)
+ return -ERANGE;
+
+ if (e == p)
+ return -EINVAL;
+
+ e += strspn(e, WHITESPACE);
+
+ for (i = 0; i < ELEMENTSOF(table); i++)
+ if (startswith(e, table[i].suffix)) {
+ r += (nsec_t) l * table[i].nsec;
+ p = e + strlen(table[i].suffix);
+ break;
+ }
+
+ if (i >= ELEMENTSOF(table))
+ return -EINVAL;
+
+ } while (*p != 0);
+
+ *nsec = r;
+
+ return 0;
+}
+
int parse_bytes(const char *t, off_t *bytes) {
static const struct {
const char *suffix;
diff --git a/src/shared/util.h b/src/shared/util.h
index 35ff2e3547..18b2930e18 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -39,6 +39,7 @@
#include "macro.h"
typedef uint64_t usec_t;
+typedef unsigned long nsec_t;
typedef struct dual_timestamp {
usec_t realtime;
@@ -53,11 +54,17 @@ typedef struct dual_timestamp {
#define NSEC_PER_USEC 1000ULL
#define USEC_PER_MINUTE (60ULL*USEC_PER_SEC)
+#define NSEC_PER_MINUTE (60ULL*NSEC_PER_SEC)
#define USEC_PER_HOUR (60ULL*USEC_PER_MINUTE)
+#define NSEC_PER_HOUR (60ULL*NSEC_PER_MINUTE)
#define USEC_PER_DAY (24ULL*USEC_PER_HOUR)
+#define NSEC_PER_DAY (24ULL*NSEC_PER_HOUR)
#define USEC_PER_WEEK (7ULL*USEC_PER_DAY)
+#define NSEC_PER_WEEK (7ULL*NSEC_PER_DAY)
#define USEC_PER_MONTH (2629800ULL*USEC_PER_SEC)
+#define NSEC_PER_MONTH (2629800ULL*NSEC_PER_SEC)
#define USEC_PER_YEAR (31557600ULL*USEC_PER_SEC)
+#define NSEC_PER_YEAR (31557600ULL*NSEC_PER_SEC)
/* What is interpreted as whitespace? */
#define WHITESPACE " \t\n\r"
@@ -139,6 +146,7 @@ void close_many(const int fds[], unsigned n_fd);
int parse_boolean(const char *v);
int parse_usec(const char *t, usec_t *usec);
+int parse_nsec(const char *t, nsec_t *nsec);
int parse_bytes(const char *t, off_t *bytes);
int parse_pid(const char *s, pid_t* ret_pid);
int parse_uid(const char *s, uid_t* ret_uid);