util-lib: unify parsing of nice level values

This adds parse_nice() that parses a nice level and ensures it is in the right
range, via a new nice_is_valid() helper. It then ports over a number of users
to this.

No functional changes.
This commit is contained in:
Lennart Poettering 2016-08-05 11:17:08 +02:00
parent 1ed1f50f82
commit 41bf0590cc
8 changed files with 78 additions and 30 deletions

View file

@ -29,6 +29,7 @@
#include "extract-word.h"
#include "macro.h"
#include "parse-util.h"
#include "process-util.h"
#include "string-util.h"
int parse_boolean(const char *v) {
@ -551,10 +552,25 @@ int parse_percent_unbounded(const char *p) {
}
int parse_percent(const char *p) {
int v = parse_percent_unbounded(p);
int v;
v = parse_percent_unbounded(p);
if (v > 100)
return -ERANGE;
return v;
}
int parse_nice(const char *p, int *ret) {
int n, r;
r = safe_atoi(p, &n);
if (r < 0)
return r;
if (!nice_is_valid(n))
return -ERANGE;
*ret = n;
return 0;
}

View file

@ -108,3 +108,5 @@ int parse_fractional_part_u(const char **s, size_t digits, unsigned *res);
int parse_percent_unbounded(const char *p);
int parse_percent(const char *p);
int parse_nice(const char *p, int *ret);

View file

@ -26,6 +26,7 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/resource.h>
#include "formats-util.h"
#include "macro.h"
@ -103,3 +104,7 @@ int sched_policy_from_string(const char *s);
void valgrind_summary_hack(void);
int pid_compare_func(const void *a, const void *b);
static inline bool nice_is_valid(int n) {
return n >= PRIO_MIN && n < PRIO_MAX;
}

View file

@ -935,7 +935,7 @@ int bus_exec_context_set_transient_property(
if (r < 0)
return r;
if (n < PRIO_MIN || n >= PRIO_MAX)
if (!nice_is_valid(n))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
if (mode != UNIT_CHECK) {

View file

@ -491,16 +491,17 @@ int config_parse_socket_bind(const char *unit,
return 0;
}
int config_parse_exec_nice(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_exec_nice(
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) {
ExecContext *c = data;
int priority, r;
@ -510,14 +511,13 @@ int config_parse_exec_nice(const char *unit,
assert(rvalue);
assert(data);
r = safe_atoi(rvalue, &priority);
r = parse_nice(rvalue, &priority);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse nice priority, ignoring: %s", rvalue);
return 0;
}
if (r == -ERANGE)
log_syntax(unit, LOG_ERR, filename, line, r, "Nice priority out of range, ignoring: %s", rvalue);
else
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse nice priority, ignoring: %s", rvalue);
if (priority < PRIO_MIN || priority >= PRIO_MAX) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Nice priority out of range, ignoring: %s", rvalue);
return 0;
}

View file

@ -257,11 +257,9 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_NICE:
r = safe_atoi(optarg, &arg_nice);
if (r < 0 || arg_nice < PRIO_MIN || arg_nice >= PRIO_MAX) {
log_error("Failed to parse nice value");
return -EINVAL;
}
r = parse_nice(optarg, &arg_nice);
if (r < 0)
return log_error_errno(r, "Failed to parse nice value: %s", optarg);
arg_nice_set = true;
break;

View file

@ -366,15 +366,13 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
}
} else if (streq(field, "Nice")) {
int32_t i;
int n;
r = safe_atoi32(eq, &i);
if (r < 0) {
log_error("Failed to parse %s value %s.", field, eq);
return -EINVAL;
}
r = parse_nice(eq, &n);
if (r < 0)
return log_error_errno(r, "Failed to parse nice value: %s", eq);
r = sd_bus_message_append(m, "v", "i", i);
r = sd_bus_message_append(m, "v", "i", (int32_t) n);
} else if (STR_IN_SET(field, "Environment", "PassEnvironment")) {
const char *p;

View file

@ -498,6 +498,34 @@ static void test_parse_percent_unbounded(void) {
assert_se(parse_percent_unbounded("400%") == 400);
}
static void test_parse_nice(void) {
int n;
assert_se(parse_nice("0", &n) >= 0 && n == 0);
assert_se(parse_nice("+0", &n) >= 0 && n == 0);
assert_se(parse_nice("-1", &n) >= 0 && n == -1);
assert_se(parse_nice("-2", &n) >= 0 && n == -2);
assert_se(parse_nice("1", &n) >= 0 && n == 1);
assert_se(parse_nice("2", &n) >= 0 && n == 2);
assert_se(parse_nice("+1", &n) >= 0 && n == 1);
assert_se(parse_nice("+2", &n) >= 0 && n == 2);
assert_se(parse_nice("-20", &n) >= 0 && n == -20);
assert_se(parse_nice("19", &n) >= 0 && n == 19);
assert_se(parse_nice("+19", &n) >= 0 && n == 19);
assert_se(parse_nice("", &n) == -EINVAL);
assert_se(parse_nice("-", &n) == -EINVAL);
assert_se(parse_nice("+", &n) == -EINVAL);
assert_se(parse_nice("xx", &n) == -EINVAL);
assert_se(parse_nice("-50", &n) == -ERANGE);
assert_se(parse_nice("50", &n) == -ERANGE);
assert_se(parse_nice("+50", &n) == -ERANGE);
assert_se(parse_nice("-21", &n) == -ERANGE);
assert_se(parse_nice("20", &n) == -ERANGE);
assert_se(parse_nice("+20", &n) == -ERANGE);
}
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
@ -513,6 +541,7 @@ int main(int argc, char *argv[]) {
test_safe_atod();
test_parse_percent();
test_parse_percent_unbounded();
test_parse_nice();
return 0;
}