From 9eaebafed6dec1c3b5d1307b37f1b03a19530527 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Jun 2016 19:25:38 +0200 Subject: [PATCH] util-lib: introduce parse_percent() for parsing percent specifications And port a couple of users over to it. --- src/basic/parse-util.c | 19 +++++++++++++++++++ src/basic/parse-util.h | 2 ++ src/login/logind-user.c | 29 ++++++++--------------------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index d0208e93f..90bae7149 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -536,3 +536,22 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) { return 0; } + +int parse_percent(const char *p) { + const char *pc, *n; + unsigned v; + int r; + + pc = endswith(p, "%"); + if (!pc) + return -EINVAL; + + n = strndupa(p, pc - p); + r = safe_atou(n, &v); + if (r < 0) + return r; + if (v > 100) + return -ERANGE; + + return (int) v; +} diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h index 250f887f4..1f420c050 100644 --- a/src/basic/parse-util.h +++ b/src/basic/parse-util.h @@ -107,3 +107,5 @@ static inline int safe_atozu(const char *s, size_t *ret_u) { int safe_atod(const char *s, double *ret_d); int parse_fractional_part_u(const char **s, size_t digits, unsigned *res); + +int parse_percent(const char *p); diff --git a/src/login/logind-user.c b/src/login/logind-user.c index a89d1bef7..7ffad3ac9 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -886,7 +886,6 @@ int config_parse_tmpfs_size( void *userdata) { size_t *sz = data; - const char *e; int r; assert(filename); @@ -894,29 +893,17 @@ int config_parse_tmpfs_size( assert(rvalue); assert(data); - e = endswith(rvalue, "%"); - if (e) { - unsigned long ul; - char *f; - - errno = 0; - ul = strtoul(rvalue, &f, 10); - if (errno > 0 || f != e) { - log_syntax(unit, LOG_ERR, filename, line, errno, "Failed to parse percentage value, ignoring: %s", rvalue); - return 0; - } - - if (ul <= 0 || ul >= 100) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Percentage value out of range, ignoring: %s", rvalue); - return 0; - } - - *sz = PAGE_ALIGN((size_t) ((physical_memory() * (uint64_t) ul) / (uint64_t) 100)); - } else { + /* First, try to parse as percentage */ + r = parse_percent(rvalue); + if (r > 0 && r < 100) + *sz = PAGE_ALIGN((size_t) ((physical_memory() * (uint64_t) r) / 100U)); + else { uint64_t k; + /* If the passed argument was not a percentage, or out of range, parse as byte size */ + r = parse_size(rvalue, 1024, &k); - if (r < 0 || (uint64_t) (size_t) k != k) { + if (r < 0 || k <= 0 || (uint64_t) (size_t) k != k) { log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value, ignoring: %s", rvalue); return 0; } -- 2.30.2