summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/calendarspec.c4
-rw-r--r--src/basic/def.h24
-rw-r--r--src/basic/extract-word.c141
-rw-r--r--src/basic/parse-util.c100
-rw-r--r--src/basic/time-util.c33
-rw-r--r--src/basic/time-util.h1
-rw-r--r--src/basic/virt.c2
7 files changed, 176 insertions, 129 deletions
diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c
index a6a906f453..7151fc3d0c 100644
--- a/src/basic/calendarspec.c
+++ b/src/basic/calendarspec.c
@@ -562,7 +562,7 @@ static int parse_date(const char **p, CalendarSpec *c) {
return -EINVAL;
}
-static int parse_time(const char **p, CalendarSpec *c) {
+static int parse_calendar_time(const char **p, CalendarSpec *c) {
CalendarComponent *h = NULL, *m = NULL, *s = NULL;
const char *t;
int r;
@@ -802,7 +802,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
if (r < 0)
goto fail;
- r = parse_time(&p, c);
+ r = parse_calendar_time(&p, c);
if (r < 0)
goto fail;
diff --git a/src/basic/def.h b/src/basic/def.h
index 950f693899..0657ac7367 100644
--- a/src/basic/def.h
+++ b/src/basic/def.h
@@ -76,17 +76,19 @@
#define NOTIFY_FD_MAX 768
#define NOTIFY_BUFFER_MAX PIPE_BUF
-/* Return a nulstr for a standard cascade of configuration directories,
- * suitable to pass to conf_files_list_nulstr or config_parse_many. */
-#define CONF_DIRS_NULSTR(n) \
- "/etc/" n ".d\0" \
- "/run/" n ".d\0" \
- "/usr/local/lib/" n ".d\0" \
- "/usr/lib/" n ".d\0" \
- CONF_DIR_SPLIT_USR(n)
-
#ifdef HAVE_SPLIT_USR
-#define CONF_DIR_SPLIT_USR(n) "/lib/" n ".d\0"
+#define _CONF_PATHS_SPLIT_USR(n) "/lib/" n "\0"
#else
-#define CONF_DIR_SPLIT_USR(n)
+#define _CONF_PATHS_SPLIT_USR(n)
#endif
+
+/* Return a nulstr for a standard cascade of configuration paths,
+ * suitable to pass to conf_files_list_nulstr() or config_parse_many()
+ * to implement drop-in directories for extending configuration
+ * files. */
+#define CONF_PATHS_NULSTR(n) \
+ "/etc/" n "\0" \
+ "/run/" n "\0" \
+ "/usr/local/lib/" n "\0" \
+ "/usr/lib/" n "\0" \
+ _CONF_PATHS_SPLIT_USR(n)
diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c
index 6721b85c0a..ff6d211ef4 100644
--- a/src/basic/extract-word.c
+++ b/src/basic/extract-word.c
@@ -29,54 +29,51 @@
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
_cleanup_free_ char *s = NULL;
size_t allocated = 0, sz = 0;
+ char c;
int r;
char quote = 0; /* 0 or ' or " */
bool backslash = false; /* whether we've just seen a backslash */
- bool separator = false; /* whether we've just seen a separator */
- bool start = true; /* false means we're looking at a value */
assert(p);
assert(ret);
- if (!separators)
- separators = WHITESPACE;
-
/* Bail early if called after last value or with no input */
if (!*p)
goto finish_force_terminate;
+ c = **p;
+
+ if (!separators)
+ separators = WHITESPACE;
/* Parses the first word of a string, and returns it in
* *ret. Removes all quotes in the process. When parsing fails
* (because of an uneven number of quotes or similar), leaves
* the pointer *p at the first invalid character. */
- for (;;) {
- char c = **p;
-
- if (start) {
- if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
- if (!GREEDY_REALLOC(s, allocated, sz+1))
- return -ENOMEM;
+ if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
+ if (!GREEDY_REALLOC(s, allocated, sz+1))
+ return -ENOMEM;
- if (c == 0)
- goto finish_force_terminate;
- else if (strchr(separators, c)) {
+ for (;; (*p) ++, c = **p) {
+ if (c == 0)
+ goto finish_force_terminate;
+ else if (strchr(separators, c)) {
+ if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
(*p) ++;
- if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
- goto finish_force_next;
- continue;
+ goto finish_force_next;
}
-
+ } else {
/* We found a non-blank character, so we will always
* want to return a string (even if it is empty),
* allocate it here. */
if (!GREEDY_REALLOC(s, allocated, sz+1))
return -ENOMEM;
-
- start = false;
+ break;
}
+ }
+ for (;; (*p) ++, c = **p) {
if (backslash) {
if (!GREEDY_REALLOC(s, allocated, sz+7))
return -ENOMEM;
@@ -107,67 +104,73 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
if (flags & EXTRACT_CUNESCAPE_RELAX) {
s[sz++] = '\\';
s[sz++] = c;
- goto end_escape;
- }
- return -EINVAL;
+ } else
+ return -EINVAL;
+ } else {
+ (*p) += r - 1;
+
+ if (c != 0)
+ s[sz++] = c; /* normal explicit char */
+ else
+ sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
}
-
- (*p) += r - 1;
-
- if (c != 0)
- s[sz++] = c; /* normal explicit char */
- else
- sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
} else
s[sz++] = c;
-end_escape:
backslash = false;
} else if (quote) { /* inside either single or double quotes */
- if (c == 0) {
- if (flags & EXTRACT_RELAX)
- goto finish_force_terminate;
- return -EINVAL;
- } else if (c == quote) /* found the end quote */
- quote = 0;
- else if (c == '\\')
- backslash = true;
- else {
- if (!GREEDY_REALLOC(s, allocated, sz+2))
- return -ENOMEM;
-
- s[sz++] = c;
+ for (;; (*p) ++, c = **p) {
+ if (c == 0) {
+ if (flags & EXTRACT_RELAX)
+ goto finish_force_terminate;
+ return -EINVAL;
+ } else if (c == quote) { /* found the end quote */
+ quote = 0;
+ break;
+ } else if (c == '\\') {
+ backslash = true;
+ break;
+ } else {
+ if (!GREEDY_REALLOC(s, allocated, sz+2))
+ return -ENOMEM;
+
+ s[sz++] = c;
+ }
}
- } else if (separator) {
- if (c == 0)
- goto finish_force_terminate;
- if (!strchr(separators, c))
- goto finish;
-
} else {
- if (c == 0)
- goto finish_force_terminate;
- else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES))
- quote = c;
- else if (c == '\\')
- backslash = true;
- else if (strchr(separators, c)) {
- if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
- (*p) ++;
- goto finish_force_next;
- }
- separator = true;
- } else {
- if (!GREEDY_REALLOC(s, allocated, sz+2))
- return -ENOMEM;
+ for (;; (*p) ++, c = **p) {
+ if (c == 0)
+ goto finish_force_terminate;
+ else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES)) {
+ quote = c;
+ break;
+ } else if (c == '\\') {
+ backslash = true;
+ break;
+ } else if (strchr(separators, c)) {
+ if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
+ (*p) ++;
+ goto finish_force_next;
+ }
+ /* Skip additional coalesced separators. */
+ for (;; (*p) ++, c = **p) {
+ if (c == 0)
+ goto finish_force_terminate;
+ if (!strchr(separators, c))
+ break;
+ }
+ goto finish;
- s[sz++] = c;
+ } else {
+ if (!GREEDY_REALLOC(s, allocated, sz+2))
+ return -ENOMEM;
+
+ s[sz++] = c;
+ }
}
}
-
- (*p) ++;
}
finish_force_terminate:
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
index b6358c459a..151067e916 100644
--- a/src/basic/parse-util.c
+++ b/src/basic/parse-util.c
@@ -67,11 +67,14 @@ int parse_mode(const char *s, mode_t *ret) {
assert(s);
assert(ret);
+ s += strspn(s, WHITESPACE);
+ if (s[0] == '-')
+ return -ERANGE;
+
errno = 0;
l = strtol(s, &x, 8);
if (errno != 0)
return -errno;
-
if (!x || x == s || *x)
return -EINVAL;
if (l < 0 || l > 07777)
@@ -162,15 +165,15 @@ int parse_size(const char *t, uint64_t base, uint64_t *size) {
unsigned i;
p += strspn(p, WHITESPACE);
- if (*p == '-')
- return -ERANGE;
errno = 0;
l = strtoull(p, &e, 10);
- if (errno > 0)
+ if (errno != 0)
return -errno;
if (e == p)
return -EINVAL;
+ if (*p == '-')
+ return -ERANGE;
if (*e == '.') {
e++;
@@ -181,7 +184,7 @@ int parse_size(const char *t, uint64_t base, uint64_t *size) {
char *e2;
l2 = strtoull(e, &e2, 10);
- if (errno > 0)
+ if (errno != 0)
return -errno;
/* Ignore failure. E.g. 10.M is valid */
@@ -307,12 +310,24 @@ int safe_atou(const char *s, unsigned *ret_u) {
assert(s);
assert(ret_u);
- errno = 0;
- l = strtoul(s, &x, 0);
+ /* strtoul() is happy to parse negative values, and silently
+ * converts them to unsigned values without generating an
+ * error. We want a clean error, hence let's look for the "-"
+ * prefix on our own, and generate an error. But let's do so
+ * only after strtoul() validated that the string is clean
+ * otherwise, so that we return EINVAL preferably over
+ * ERANGE. */
- if (!x || x == s || *x || errno)
- return errno > 0 ? -errno : -EINVAL;
+ s += strspn(s, WHITESPACE);
+ errno = 0;
+ l = strtoul(s, &x, 0);
+ if (errno != 0)
+ return -errno;
+ if (!x || x == s || *x)
+ return -EINVAL;
+ if (s[0] == '-')
+ return -ERANGE;
if ((unsigned long) (unsigned) l != l)
return -ERANGE;
@@ -329,10 +344,10 @@ int safe_atoi(const char *s, int *ret_i) {
errno = 0;
l = strtol(s, &x, 0);
-
- if (!x || x == s || *x || errno)
- return errno > 0 ? -errno : -EINVAL;
-
+ if (errno != 0)
+ return -errno;
+ if (!x || x == s || *x)
+ return -EINVAL;
if ((long) (int) l != l)
return -ERANGE;
@@ -347,11 +362,16 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) {
assert(s);
assert(ret_llu);
+ s += strspn(s, WHITESPACE);
+
errno = 0;
l = strtoull(s, &x, 0);
-
- if (!x || x == s || *x || errno)
- return errno ? -errno : -EINVAL;
+ if (errno != 0)
+ return -errno;
+ if (!x || x == s || *x)
+ return -EINVAL;
+ if (*s == '-')
+ return -ERANGE;
*ret_llu = l;
return 0;
@@ -366,9 +386,10 @@ int safe_atolli(const char *s, long long int *ret_lli) {
errno = 0;
l = strtoll(s, &x, 0);
-
- if (!x || x == s || *x || errno)
- return errno ? -errno : -EINVAL;
+ if (errno != 0)
+ return -errno;
+ if (!x || x == s || *x)
+ return -EINVAL;
*ret_lli = l;
return 0;
@@ -381,12 +402,16 @@ int safe_atou8(const char *s, uint8_t *ret) {
assert(s);
assert(ret);
+ s += strspn(s, WHITESPACE);
+
errno = 0;
l = strtoul(s, &x, 0);
-
- if (!x || x == s || *x || errno)
- return errno > 0 ? -errno : -EINVAL;
-
+ if (errno != 0)
+ return -errno;
+ if (!x || x == s || *x)
+ return -EINVAL;
+ if (s[0] == '-')
+ return -ERANGE;
if ((unsigned long) (uint8_t) l != l)
return -ERANGE;
@@ -401,12 +426,16 @@ int safe_atou16(const char *s, uint16_t *ret) {
assert(s);
assert(ret);
+ s += strspn(s, WHITESPACE);
+
errno = 0;
l = strtoul(s, &x, 0);
-
- if (!x || x == s || *x || errno)
- return errno > 0 ? -errno : -EINVAL;
-
+ if (errno != 0)
+ return -errno;
+ if (!x || x == s || *x)
+ return -EINVAL;
+ if (s[0] == '-')
+ return -ERANGE;
if ((unsigned long) (uint16_t) l != l)
return -ERANGE;
@@ -423,10 +452,10 @@ int safe_atoi16(const char *s, int16_t *ret) {
errno = 0;
l = strtol(s, &x, 0);
-
- if (!x || x == s || *x || errno)
- return errno > 0 ? -errno : -EINVAL;
-
+ if (errno != 0)
+ return -errno;
+ if (!x || x == s || *x)
+ return -EINVAL;
if ((long) (int16_t) l != l)
return -ERANGE;
@@ -448,10 +477,13 @@ int safe_atod(const char *s, double *ret_d) {
errno = 0;
d = strtod_l(s, &x, loc);
-
- if (!x || x == s || *x || errno) {
+ if (errno != 0) {
freelocale(loc);
- return errno ? -errno : -EINVAL;
+ return -errno;
+ }
+ if (!x || x == s || *x) {
+ freelocale(loc);
+ return -EINVAL;
}
freelocale(loc);
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
index e629d91cb2..b36fbe4f09 100644
--- a/src/basic/time-util.c
+++ b/src/basic/time-util.c
@@ -705,7 +705,8 @@ finish:
return 0;
}
-int parse_sec(const char *t, usec_t *usec) {
+int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
+
static const struct {
const char *suffix;
usec_t usec;
@@ -737,7 +738,6 @@ int parse_sec(const char *t, usec_t *usec) {
{ "y", USEC_PER_YEAR },
{ "usec", 1ULL },
{ "us", 1ULL },
- { "", USEC_PER_SEC }, /* default is sec */
};
const char *p, *s;
@@ -746,6 +746,7 @@ int parse_sec(const char *t, usec_t *usec) {
assert(t);
assert(usec);
+ assert(default_unit > 0);
p = t;
@@ -764,6 +765,7 @@ int parse_sec(const char *t, usec_t *usec) {
long long l, z = 0;
char *e;
unsigned i, n = 0;
+ usec_t multiplier, k;
p += strspn(p, WHITESPACE);
@@ -806,21 +808,24 @@ int parse_sec(const char *t, usec_t *usec) {
for (i = 0; i < ELEMENTSOF(table); i++)
if (startswith(e, table[i].suffix)) {
- usec_t k = (usec_t) z * table[i].usec;
-
- for (; n > 0; n--)
- k /= 10;
-
- r += (usec_t) l * table[i].usec + k;
+ multiplier = table[i].usec;
p = e + strlen(table[i].suffix);
-
- something = true;
break;
}
- if (i >= ELEMENTSOF(table))
- return -EINVAL;
+ if (i >= ELEMENTSOF(table)) {
+ multiplier = default_unit;
+ p = e;
+ }
+
+ something = true;
+
+ k = (usec_t) z * multiplier;
+ for (; n > 0; n--)
+ k /= 10;
+
+ r += (usec_t) l * multiplier + k;
}
*usec = r;
@@ -828,6 +833,10 @@ int parse_sec(const char *t, usec_t *usec) {
return 0;
}
+int parse_sec(const char *t, usec_t *usec) {
+ return parse_time(t, usec, USEC_PER_SEC);
+}
+
int parse_nsec(const char *t, nsec_t *nsec) {
static const struct {
const char *suffix;
diff --git a/src/basic/time-util.h b/src/basic/time-util.h
index 925bf18eb2..0417c29cdd 100644
--- a/src/basic/time-util.h
+++ b/src/basic/time-util.h
@@ -104,6 +104,7 @@ int dual_timestamp_deserialize(const char *value, dual_timestamp *t);
int parse_timestamp(const char *t, usec_t *usec);
int parse_sec(const char *t, usec_t *usec);
+int parse_time(const char *t, usec_t *usec, usec_t default_unit);
int parse_nsec(const char *t, nsec_t *nsec);
bool ntp_synced(void);
diff --git a/src/basic/virt.c b/src/basic/virt.c
index ff006e96c6..d088b7a804 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -400,7 +400,7 @@ int detect_container(void) {
goto finish;
}
- r = VIRTUALIZATION_NONE;
+ r = VIRTUALIZATION_CONTAINER_OTHER;
finish:
cached_found = r;