diff options
Diffstat (limited to 'src/core/load-fragment.c')
-rw-r--r-- | src/core/load-fragment.c | 736 |
1 files changed, 415 insertions, 321 deletions
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index a13f42b5e0..7f12f26b08 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -20,44 +20,52 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <linux/oom.h> #include <errno.h> -#include <string.h> #include <fcntl.h> -#include <sched.h> #include <linux/fs.h> -#include <sys/stat.h> -#include <sys/resource.h> - +#include <linux/oom.h> #ifdef HAVE_SECCOMP #include <seccomp.h> #endif +#include <sched.h> +#include <string.h> +#include <sys/resource.h> +#include <sys/stat.h> -#include "unit.h" -#include "strv.h" +#include "alloc-util.h" +#include "af-list.h" +#include "bus-error.h" +#include "bus-internal.h" +#include "bus-util.h" +#include "cap-list.h" +#include "cgroup.h" #include "conf-parser.h" +#include "cpu-set-util.h" +#include "env-util.h" +#include "errno-list.h" +#include "escape.h" +#include "fd-util.h" +#include "fs-util.h" +#include "ioprio.h" #include "load-fragment.h" #include "log.h" -#include "ioprio.h" -#include "securebits.h" #include "missing.h" -#include "unit-name.h" -#include "unit-printf.h" -#include "utf8.h" +#include "parse-util.h" #include "path-util.h" -#include "env-util.h" -#include "cgroup.h" -#include "bus-util.h" -#include "bus-error.h" -#include "errno-list.h" -#include "af-list.h" -#include "cap-list.h" -#include "signal-util.h" -#include "bus-internal.h" - +#include "process-util.h" #ifdef HAVE_SECCOMP #include "seccomp-util.h" #endif +#include "securebits.h" +#include "signal-util.h" +#include "stat-util.h" +#include "string-util.h" +#include "strv.h" +#include "unit-name.h" +#include "unit-printf.h" +#include "unit.h" +#include "utf8.h" +#include "web-util.h" int config_parse_warn_compat( const char *unit, @@ -74,15 +82,15 @@ int config_parse_warn_compat( switch(reason) { case DISABLED_CONFIGURATION: - log_syntax(unit, LOG_DEBUG, filename, line, EINVAL, + log_syntax(unit, LOG_DEBUG, filename, line, 0, "Support for option %s= has been disabled at compile time and it is ignored", lvalue); break; case DISABLED_LEGACY: - log_syntax(unit, LOG_INFO, filename, line, EINVAL, + log_syntax(unit, LOG_INFO, filename, line, 0, "Support for option %s= has been removed and it is ignored", lvalue); break; case DISABLED_EXPERIMENTAL: - log_syntax(unit, LOG_INFO, filename, line, EINVAL, + log_syntax(unit, LOG_INFO, filename, line, 0, "Support for option %s= has not yet been enabled and it is ignored", lvalue); break; }; @@ -120,18 +128,16 @@ int config_parse_unit_deps(const char *unit, r = unit_name_printf(u, t, &k); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve specifiers, ignoring: %s", strerror(-r)); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m"); continue; } r = unit_add_dependency_by_name(u, d, k, NULL, true); if (r < 0) - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to add dependency on %s, ignoring: %s", k, strerror(-r)); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add dependency on %s, ignoring: %m", k); } if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid syntax, ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, ignoring."); return 0; } @@ -166,16 +172,17 @@ int config_parse_unit_string_printf( return config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, k, data, userdata); } -int config_parse_unit_strv_printf(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_unit_strv_printf( + 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) { Unit *u = userdata; _cleanup_free_ char *k = NULL; @@ -187,24 +194,25 @@ int config_parse_unit_strv_printf(const char *unit, assert(u); r = unit_full_printf(u, rvalue, &k); - if (r < 0) - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", rvalue); + return 0; + } - return config_parse_strv(unit, filename, line, section, section_line, lvalue, ltype, - k ? k : rvalue, data, userdata); + return config_parse_strv(unit, filename, line, section, section_line, lvalue, ltype, k, data, userdata); } -int config_parse_unit_path_printf(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_unit_path_printf( + 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) { _cleanup_free_ char *k = NULL; Unit *u = userdata; @@ -217,7 +225,7 @@ int config_parse_unit_path_printf(const char *unit, r = unit_full_printf(u, rvalue, &k); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", rvalue); return 0; } @@ -256,17 +264,17 @@ int config_parse_unit_path_strv_printf( r = unit_full_printf(u, t, &k); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve unit specifiers on %s, ignoring: %s", t, strerror(-r)); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", t); return 0; } if (!utf8_is_valid(k)) { - log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue); + log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue); return 0; } if (!path_is_absolute(k)) { - log_syntax(unit, LOG_ERR, filename, line, -r, "Symlink path %s is not absolute, ignoring: %s", k, strerror(-r)); + log_syntax(unit, LOG_ERR, filename, line, 0, "Symlink path %s is not absolute, ignoring: %m", k); return 0; } @@ -279,7 +287,7 @@ int config_parse_unit_path_strv_printf( k = NULL; } if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid syntax, ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, ignoring."); return 0; } @@ -322,12 +330,8 @@ int config_parse_socket_listen(const char *unit, p->type = ltype; r = unit_full_printf(UNIT(s), rvalue, &p->path); if (r < 0) { - p->path = strdup(rvalue); - if (!p->path) - return log_oom(); - else - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", rvalue); + return 0; } path_kill_slashes(p->path); @@ -337,14 +341,14 @@ int config_parse_socket_listen(const char *unit, p->type = SOCKET_SOCKET; r = unit_full_printf(UNIT(s), rvalue, &k); - if (r < 0) - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", rvalue); + return 0; + } - r = socket_address_parse_netlink(&p->address, k ?: rvalue); + r = socket_address_parse_netlink(&p->address, k); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to parse address value, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address value, ignoring: %s", rvalue); return 0; } @@ -353,14 +357,14 @@ int config_parse_socket_listen(const char *unit, p->type = SOCKET_SOCKET; r = unit_full_printf(UNIT(s), rvalue, &k); - if (r < 0) - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r,"Failed to resolve unit specifiers on %s, ignoring: %m", rvalue); + return 0; + } - r = socket_address_parse_and_warn(&p->address, k ? k : rvalue); + r = socket_address_parse_and_warn(&p->address, k); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to parse address value, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address value, ignoring: %s", rvalue); return 0; } @@ -374,8 +378,7 @@ int config_parse_socket_listen(const char *unit, } if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) { - log_syntax(unit, LOG_ERR, filename, line, EOPNOTSUPP, - "Address family not supported, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Address family not supported, ignoring: %s", rvalue); return 0; } } @@ -422,8 +425,7 @@ int config_parse_socket_bind(const char *unit, r = parse_boolean(rvalue); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse bind IPv6 only value, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse bind IPv6 only value, ignoring: %s", rvalue); return 0; } @@ -455,14 +457,12 @@ int config_parse_exec_nice(const char *unit, r = safe_atoi(rvalue, &priority); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to parse nice priority, ignoring: %s. ", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse nice priority, ignoring: %s", rvalue); return 0; } if (priority < PRIO_MIN || priority >= PRIO_MAX) { - log_syntax(unit, LOG_ERR, filename, line, ERANGE, - "Nice priority out of range, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Nice priority out of range, ignoring: %s", rvalue); return 0; } @@ -493,14 +493,12 @@ int config_parse_exec_oom_score_adjust(const char* unit, r = safe_atoi(rvalue, &oa); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to parse the OOM score adjust value, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse the OOM score adjust value, ignoring: %s", rvalue); return 0; } if (oa < OOM_SCORE_ADJ_MIN || oa > OOM_SCORE_ADJ_MAX) { - log_syntax(unit, LOG_ERR, filename, line, ERANGE, - "OOM score adjust value out of range, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "OOM score adjust value out of range, ignoring: %s", rvalue); return 0; } @@ -533,9 +531,7 @@ int config_parse_exec( assert(e); e += ltype; - rvalue += strspn(rvalue, WHITESPACE); - p = rvalue; if (isempty(rvalue)) { /* An empty assignment resets the list */ @@ -543,14 +539,15 @@ int config_parse_exec( return 0; } + p = rvalue; do { - int i; + _cleanup_free_ char *path = NULL, *firstword = NULL; + bool separate_argv0 = false, ignore = false; + _cleanup_free_ ExecCommand *nce = NULL; _cleanup_strv_free_ char **n = NULL; size_t nlen = 0, nbufsize = 0; - _cleanup_free_ ExecCommand *nce = NULL; - _cleanup_free_ char *path = NULL, *firstword = NULL; char *f; - bool separate_argv0 = false, ignore = false; + int i; semicolon = false; @@ -574,24 +571,19 @@ int config_parse_exec( if (isempty(f)) { /* First word is either "-" or "@" with no command. */ - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Empty path in command line, ignoring: \"%s\"", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Empty path in command line, ignoring: \"%s\"", rvalue); return 0; } - if (!string_is_safe(f)) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Executable path contains special characters, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path contains special characters, ignoring: %s", rvalue); return 0; } if (!path_is_absolute(f)) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Executable path is not absolute, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path is not absolute, ignoring: %s", rvalue); return 0; } if (endswith(f, "/")) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Executable path specifies a directory, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path specifies a directory, ignoring: %s", rvalue); return 0; } @@ -658,8 +650,7 @@ int config_parse_exec( } if (!n || !n[0]) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Empty executable name or zeroeth argument, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Empty executable name or zeroeth argument, ignoring: %s", rvalue); return 0; } @@ -743,8 +734,7 @@ int config_parse_exec_io_class(const char *unit, x = ioprio_class_from_string(rvalue); if (x < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse IO scheduling class, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IO scheduling class, ignoring: %s", rvalue); return 0; } @@ -775,8 +765,7 @@ int config_parse_exec_io_priority(const char *unit, r = safe_atoi(rvalue, &i); if (r < 0 || i < 0 || i >= IOPRIO_BE_NR) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to parse IO priority, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse IO priority, ignoring: %s", rvalue); return 0; } @@ -808,8 +797,7 @@ int config_parse_exec_cpu_sched_policy(const char *unit, x = sched_policy_from_string(rvalue); if (x < 0) { - log_syntax(unit, LOG_ERR, filename, line, -x, - "Failed to parse CPU scheduling policy, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse CPU scheduling policy, ignoring: %s", rvalue); return 0; } @@ -842,8 +830,7 @@ int config_parse_exec_cpu_sched_prio(const char *unit, r = safe_atoi(rvalue, &i); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to parse CPU scheduling policy, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU scheduling policy, ignoring: %s", rvalue); return 0; } @@ -852,8 +839,7 @@ int config_parse_exec_cpu_sched_prio(const char *unit, max = sched_get_priority_max(c->cpu_sched_policy); if (i < min || i > max) { - log_syntax(unit, LOG_ERR, filename, line, ERANGE, - "CPU scheduling priority is out of range, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "CPU scheduling priority is out of range, ignoring: %s", rvalue); return 0; } @@ -883,8 +869,7 @@ int config_parse_exec_cpu_affinity(const char *unit, assert(rvalue); assert(data); - ncpus = parse_cpu_set(rvalue, &cpuset, unit, filename, line, lvalue); - + ncpus = parse_cpu_set_and_warn(rvalue, &cpuset, unit, filename, line, lvalue); if (ncpus < 0) return ncpus; @@ -924,8 +909,7 @@ int config_parse_exec_capabilities(const char *unit, cap = cap_from_text(rvalue); if (!cap) { - log_syntax(unit, LOG_ERR, filename, line, errno, - "Failed to parse capabilities, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, errno, "Failed to parse capabilities, ignoring: %s", rvalue); return 0; } @@ -976,14 +960,12 @@ int config_parse_exec_secure_bits(const char *unit, else if (first_word(word, "noroot-locked")) c->secure_bits |= 1<<SECURE_NOROOT_LOCKED; else { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse secure bits, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse secure bits, ignoring: %s", rvalue); return 0; } } if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid syntax, garbage at the end, ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, garbage at the end, ignoring."); return 0; } @@ -1000,10 +982,11 @@ int config_parse_bounding_set(const char *unit, void *userdata) { uint64_t *capability_bounding_set_drop = data; - const char *word, *state; - size_t l; + uint64_t capability_bounding_set; bool invert = false; uint64_t sum = 0; + const char *prev; + const char *cur; assert(filename); assert(lvalue); @@ -1020,30 +1003,38 @@ int config_parse_bounding_set(const char *unit, * non-inverted everywhere to have a fully normalized * interface. */ - FOREACH_WORD_QUOTED(word, l, rvalue, state) { - _cleanup_free_ char *t = NULL; + prev = cur = rvalue; + for (;;) { + _cleanup_free_ char *word = NULL; int cap; + int r; - t = strndup(word, l); - if (!t) + r = extract_first_word(&cur, &word, NULL, EXTRACT_QUOTES); + if (r == 0) + break; + if (r == -ENOMEM) return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Trailing garbage in bounding set, ignoring: %s", prev); + break; + } - cap = capability_from_name(t); + cap = capability_from_name(word); if (cap < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Failed to parse capability in bounding set, ignoring: %s", t); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse capability in bounding set, ignoring: %s", word); + prev = cur; continue; } sum |= ((uint64_t) 1ULL) << (uint64_t) cap; + prev = cur; } - if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Trailing garbage, ignoring."); - if (invert) - *capability_bounding_set_drop |= sum; + capability_bounding_set = invert ? ~sum : sum; + if (*capability_bounding_set_drop && capability_bounding_set) + *capability_bounding_set_drop = ~(~*capability_bounding_set_drop | capability_bounding_set); else - *capability_bounding_set_drop |= ~sum; + *capability_bounding_set_drop = ~capability_bounding_set; return 0; } @@ -1076,8 +1067,7 @@ int config_parse_limit(const char *unit, r = safe_atollu(rvalue, &u); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to parse resource value, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue); return 0; } } @@ -1092,6 +1082,49 @@ int config_parse_limit(const char *unit, return 0; } +int config_parse_bytes_limit(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) { + + struct rlimit **rl = data; + uint64_t bytes; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + rl += ltype; + + if (streq(rvalue, "infinity")) + bytes = (uint64_t) RLIM_INFINITY; + else { + int r; + + r = parse_size(rvalue, 1024, &bytes); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue); + return 0; + } + } + + if (!*rl) { + *rl = new(struct rlimit, 1); + if (!*rl) + return log_oom(); + } + + (*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) bytes; + return 0; +} + #ifdef HAVE_SYSV_COMPAT int config_parse_sysv_priority(const char *unit, const char *filename, @@ -1114,8 +1147,7 @@ int config_parse_sysv_priority(const char *unit, r = safe_atoi(rvalue, &i); if (r < 0 || i < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to parse SysV start priority, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse SysV start priority, ignoring: %s", rvalue); return 0; } @@ -1162,12 +1194,12 @@ int config_parse_exec_mount_flags(const char *unit, else if (streq(t, "private")) flags = MS_PRIVATE; else { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Failed to parse mount flag %s, ignoring: %s", t, rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse mount flag %s, ignoring: %s", t, rvalue); return 0; } } if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Trailing garbage, ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring."); c->mount_flags = flags; return 0; @@ -1210,8 +1242,7 @@ int config_parse_exec_selinux_context( r = unit_name_printf(u, rvalue, &k); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve specifiers, ignoring: %s", strerror(-r)); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m"); return 0; } @@ -1259,8 +1290,7 @@ int config_parse_exec_apparmor_profile( r = unit_name_printf(u, rvalue, &k); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve specifiers, ignoring: %s", strerror(-r)); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m"); return 0; } @@ -1308,8 +1338,7 @@ int config_parse_exec_smack_process_label( r = unit_name_printf(u, rvalue, &k); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve specifiers, ignoring: %s", strerror(-r)); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m"); return 0; } @@ -1350,23 +1379,18 @@ int config_parse_timer(const char *unit, b = timer_base_from_string(lvalue); if (b < 0) { - log_syntax(unit, LOG_ERR, filename, line, -b, - "Failed to parse timer base, ignoring: %s", lvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse timer base, ignoring: %s", lvalue); return 0; } if (b == TIMER_CALENDAR) { if (calendar_spec_from_string(rvalue, &c) < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse calendar specification, ignoring: %s", - rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse calendar specification, ignoring: %s", rvalue); return 0; } } else { if (parse_sec(rvalue, &u) < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse timer value, ignoring: %s", - rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse timer value, ignoring: %s", rvalue); return 0; } } @@ -1409,33 +1433,30 @@ int config_parse_trigger_unit( assert(data); if (!set_isempty(u->dependencies[UNIT_TRIGGERS])) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Multiple units to trigger specified, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Multiple units to trigger specified, ignoring: %s", rvalue); return 0; } r = unit_name_printf(u, rvalue, &p); - if (r < 0) - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve specifiers, ignoring: %s", strerror(-r)); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m"); + return 0; + } - type = unit_name_to_type(p ?: rvalue); + type = unit_name_to_type(p); if (type < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Unit type not valid, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Unit type not valid, ignoring: %s", rvalue); return 0; } if (type == u->type) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Trigger cannot be of same type, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Trigger cannot be of same type, ignoring: %s", rvalue); return 0; } - r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_TRIGGERS, p ?: rvalue, NULL, true); + r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_TRIGGERS, p, NULL, true); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to add trigger on %s, ignoring: %s", p ?: rvalue, strerror(-r)); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add trigger on %s, ignoring: %m", p); return 0; } @@ -1472,25 +1493,18 @@ int config_parse_path_spec(const char *unit, b = path_type_from_string(lvalue); if (b < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse path type, ignoring: %s", lvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse path type, ignoring: %s", lvalue); return 0; } r = unit_full_printf(UNIT(p), rvalue, &k); if (r < 0) { - k = strdup(rvalue); - if (!k) - return log_oom(); - else - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve unit specifiers on %s. Ignoring.", - rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + return 0; } if (!path_is_absolute(k)) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Path is not absolute, ignoring: %s", k); + log_syntax(unit, LOG_ERR, filename, line, 0, "Path is not absolute, ignoring: %s", k); return 0; } @@ -1522,10 +1536,10 @@ int config_parse_socket_service( void *userdata) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_free_ char *p = NULL; Socket *s = data; - int r; Unit *x; - _cleanup_free_ char *p = NULL; + int r; assert(filename); assert(lvalue); @@ -1539,13 +1553,13 @@ int config_parse_socket_service( } if (!endswith(p, ".service")) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Unit must be of type service, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Unit must be of type service, ignoring: %s", rvalue); return 0; } r = manager_load_unit(UNIT(s)->manager, p, NULL, &error, &x); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r)); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r)); return 0; } @@ -1554,6 +1568,50 @@ int config_parse_socket_service( return 0; } +int config_parse_fdname( + 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) { + + _cleanup_free_ char *p = NULL; + Socket *s = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (isempty(rvalue)) { + s->fdname = mfree(s->fdname); + return 0; + } + + r = unit_name_printf(UNIT(s), rvalue, &p); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue); + return 0; + } + + if (!fdname_is_valid(p)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid file descriptor name, ignoring: %s", p); + return 0; + } + + free(s->fdname); + s->fdname = p; + p = NULL; + + return 0; +} + int config_parse_service_sockets( const char *unit, const char *filename, @@ -1567,8 +1625,7 @@ int config_parse_service_sockets( void *userdata) { Service *s = data; - const char *word, *state; - size_t l; + const char *p; int r; assert(filename); @@ -1576,21 +1633,28 @@ int config_parse_service_sockets( assert(rvalue); assert(data); - FOREACH_WORD_QUOTED(word, l, rvalue, state) { - _cleanup_free_ char *t = NULL, *k = NULL; + p = rvalue; + for(;;) { + _cleanup_free_ char *word = NULL, *k = NULL; - t = strndup(word, l); - if (!t) + r = extract_first_word(&p, &word, NULL, 0); + if (r == 0) + break; + if (r == -ENOMEM) return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Trailing garbage in sockets, ignoring: %s", rvalue); + break; + } - r = unit_name_printf(UNIT(s), t, &k); + r = unit_name_printf(UNIT(s), word, &k); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m"); continue; } if (!endswith(k, ".socket")) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Unit must be of type socket, ignoring: %s", k); + log_syntax(unit, LOG_ERR, filename, line, 0, "Unit must be of type socket, ignoring: %s", k); continue; } @@ -1602,8 +1666,6 @@ int config_parse_service_sockets( if (r < 0) log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add dependency on %s, ignoring: %m", k); } - if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Trailing garbage, ignoring."); return 0; } @@ -1636,7 +1698,7 @@ int config_parse_bus_name( } if (!service_name_is_valid(k)) { - log_syntax(unit, LOG_ERR, filename, line, r, "Invalid bus name %s, ignoring.", k); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid bus name %s, ignoring.", k); return 0; } @@ -1701,21 +1763,18 @@ int config_parse_busname_service( r = unit_name_printf(UNIT(n), rvalue, &p); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve specifiers, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue); return 0; } if (!endswith(p, ".service")) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Unit must be of type service, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Unit must be of type service, ignoring: %s", rvalue); return 0; } r = manager_load_unit(UNIT(n)->manager, p, NULL, &error, &x); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r)); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r)); return 0; } @@ -1765,8 +1824,7 @@ int config_parse_bus_policy( access_str = strpbrk(id_str, WHITESPACE); if (!access_str) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid busname policy value '%s'", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid busname policy value '%s'", rvalue); return 0; } @@ -1776,8 +1834,7 @@ int config_parse_bus_policy( p->access = bus_policy_access_from_string(access_str); if (p->access < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid busname policy access type '%s'", access_str); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid busname policy access type '%s'", access_str); return 0; } @@ -1819,8 +1876,7 @@ int config_parse_bus_endpoint_policy( access_str = strpbrk(name, WHITESPACE); if (!access_str) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid endpoint policy value '%s'", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid endpoint policy value '%s'", rvalue); return 0; } @@ -1831,21 +1887,83 @@ int config_parse_bus_endpoint_policy( access = bus_policy_access_from_string(access_str); if (access <= _BUS_POLICY_ACCESS_INVALID || access >= _BUS_POLICY_ACCESS_MAX) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid endpoint policy access type '%s'", access_str); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid endpoint policy access type '%s'", access_str); return 0; } if (!c->bus_endpoint) { r = bus_endpoint_new(&c->bus_endpoint); - if (r < 0) - return r; + return log_error_errno(r, "Failed to create bus endpoint object: %m"); } return bus_endpoint_add_policy(c->bus_endpoint, name, access); } +int config_parse_working_directory( + 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; + Unit *u = userdata; + bool missing_ok; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(c); + assert(u); + + if (rvalue[0] == '-') { + missing_ok = true; + rvalue++; + } else + missing_ok = false; + + if (streq(rvalue, "~")) { + c->working_directory_home = true; + c->working_directory = mfree(c->working_directory); + } else { + _cleanup_free_ char *k = NULL; + + r = unit_full_printf(u, rvalue, &k); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in working directory path '%s', ignoring: %m", rvalue); + return 0; + } + + path_kill_slashes(k); + + if (!utf8_is_valid(k)) { + log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue); + return 0; + } + + if (!path_is_absolute(k)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Working directory path '%s' is not absolute, ignoring.", rvalue); + return 0; + } + + free(c->working_directory); + c->working_directory = k; + k = NULL; + + c->working_directory_home = false; + } + + c->working_directory_missing_ok = missing_ok; + return 0; +} + int config_parse_unit_env_file(const char *unit, const char *filename, unsigned line, @@ -1860,7 +1978,6 @@ int config_parse_unit_env_file(const char *unit, char ***env = data; Unit *u = userdata; _cleanup_free_ char *n = NULL; - const char *s; int r; assert(filename); @@ -1875,18 +1992,17 @@ int config_parse_unit_env_file(const char *unit, } r = unit_full_printf(u, rvalue, &n); - if (r < 0) - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve specifiers, ignoring: %s", rvalue); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue); + return 0; + } - s = n ?: rvalue; - if (!path_is_absolute(s[0] == '-' ? s + 1 : s)) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Path '%s' is not absolute, ignoring.", s); + if (!path_is_absolute(n[0] == '-' ? n + 1 : n)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Path '%s' is not absolute, ignoring.", n); return 0; } - r = strv_extend(env, s); + r = strv_extend(env, n); if (r < 0) return log_oom(); @@ -1924,14 +2040,17 @@ int config_parse_environ(const char *unit, if (u) { r = unit_full_printf(u, rvalue, &k); - if (r < 0) - log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve specifiers, ignoring: %s", rvalue); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue); + return 0; + } } - if (!k) + if (!k) { k = strdup(rvalue); - if (!k) - return log_oom(); + if (!k) + return log_oom(); + } FOREACH_WORD_QUOTED(word, l, k, state) { _cleanup_free_ char *n = NULL; @@ -1944,7 +2063,7 @@ int config_parse_environ(const char *unit, } if (!env_assignment_is_valid(n)) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid environment assignment, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid environment assignment, ignoring: %s", rvalue); continue; } @@ -1956,8 +2075,7 @@ int config_parse_environ(const char *unit, *env = x; } if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Trailing garbage, ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring."); return 0; } @@ -1982,8 +2100,7 @@ int config_parse_ip_tos(const char *unit, x = ip_tos_from_string(rvalue); if (x < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse IP TOS value, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IP TOS value, ignoring: %s", rvalue); return 0; } @@ -2031,12 +2148,12 @@ int config_parse_unit_condition_path( r = unit_full_printf(u, rvalue, &p); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve specifiers, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue); return 0; } if (!path_is_absolute(p)) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Path in condition not absolute, ignoring: %s", p); + log_syntax(unit, LOG_ERR, filename, line, 0, "Path in condition not absolute, ignoring: %s", p); return 0; } @@ -2088,7 +2205,7 @@ int config_parse_unit_condition_string( r = unit_full_printf(u, rvalue, &s); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve specifiers, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue); return 0; } @@ -2137,7 +2254,7 @@ int config_parse_unit_condition_null( b = parse_boolean(rvalue); if (b < 0) { - log_syntax(unit, LOG_ERR, filename, line, -b, "Failed to parse boolean value in condition, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, b, "Failed to parse boolean value in condition, ignoring: %s", rvalue); return 0; } @@ -2185,20 +2302,18 @@ int config_parse_unit_requires_mounts_for( return log_oom(); if (!utf8_is_valid(n)) { - log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue); + log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue); continue; } r = unit_require_mounts_for(u, n); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to add required mount for, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add required mount for, ignoring: %s", rvalue); continue; } } if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Trailing garbage, ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring."); return 0; } @@ -2239,8 +2354,7 @@ int config_parse_documentation(const char *unit, if (documentation_url_is_valid(*a)) *(b++) = *a; else { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid URL, ignoring: %s", *a); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid URL, ignoring: %s", *a); free(*a); } } @@ -2335,8 +2449,7 @@ int config_parse_syscall_filter( id = seccomp_syscall_resolve_name(t); if (id < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse system call, ignoring: %s", t); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse system call, ignoring: %s", t); continue; } @@ -2353,8 +2466,7 @@ int config_parse_syscall_filter( set_remove(c->syscall_filter, INT_TO_PTR(id + 1)); } if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Trailing garbage, ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring."); /* Turn on NNP, but only if it wasn't configured explicitly * before, and only if we are in user mode. */ @@ -2400,8 +2512,7 @@ int config_parse_syscall_archs( r = seccomp_arch_from_string(t, &a); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse system call architecture, ignoring: %s", t); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse system call architecture, ignoring: %s", t); continue; } @@ -2412,8 +2523,7 @@ int config_parse_syscall_archs( return log_oom(); } if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Trailing garbage, ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring."); return 0; } @@ -2445,8 +2555,7 @@ int config_parse_syscall_errno( e = errno_from_name(rvalue); if (e < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse error number, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse error number, ignoring: %s", rvalue); return 0; } @@ -2506,8 +2615,7 @@ int config_parse_address_families( af = af_from_name(t); if (af <= 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse address family, ignoring: %s", t); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse address family, ignoring: %s", t); continue; } @@ -2524,8 +2632,7 @@ int config_parse_address_families( set_remove(c->address_families, INT_TO_PTR(af)); } if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Trailing garbage, ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring."); return 0; } @@ -2628,15 +2735,12 @@ int config_parse_cpu_quota( } if (!endswith(rvalue, "%")) { - - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "CPU quota '%s' not ending in '%%'. Ignoring.", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "CPU quota '%s' not ending in '%%'. Ignoring.", rvalue); return 0; } if (sscanf(rvalue, "%lf%%", &percent) != 1 || percent <= 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "CPU quota '%s' invalid. Ignoring.", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "CPU quota '%s' invalid. Ignoring.", rvalue); return 0; } @@ -2668,7 +2772,7 @@ int config_parse_memory_limit( r = parse_size(rvalue, 1024, &bytes); if (r < 0 || bytes < 1) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Memory limit '%s' invalid. Ignoring.", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Memory limit '%s' invalid. Ignoring.", rvalue); return 0; } @@ -2699,10 +2803,11 @@ int config_parse_tasks_max( r = safe_atou64(rvalue, &u); if (r < 0 || u < 1) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Maximum tasks value '%s' invalid. Ignoring.", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Maximum tasks value '%s' invalid. Ignoring.", rvalue); return 0; } + c->tasks_max = u; return 0; } @@ -2739,8 +2844,7 @@ int config_parse_device_allow( if (!startswith(path, "/dev/") && !startswith(path, "block-") && !startswith(path, "char-")) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid device node path '%s'. Ignoring.", path); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path); return 0; } @@ -2749,8 +2853,7 @@ int config_parse_device_allow( m = "rwm"; if (!in_charset(m, "rwm")) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid device rights '%s'. Ignoring.", m); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device rights '%s'. Ignoring.", m); return 0; } @@ -2832,7 +2935,7 @@ int config_parse_blockio_device_weight( weight += strspn(weight, WHITESPACE); if (isempty(weight)) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Expected block device and device weight. Ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Expected block device and device weight. Ignoring."); return 0; } @@ -2841,7 +2944,7 @@ int config_parse_blockio_device_weight( return log_oom(); if (!path_startswith(path, "/dev")) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid device node path '%s'. Ignoring.", path); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path); return 0; } @@ -2908,8 +3011,7 @@ int config_parse_blockio_bandwidth( bandwidth += strspn(bandwidth, WHITESPACE); if (!*bandwidth) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Expected space separated pair of device node and bandwidth. Ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Expected space separated pair of device node and bandwidth. Ignoring."); return 0; } @@ -2918,15 +3020,13 @@ int config_parse_blockio_bandwidth( return log_oom(); if (!path_startswith(path, "/dev")) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid device node path '%s'. Ignoring.", path); + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path); return 0; } r = parse_size(bandwidth, 1000, &bytes); if (r < 0 || bytes <= 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Block IO Bandwidth '%s' invalid. Ignoring.", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Block IO Bandwidth '%s' invalid. Ignoring.", rvalue); return 0; } @@ -2971,13 +3071,12 @@ int config_parse_netclass( r = safe_atou32(rvalue, &v); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Netclass '%s' invalid. Ignoring.", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Netclass '%s' invalid. Ignoring.", rvalue); return 0; } if (v > CGROUP_NETCLASS_FIXED_MAX) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, + log_syntax(unit, LOG_ERR, filename, line, 0, "Fixed netclass %" PRIu32 " out of allowed range (0-%d). Applying anyway.", v, (uint32_t) CGROUP_NETCLASS_FIXED_MAX); c->netclass_id = v; @@ -3009,8 +3108,7 @@ int config_parse_job_mode_isolate( r = parse_boolean(rvalue); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse boolean, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse boolean, ignoring: %s", rvalue); return 0; } @@ -3056,14 +3154,12 @@ int config_parse_runtime_directory( r = unit_name_printf(u, t, &n); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve specifiers, ignoring: %s", strerror(-r)); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m"); continue; } if (!filename_is_valid(n)) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Runtime directory is not valid, ignoring assignment: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Runtime directory is not valid, ignoring assignment: %s", rvalue); continue; } @@ -3074,8 +3170,7 @@ int config_parse_runtime_directory( n = NULL; } if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Trailing garbage, ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring."); return 0; } @@ -3122,15 +3217,13 @@ int config_parse_set_status( val = signal_from_string_try_harder(temp); if (val <= 0) { - log_syntax(unit, LOG_ERR, filename, line, -val, - "Failed to parse value, ignoring: %s", word); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse value, ignoring: %s", word); continue; } set = &status_set->signal; } else { if (val < 0 || val > 255) { - log_syntax(unit, LOG_ERR, filename, line, ERANGE, - "Value %d is outside range 0-255, ignoring", val); + log_syntax(unit, LOG_ERR, filename, line, 0, "Value %d is outside range 0-255, ignoring", val); continue; } set = &status_set->status; @@ -3142,14 +3235,12 @@ int config_parse_set_status( r = set_put(*set, INT_TO_PTR(val)); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Unable to store: %s", word); + log_syntax(unit, LOG_ERR, filename, line, r, "Unable to store: %s", word); return r; } } if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Trailing garbage, ignoring."); + log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring."); return 0; } @@ -3167,8 +3258,8 @@ int config_parse_namespace_path_strv( void *userdata) { char*** sv = data; - const char *word, *state; - size_t l; + const char *prev; + const char *cur; int r; assert(filename); @@ -3182,37 +3273,43 @@ int config_parse_namespace_path_strv( return 0; } - FOREACH_WORD_QUOTED(word, l, rvalue, state) { - _cleanup_free_ char *n; + prev = cur = rvalue; + for (;;) { + _cleanup_free_ char *word = NULL; int offset; - n = strndup(word, l); - if (!n) + r = extract_first_word(&cur, &word, NULL, EXTRACT_QUOTES); + if (r == 0) + break; + if (r == -ENOMEM) return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Trailing garbage, ignoring: %s", prev); + return 0; + } - if (!utf8_is_valid(n)) { - log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue); + if (!utf8_is_valid(word)) { + log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, word); + prev = cur; continue; } - offset = n[0] == '-'; - if (!path_is_absolute(n + offset)) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Not an absolute path, ignoring: %s", rvalue); + offset = word[0] == '-'; + if (!path_is_absolute(word + offset)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", word); + prev = cur; continue; } - path_kill_slashes(n); + path_kill_slashes(word + offset); - r = strv_push(sv, n); + r = strv_push(sv, word); if (r < 0) return log_oom(); - n = NULL; + prev = cur; + word = NULL; } - if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Trailing garbage, ignoring."); return 0; } @@ -3239,8 +3336,7 @@ int config_parse_no_new_privileges( k = parse_boolean(rvalue); if (k < 0) { - log_syntax(unit, LOG_ERR, filename, line, -k, - "Failed to parse boolean value, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse boolean value, ignoring: %s", rvalue); return 0; } @@ -3283,8 +3379,7 @@ int config_parse_protect_home( h = protect_home_from_string(rvalue); if (h < 0){ - log_syntax(unit, LOG_ERR, filename, line, -h, - "Failed to parse protect home value, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect home value, ignoring: %s", rvalue); return 0; } @@ -3327,8 +3422,7 @@ int config_parse_protect_system( s = protect_system_from_string(rvalue); if (s < 0){ - log_syntax(unit, LOG_ERR, filename, line, -s, - "Failed to parse protect system value, ignoring: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect system value, ignoring: %s", rvalue); return 0; } |