From f6dd5e7c189bf4577541a37e062bd877273823ff Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 11:58:58 +0100 Subject: [PATCH 01/18] proc-cmdline: turn flags parameter into a proper typedef'ed enum Let's add some extra typesafety. --- src/basic/proc-cmdline.c | 6 +++--- src/basic/proc-cmdline.h | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c index 205ea08f6d..a52e58002e 100644 --- a/src/basic/proc-cmdline.c +++ b/src/basic/proc-cmdline.c @@ -39,7 +39,7 @@ int proc_cmdline(char **ret) { return read_one_line_file("/proc/cmdline", ret); } -int proc_cmdline_parse_given(const char *line, proc_cmdline_parse_t parse_item, void *data, unsigned flags) { +int proc_cmdline_parse_given(const char *line, proc_cmdline_parse_t parse_item, void *data, ProcCmdlineFlags flags) { const char *p; int r; @@ -82,7 +82,7 @@ int proc_cmdline_parse_given(const char *line, proc_cmdline_parse_t parse_item, return 0; } -int proc_cmdline_parse(proc_cmdline_parse_t parse_item, void *data, unsigned flags) { +int proc_cmdline_parse(proc_cmdline_parse_t parse_item, void *data, ProcCmdlineFlags flags) { _cleanup_free_ char *line = NULL; int r; @@ -127,7 +127,7 @@ bool proc_cmdline_key_streq(const char *x, const char *y) { return true; } -int proc_cmdline_get_key(const char *key, unsigned flags, char **value) { +int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **value) { _cleanup_free_ char *line = NULL, *ret = NULL; bool found = false; const char *p; diff --git a/src/basic/proc-cmdline.h b/src/basic/proc-cmdline.h index efa88df0a0..cf04cb46c2 100644 --- a/src/basic/proc-cmdline.h +++ b/src/basic/proc-cmdline.h @@ -5,20 +5,20 @@ #include "log.h" -enum { +typedef enum ProcCmdlineFlags { PROC_CMDLINE_STRIP_RD_PREFIX = 1 << 0, PROC_CMDLINE_VALUE_OPTIONAL = 1 << 1, PROC_CMDLINE_RD_STRICT = 1 << 2, -}; +} ProcCmdlineFlags; typedef int (*proc_cmdline_parse_t)(const char *key, const char *value, void *data); int proc_cmdline(char **ret); -int proc_cmdline_parse_given(const char *line, proc_cmdline_parse_t parse_item, void *data, unsigned flags); -int proc_cmdline_parse(const proc_cmdline_parse_t parse, void *userdata, unsigned flags); +int proc_cmdline_parse_given(const char *line, proc_cmdline_parse_t parse_item, void *data, ProcCmdlineFlags flags); +int proc_cmdline_parse(const proc_cmdline_parse_t parse, void *userdata, ProcCmdlineFlags flags); -int proc_cmdline_get_key(const char *parameter, unsigned flags, char **value); +int proc_cmdline_get_key(const char *parameter, ProcCmdlineFlags flags, char **value); int proc_cmdline_get_bool(const char *key, bool *ret); char *proc_cmdline_key_startswith(const char *s, const char *prefix); From 1e7a599671ccf1dccd21e02414f515efca069be6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 12:39:34 +0100 Subject: [PATCH 02/18] proc-cmdline: split out rd. prefix handling in proc_cmdline_parse_given() and proc_cmdline_get_key() This introduces a wrapper around extrac_first_word() called proc_cmdline_extract_first(), which suppresses "rd." parameters depending on the specified calls. This allows us to share more code between proc_cmdline_parse_given() and proc_cmdline_get_key(), and makes it easier to reuse this logic for other purposes. --- src/basic/proc-cmdline.c | 113 ++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 48 deletions(-) diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c index a52e58002e..112f3b7aa2 100644 --- a/src/basic/proc-cmdline.c +++ b/src/basic/proc-cmdline.c @@ -39,42 +39,71 @@ int proc_cmdline(char **ret) { return read_one_line_file("/proc/cmdline", ret); } +static int proc_cmdline_extract_first(const char **p, char **ret_word, ProcCmdlineFlags flags) { + const char *q = *p; + int r; + + for (;;) { + _cleanup_free_ char *word = NULL; + const char *c; + + r = extract_first_word(&q, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX); + if (r < 0) + return r; + if (r == 0) + break; + + /* Filter out arguments that are intended only for the initrd */ + c = startswith(word, "rd."); + if (c) { + if (!in_initrd()) + continue; + + if (FLAGS_SET(flags, PROC_CMDLINE_STRIP_RD_PREFIX)) { + r = free_and_strdup(&word, c); + if (r < 0) + return r; + } + + } else if (FLAGS_SET(flags, PROC_CMDLINE_RD_STRICT) && in_initrd()) + continue; /* And optionally filter out arguments that are intended only for the host */ + + *p = q; + *ret_word = TAKE_PTR(word); + return 1; + } + + *p = q; + *ret_word = NULL; + return 0; +} + int proc_cmdline_parse_given(const char *line, proc_cmdline_parse_t parse_item, void *data, ProcCmdlineFlags flags) { const char *p; int r; assert(parse_item); + /* The PROC_CMDLINE_VALUE_OPTIONAL flag doesn't really make sense for proc_cmdline_parse(), let's make this + * clear. */ + assert(!FLAGS_SET(flags, PROC_CMDLINE_VALUE_OPTIONAL)); + p = line; for (;;) { _cleanup_free_ char *word = NULL; - char *value, *key, *q; + char *value; - r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX); + r = proc_cmdline_extract_first(&p, &word, flags); if (r < 0) return r; if (r == 0) break; - key = word; - - /* Filter out arguments that are intended only for the initrd */ - q = startswith(word, "rd."); - if (q) { - if (!in_initrd()) - continue; - - if (FLAGS_SET(flags, PROC_CMDLINE_STRIP_RD_PREFIX)) - key = q; - - } else if (FLAGS_SET(flags, PROC_CMDLINE_RD_STRICT) && in_initrd()) - continue; /* And optionally filter out arguments that are intended only for the host */ - - value = strchr(key, '='); + value = strchr(word, '='); if (value) *(value++) = 0; - r = parse_item(key, value, data); + r = parse_item(word, value, data); if (r < 0) return r; } @@ -127,29 +156,29 @@ bool proc_cmdline_key_streq(const char *x, const char *y) { return true; } -int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **value) { +int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **ret_value) { _cleanup_free_ char *line = NULL, *ret = NULL; bool found = false; const char *p; int r; - /* Looks for a specific key on the kernel command line. Supports two modes: + /* Looks for a specific key on the kernel command line. Supports three modes: * - * a) The "value" parameter is used. In this case a parameter beginning with the "key" string followed by "=" - * is searched, and the value following this is returned in "value". + * a) The "ret_value" parameter is used. In this case a parameter beginning with the "key" string followed by + * "=" is searched for, and the value following it is returned in "ret_value". * - * b) as above, but the PROC_CMDLINE_VALUE_OPTIONAL flag is set. In this case if the key is found as a - * separate word (i.e. not followed by "=" but instead by whitespace or the end of the command line), then - * this is also accepted, and "value" is returned as NULL. + * b) as above, but the PROC_CMDLINE_VALUE_OPTIONAL flag is set. In this case if the key is found as a separate + * word (i.e. not followed by "=" but instead by whitespace or the end of the command line), then this is + * also accepted, and "value" is returned as NULL. * - * c) The "value" parameter is NULL. In this case a search for the exact "key" parameter is performed. + * c) The "ret_value" parameter is NULL. In this case a search for the exact "key" parameter is performed. * * In all three cases, > 0 is returned if the key is found, 0 if not. */ if (isempty(key)) return -EINVAL; - if (FLAGS_SET(flags, PROC_CMDLINE_VALUE_OPTIONAL) && !value) + if (FLAGS_SET(flags, PROC_CMDLINE_VALUE_OPTIONAL) && !ret_value) return -EINVAL; r = proc_cmdline(&line); @@ -159,31 +188,17 @@ int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **value) p = line; for (;;) { _cleanup_free_ char *word = NULL; - const char *e, *k, *q; - r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX); + r = proc_cmdline_extract_first(&p, &word, flags); if (r < 0) return r; if (r == 0) break; - k = word; + if (ret_value) { + const char *e; - /* Automatically filter out arguments that are intended only for the initrd, if we are not in the - * initrd. */ - q = startswith(word, "rd."); - if (q) { - if (!in_initrd()) - continue; - - if (FLAGS_SET(flags, PROC_CMDLINE_STRIP_RD_PREFIX)) - k = q; - - } else if (FLAGS_SET(flags, PROC_CMDLINE_RD_STRICT) && in_initrd()) - continue; - - if (value) { - e = proc_cmdline_key_startswith(k, key); + e = proc_cmdline_key_startswith(word, key); if (!e) continue; @@ -198,13 +213,15 @@ int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **value) found = true; } else { - if (streq(k, key)) + if (streq(word, key)) { found = true; + break; /* we found what we were looking for */ + } } } - if (value) - *value = TAKE_PTR(ret); + if (ret_value) + *ret_value = TAKE_PTR(ret); return found; } From 78b30ee056796e7fbb2eb5e8ed9363511da9fa5d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 12:41:23 +0100 Subject: [PATCH 03/18] proc-cmdline: introduce new proc_cmdline_get_key_many() helper This is like parse_env_file(), but from the kernel command line --- src/basic/proc-cmdline.c | 56 ++++++++++++++++++++++++++++++++++++ src/basic/proc-cmdline.h | 3 ++ src/test/test-proc-cmdline.c | 19 ++++++++++++ 3 files changed, 78 insertions(+) diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c index 112f3b7aa2..1670001364 100644 --- a/src/basic/proc-cmdline.c +++ b/src/basic/proc-cmdline.c @@ -251,6 +251,62 @@ int proc_cmdline_get_bool(const char *key, bool *ret) { return 1; } +int proc_cmdline_get_key_many_internal(ProcCmdlineFlags flags, ...) { + _cleanup_free_ char *line = NULL; + const char *p; + va_list ap; + int r, ret = 0; + + /* The PROC_CMDLINE_VALUE_OPTIONAL flag doesn't really make sense for proc_cmdline_get_key_many(), let's make + * this clear. */ + assert(!FLAGS_SET(flags, PROC_CMDLINE_VALUE_OPTIONAL)); + + /* This call may clobber arguments on failure! */ + + r = proc_cmdline(&line); + if (r < 0) + return r; + + p = line; + for (;;) { + _cleanup_free_ char *word = NULL; + + r = proc_cmdline_extract_first(&p, &word, flags); + if (r < 0) + return r; + if (r == 0) + break; + + va_start(ap, flags); + + for (;;) { + char **v; + const char *k, *e; + + k = va_arg(ap, const char*); + if (!k) + break; + + assert_se(v = va_arg(ap, char**)); + + e = proc_cmdline_key_startswith(word, k); + if (e && *e == '=') { + r = free_and_strdup(v, e + 1); + if (r < 0) { + va_end(ap); + return r; + } + + ret++; + } + } + + va_end(ap); + } + + return ret; +} + int shall_restore_state(void) { bool ret; int r; diff --git a/src/basic/proc-cmdline.h b/src/basic/proc-cmdline.h index cf04cb46c2..ff04379fbd 100644 --- a/src/basic/proc-cmdline.h +++ b/src/basic/proc-cmdline.h @@ -21,6 +21,9 @@ int proc_cmdline_parse(const proc_cmdline_parse_t parse, void *userdata, ProcCmd int proc_cmdline_get_key(const char *parameter, ProcCmdlineFlags flags, char **value); int proc_cmdline_get_bool(const char *key, bool *ret); +int proc_cmdline_get_key_many_internal(ProcCmdlineFlags flags, ...); +#define proc_cmdline_get_key_many(flags, ...) proc_cmdline_get_key_many_internal(flags, __VA_ARGS__, NULL) + char *proc_cmdline_key_startswith(const char *s, const char *prefix); bool proc_cmdline_key_streq(const char *x, const char *y); diff --git a/src/test/test-proc-cmdline.c b/src/test/test-proc-cmdline.c index 1b6724755f..3edc75f554 100644 --- a/src/test/test-proc-cmdline.c +++ b/src/test/test-proc-cmdline.c @@ -135,6 +135,24 @@ static void test_proc_cmdline_get_bool(void) { assert_se(proc_cmdline_get_bool("quux", &value) == -EINVAL && value == false); } +static void test_proc_cmdline_get_key_many(void) { + _cleanup_free_ char *value1 = NULL, *value2 = NULL, *value3 = NULL, *value4 = NULL; + + log_info("/* %s */", __func__); + assert_se(putenv((char*) "SYSTEMD_PROC_CMDLINE=foo_bar=quux wuff-piep=tuet zumm") == 0); + + assert_se(proc_cmdline_get_key_many(0, + "wuff-piep", &value3, + "foo_bar", &value1, + "idontexist", &value2, + "zumm", &value4) == 2); + + assert_se(streq_ptr(value1, "quux")); + assert_se(!value2); + assert_se(streq_ptr(value3, "tuet")); + assert_se(!value4); +} + static void test_proc_cmdline_key_streq(void) { log_info("/* %s */", __func__); @@ -199,6 +217,7 @@ int main(void) { test_proc_cmdline_key_startswith(); test_proc_cmdline_get_key(); test_proc_cmdline_get_bool(); + test_proc_cmdline_get_key_many(); test_runlevel_to_target(); return 0; From 05e062cb89052705442ee43c48979d926fb3fda9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 12:50:06 +0100 Subject: [PATCH 04/18] locale-setup: use _cleanup_strv_free_ --- src/core/locale-setup.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c index c14523fee9..c123f3906e 100644 --- a/src/core/locale-setup.c +++ b/src/core/locale-setup.c @@ -14,8 +14,8 @@ #include "virt.h" int locale_setup(char ***environment) { - char **add; char *variables[_VARIABLE_LC_MAX] = {}; + _cleanup_strv_free_ char **add = NULL; int r = 0, i; if (detect_container() <= 0) { @@ -64,7 +64,6 @@ int locale_setup(char ***environment) { log_warning_errno(r, "Failed to read /etc/locale.conf: %m"); } - add = NULL; for (i = 0; i < _VARIABLE_LC_MAX; i++) { char *s; @@ -98,8 +97,6 @@ int locale_setup(char ***environment) { r = 0; finish: - strv_free(add); - for (i = 0; i < _VARIABLE_LC_MAX; i++) free(variables[i]); From 6176be15ac02c8988caff0820e865080e866682f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 12:51:23 +0100 Subject: [PATCH 05/18] locale-setup: use precise type for locale variable iterator --- src/core/locale-setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c index c123f3906e..a51ff74c8c 100644 --- a/src/core/locale-setup.c +++ b/src/core/locale-setup.c @@ -16,7 +16,8 @@ int locale_setup(char ***environment) { char *variables[_VARIABLE_LC_MAX] = {}; _cleanup_strv_free_ char **add = NULL; - int r = 0, i; + LocaleVariable i; + int r = 0; if (detect_container() <= 0) { r = parse_env_file(NULL, "/proc/cmdline", WHITESPACE, From cd45734f8700feb66409774d8830d6541f6bb294 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 12:53:28 +0100 Subject: [PATCH 06/18] locale-setup: rework to use new proc_cmdline_get_key_many() API This way we use the same code to access /proc/cmdline as everywhere else, and thus support it in containers and the SYSTEMD_PROC_CMDLINE env var. --- src/core/locale-setup.c | 44 +++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c index a51ff74c8c..5fd54773b3 100644 --- a/src/core/locale-setup.c +++ b/src/core/locale-setup.c @@ -8,6 +8,7 @@ #include "fileio.h" #include "locale-setup.h" #include "locale-util.h" +#include "proc-cmdline.h" #include "string-util.h" #include "strv.h" #include "util.h" @@ -17,32 +18,27 @@ int locale_setup(char ***environment) { char *variables[_VARIABLE_LC_MAX] = {}; _cleanup_strv_free_ char **add = NULL; LocaleVariable i; - int r = 0; + int r; - if (detect_container() <= 0) { - r = parse_env_file(NULL, "/proc/cmdline", WHITESPACE, - "locale.LANG", &variables[VARIABLE_LANG], - "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE], - "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE], - "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], - "locale.LC_TIME", &variables[VARIABLE_LC_TIME], - "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE], - "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY], - "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], - "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER], - "locale.LC_NAME", &variables[VARIABLE_LC_NAME], - "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], - "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], - "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], - "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], - NULL); + r = proc_cmdline_get_key_many(PROC_CMDLINE_STRIP_RD_PREFIX, + "locale.LANG", &variables[VARIABLE_LANG], + "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE], + "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE], + "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], + "locale.LC_TIME", &variables[VARIABLE_LC_TIME], + "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE], + "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY], + "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], + "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER], + "locale.LC_NAME", &variables[VARIABLE_LC_NAME], + "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], + "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], + "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], + "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION]); + if (r < 0 && r != -ENOENT) + log_warning_errno(r, "Failed to read /proc/cmdline: %m"); - if (r < 0 && r != -ENOENT) - log_warning_errno(r, "Failed to read /proc/cmdline: %m"); - } - - /* Hmm, nothing set on the kernel cmd line? Then let's - * try /etc/locale.conf */ + /* Hmm, nothing set on the kernel cmd line? Then let's try /etc/locale.conf */ if (r <= 0) { r = parse_env_file(NULL, "/etc/locale.conf", NEWLINE, "LANG", &variables[VARIABLE_LANG], From 0db9bd200f62a5707ea16552537dcaad2d9e9331 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 13:12:39 +0100 Subject: [PATCH 07/18] locale-setup: default to C.UTF-8 Most distributions already were shipping a C.UTF-8 locale and even Fedora now supports the C.UTF-8 locale, and there's clear indication that this is going upstream too. Hence, let's default to it now too, if nothing else is set. Note that this is only a fallback if noting else is set, and since distros generally configure a default for this behaviour shouldn't really change in installed systems. On new systems this makes vconsole.conf redundant. --- src/core/locale-setup.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c index 5fd54773b3..dc6157624d 100644 --- a/src/core/locale-setup.c +++ b/src/core/locale-setup.c @@ -79,16 +79,28 @@ int locale_setup(char ***environment) { } } - if (!strv_isempty(add)) { - char **e; + if (strv_isempty(add)) { + /* If no locale is configured then default to C.UTF-8. */ - e = strv_env_merge(2, *environment, add); - if (!e) { + add = strv_new("LANG=C.UTF-8"); + if (!add) { + r = -ENOMEM; + goto finish; + } + } + + if (strv_isempty(*environment)) + strv_free_and_replace(*environment, add); + else { + char **merged; + + merged = strv_env_merge(2, *environment, add); + if (!merged) { r = -ENOMEM; goto finish; } - strv_free_and_replace(*environment, e); + strv_free_and_replace(*environment, merged); } r = 0; From 46e8b9470ae78eeee2cb84a3b06ef9f0c98b3e08 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 13:22:36 +0100 Subject: [PATCH 08/18] localed: don't silently eat up errors, log something --- src/locale/localed.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/locale/localed.c b/src/locale/localed.c index c949fa3831..67d92e4808 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -40,11 +40,11 @@ static int locale_update_system_manager(Context *c, sd_bus *bus) { l_unset = new0(char*, _VARIABLE_LC_MAX); if (!l_unset) - return -ENOMEM; + return log_oom(); l_set = new0(char*, _VARIABLE_LC_MAX); if (!l_set) - return -ENOMEM; + return log_oom(); for (p = 0, c_set = 0, c_unset = 0; p < _VARIABLE_LC_MAX; p++) { const char *name; @@ -57,8 +57,9 @@ static int locale_update_system_manager(Context *c, sd_bus *bus) { else { char *s; - if (asprintf(&s, "%s=%s", name, c->locale[p]) < 0) - return -ENOMEM; + s = strjoin(name, "=", c->locale[p]); + if (!s) + return log_oom(); l_set[c_unset++] = s; } @@ -71,15 +72,15 @@ static int locale_update_system_manager(Context *c, sd_bus *bus) { "org.freedesktop.systemd1.Manager", "UnsetAndSetEnvironment"); if (r < 0) - return r; + return bus_log_create_error(r); r = sd_bus_message_append_strv(m, l_unset); if (r < 0) - return r; + return bus_log_create_error(r); r = sd_bus_message_append_strv(m, l_set); if (r < 0) - return r; + return bus_log_create_error(r); r = sd_bus_call(bus, m, 0, &error, NULL); if (r < 0) From 936d113663040061514f8d9db5a68a6aba46b119 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 13:22:48 +0100 Subject: [PATCH 09/18] localed: show proper bus error if we can in log message --- src/locale/localed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale/localed.c b/src/locale/localed.c index 67d92e4808..94107de62b 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -84,7 +84,7 @@ static int locale_update_system_manager(Context *c, sd_bus *bus) { r = sd_bus_call(bus, m, 0, &error, NULL); if (r < 0) - log_error_errno(r, "Failed to update the manager environment, ignoring: %m"); + return log_error_errno(r, "Failed to update the manager environment: %s", bus_error_message(&error, r)); return 0; } From 26a9337690f6fe4f1be4a1b7ae617688c38dc1ec Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 13:23:51 +0100 Subject: [PATCH 10/18] localed: no need to log twice about reload requests --- src/locale/localed.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/locale/localed.c b/src/locale/localed.c index 94107de62b..01bb5a74c2 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -105,7 +105,7 @@ static int vconsole_reload(sd_bus *bus) { "ss", "systemd-vconsole-setup.service", "replace"); if (r < 0) - return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, -r)); + return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r)); return 0; } @@ -459,9 +459,7 @@ static int method_set_vc_keyboard(sd_bus_message *m, void *userdata, sd_bus_erro log_info("Changed virtual console keymap to '%s' toggle '%s'", strempty(c->vc_keymap), strempty(c->vc_keymap_toggle)); - r = vconsole_reload(sd_bus_message_get_bus(m)); - if (r < 0) - log_error_errno(r, "Failed to request keymap reload: %m"); + (void) vconsole_reload(sd_bus_message_get_bus(m)); (void) sd_bus_emit_properties_changed( sd_bus_message_get_bus(m), From 01771226c202183ff447da712f43d2fad8874484 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 13:49:20 +0100 Subject: [PATCH 11/18] tree-wide: replace all remaining uses of parse_env_file() for parsing /proc/cmdline Let's always go through the proc-cmdline.c APIs. --- src/locale/localectl.c | 36 +++++++++++++++++------------------ src/systemctl/systemctl.c | 5 ++--- src/vconsole/vconsole-setup.c | 29 ++++++++++++++-------------- 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/locale/localectl.c b/src/locale/localectl.c index e2a9415138..c8278a383d 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -16,6 +16,7 @@ #include "fileio.h" #include "locale-util.h" #include "pager.h" +#include "proc-cmdline.h" #include "set.h" #include "spawn-polkit-agent.h" #include "strv.h" @@ -53,26 +54,25 @@ static void print_overridden_variables(void) { LocaleVariable j; bool print_warning = true; - if (detect_container() > 0 || arg_host) + if (arg_transport != BUS_TRANSPORT_LOCAL) return; - r = parse_env_file(NULL, "/proc/cmdline", WHITESPACE, - "locale.LANG", &variables[VARIABLE_LANG], - "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE], - "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE], - "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], - "locale.LC_TIME", &variables[VARIABLE_LC_TIME], - "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE], - "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY], - "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], - "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER], - "locale.LC_NAME", &variables[VARIABLE_LC_NAME], - "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], - "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], - "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], - "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], - NULL); - + r = proc_cmdline_get_key_many( + PROC_CMDLINE_STRIP_RD_PREFIX, + "locale.LANG", &variables[VARIABLE_LANG], + "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE], + "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE], + "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], + "locale.LC_TIME", &variables[VARIABLE_LC_TIME], + "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE], + "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY], + "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], + "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER], + "locale.LC_NAME", &variables[VARIABLE_LC_NAME], + "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], + "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], + "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], + "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION]); if (r < 0 && r != -ENOENT) { log_warning_errno(r, "Failed to read /proc/cmdline: %m"); goto finish; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 9d0c40b93c..336a6933d0 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -56,6 +56,7 @@ #include "parse-util.h" #include "path-lookup.h" #include "path-util.h" +#include "proc-cmdline.h" #include "process-util.h" #include "reboot-util.h" #include "rlimit-util.h" @@ -5699,9 +5700,7 @@ static int switch_root(int argc, char *argv[], void *userdata) { if (argc >= 3) init = argv[2]; else { - r = parse_env_file(NULL, "/proc/cmdline", WHITESPACE, - "init", &cmdline_init, - NULL); + r = proc_cmdline_get_key("init", 0, &cmdline_init); if (r < 0) log_debug_errno(r, "Failed to parse /proc/cmdline: %m"); diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index 4c55ed7cb5..dc409eef7e 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -23,6 +23,7 @@ #include "io-util.h" #include "locale-util.h" #include "log.h" +#include "proc-cmdline.h" #include "process-util.h" #include "signal-util.h" #include "stdio-util.h" @@ -428,21 +429,19 @@ int main(int argc, char **argv) { log_warning_errno(r, "Failed to read /etc/vconsole.conf: %m"); /* Let the kernel command line override /etc/vconsole.conf */ - if (detect_container() <= 0) { - r = parse_env_file(NULL, "/proc/cmdline", WHITESPACE, - "vconsole.keymap", &vc_keymap, - "vconsole.keymap_toggle", &vc_keymap_toggle, - "vconsole.font", &vc_font, - "vconsole.font_map", &vc_font_map, - "vconsole.font_unimap", &vc_font_unimap, - /* compatibility with obsolete multiple-dot scheme */ - "vconsole.keymap.toggle", &vc_keymap_toggle, - "vconsole.font.map", &vc_font_map, - "vconsole.font.unimap", &vc_font_unimap, - NULL); - if (r < 0 && r != -ENOENT) - log_warning_errno(r, "Failed to read /proc/cmdline: %m"); - } + r = proc_cmdline_get_key_many( + PROC_CMDLINE_STRIP_RD_PREFIX, + "vconsole.keymap", &vc_keymap, + "vconsole.keymap_toggle", &vc_keymap_toggle, + "vconsole.font", &vc_font, + "vconsole.font_map", &vc_font_map, + "vconsole.font_unimap", &vc_font_unimap, + /* compatibility with obsolete multiple-dot scheme */ + "vconsole.keymap.toggle", &vc_keymap_toggle, + "vconsole.font.map", &vc_font_map, + "vconsole.font.unimap", &vc_font_unimap); + if (r < 0 && r != -ENOENT) + log_warning_errno(r, "Failed to read /proc/cmdline: %m"); (void) toggle_utf8_sysfs(utf8); (void) toggle_utf8(vc, fd, utf8); From aa8fbc74e3eadf57a15b84cce5778a8eab1d97e6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 14:04:47 +0100 Subject: [PATCH 12/18] fileio: drop "newline" parameter for env file parsers Now that we don't (mis-)use the env file parser to parse kernel command lines there's no need anymore to override the used newline character set. Let's hence drop the argument and just "\n\r" always. This nicely simplifies our code. --- src/basic/exec-util.c | 2 +- src/basic/fileio.c | 44 +++++++++----------------- src/basic/fileio.h | 8 ++--- src/basic/os-util.c | 4 +-- src/basic/util.c | 2 +- src/core/execute.c | 2 +- src/core/locale-setup.c | 2 +- src/hostname/hostnamed.c | 4 +-- src/journal-remote/journal-upload.c | 2 +- src/journal/journald-stream.c | 2 +- src/journal/sd-journal.c | 2 +- src/libsystemd-network/sd-dhcp-lease.c | 2 +- src/libsystemd/sd-login/sd-login.c | 28 ++++++++-------- src/libsystemd/sd-network/sd-network.c | 10 +++--- src/locale/keymap-util.c | 6 ++-- src/login/logind-inhibit.c | 2 +- src/login/logind-session.c | 2 +- src/login/logind-user.c | 2 +- src/machine/machine-dbus.c | 2 +- src/machine/machine.c | 2 +- src/network/networkd-link.c | 2 +- src/network/networkd-lldp-tx.c | 2 +- src/portable/portablectl.c | 2 +- src/resolve/resolved-link.c | 2 +- src/shared/cgroup-show.c | 2 +- src/shared/condition.c | 2 +- src/shared/dissect-image.c | 4 +-- src/shared/machine-image.c | 2 +- src/shared/tests.c | 2 +- src/shared/udev-util.c | 2 +- src/test/test-fileio.c | 12 +++---- src/test/test-unit-file.c | 10 +++--- src/vconsole/vconsole-setup.c | 2 +- 33 files changed, 81 insertions(+), 95 deletions(-) diff --git a/src/basic/exec-util.c b/src/basic/exec-util.c index 2a96ecf9bb..29f14dbeae 100644 --- a/src/basic/exec-util.c +++ b/src/basic/exec-util.c @@ -242,7 +242,7 @@ static int gather_environment_generate(int fd, void *arg) { return -errno; } - r = load_env_file_pairs(f, NULL, NULL, &new); + r = load_env_file_pairs(f, NULL, &new); if (r < 0) return r; diff --git a/src/basic/fileio.c b/src/basic/fileio.c index fa6084e602..45c0b4a840 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -368,7 +368,6 @@ int read_full_file(const char *fn, char **contents, size_t *size) { static int parse_env_file_internal( FILE *f, const char *fname, - const char *newline, int (*push) (const char *filename, unsigned line, const char *key, char *value, void *userdata, int *n_pushed), void *userdata, @@ -394,8 +393,6 @@ static int parse_env_file_internal( COMMENT_ESCAPE } state = PRE_KEY; - assert(newline); - if (f) r = read_full_stream(f, &contents, NULL); else @@ -423,7 +420,7 @@ static int parse_env_file_internal( break; case KEY: - if (strchr(newline, c)) { + if (strchr(NEWLINE, c)) { state = PRE_KEY; line++; n_key = 0; @@ -445,7 +442,7 @@ static int parse_env_file_internal( break; case PRE_VALUE: - if (strchr(newline, c)) { + if (strchr(NEWLINE, c)) { state = PRE_KEY; line++; key[n_key] = 0; @@ -483,7 +480,7 @@ static int parse_env_file_internal( break; case VALUE: - if (strchr(newline, c)) { + if (strchr(NEWLINE, c)) { state = PRE_KEY; line++; @@ -528,7 +525,7 @@ static int parse_env_file_internal( case VALUE_ESCAPE: state = VALUE; - if (!strchr(newline, c)) { + if (!strchr(NEWLINE, c)) { /* Escaped newlines we eat up entirely */ if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) return -ENOMEM; @@ -554,7 +551,7 @@ static int parse_env_file_internal( case SINGLE_QUOTE_VALUE_ESCAPE: state = SINGLE_QUOTE_VALUE; - if (!strchr(newline, c)) { + if (!strchr(NEWLINE, c)) { if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) return -ENOMEM; @@ -579,7 +576,7 @@ static int parse_env_file_internal( case DOUBLE_QUOTE_VALUE_ESCAPE: state = DOUBLE_QUOTE_VALUE; - if (!strchr(newline, c)) { + if (!strchr(NEWLINE, c)) { if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) return -ENOMEM; @@ -590,7 +587,7 @@ static int parse_env_file_internal( case COMMENT: if (c == '\\') state = COMMENT_ESCAPE; - else if (strchr(newline, c)) { + else if (strchr(NEWLINE, c)) { state = PRE_KEY; line++; } @@ -699,17 +696,13 @@ static int parse_env_file_push( int parse_env_filev( FILE *f, const char *fname, - const char *newline, va_list ap) { int r, n_pushed = 0; va_list aq; - if (!newline) - newline = NEWLINE; - va_copy(aq, ap); - r = parse_env_file_internal(f, fname, newline, parse_env_file_push, &aq, &n_pushed); + r = parse_env_file_internal(f, fname, parse_env_file_push, &aq, &n_pushed); va_end(aq); if (r < 0) return r; @@ -720,14 +713,13 @@ int parse_env_filev( int parse_env_file( FILE *f, const char *fname, - const char *newline, ...) { va_list ap; int r; - va_start(ap, newline); - r = parse_env_filev(f, fname, newline, ap); + va_start(ap, fname); + r = parse_env_filev(f, fname, ap); va_end(ap); return r; @@ -763,14 +755,11 @@ static int load_env_file_push( return 0; } -int load_env_file(FILE *f, const char *fname, const char *newline, char ***rl) { +int load_env_file(FILE *f, const char *fname, char ***rl) { char **m = NULL; int r; - if (!newline) - newline = NEWLINE; - - r = parse_env_file_internal(f, fname, newline, load_env_file_push, &m, NULL); + r = parse_env_file_internal(f, fname, load_env_file_push, &m, NULL); if (r < 0) { strv_free(m); return r; @@ -812,14 +801,11 @@ static int load_env_file_push_pairs( return 0; } -int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char ***rl) { +int load_env_file_pairs(FILE *f, const char *fname, char ***rl) { char **m = NULL; int r; - if (!newline) - newline = NEWLINE; - - r = parse_env_file_internal(f, fname, newline, load_env_file_push_pairs, &m, NULL); + r = parse_env_file_internal(f, fname, load_env_file_push_pairs, &m, NULL); if (r < 0) { strv_free(m); return r; @@ -872,7 +858,7 @@ int merge_env_file( * plus "extended" substitutions, unlike other exported parsing functions. */ - return parse_env_file_internal(f, fname, NEWLINE, merge_env_file_push, env, NULL); + return parse_env_file_internal(f, fname, merge_env_file_push, env, NULL); } static void write_env_var(FILE *f, const char *v) { diff --git a/src/basic/fileio.h b/src/basic/fileio.h index f809848408..66d9582ee7 100644 --- a/src/basic/fileio.h +++ b/src/basic/fileio.h @@ -42,10 +42,10 @@ int read_full_stream(FILE *f, char **contents, size_t *size); int verify_file(const char *fn, const char *blob, bool accept_extra_nl); -int parse_env_filev(FILE *f, const char *fname, const char *separator, va_list ap); -int parse_env_file(FILE *f, const char *fname, const char *separator, ...) _sentinel_; -int load_env_file(FILE *f, const char *fname, const char *separator, char ***l); -int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l); +int parse_env_filev(FILE *f, const char *fname, va_list ap); +int parse_env_file(FILE *f, const char *fname, ...) _sentinel_; +int load_env_file(FILE *f, const char *fname, char ***l); +int load_env_file_pairs(FILE *f, const char *fname, char ***l); int merge_env_file(char ***env, FILE *f, const char *fname); diff --git a/src/basic/os-util.c b/src/basic/os-util.c index 207594cef8..82471a45ba 100644 --- a/src/basic/os-util.c +++ b/src/basic/os-util.c @@ -98,7 +98,7 @@ int parse_os_release(const char *root, ...) { return r; va_start(ap, root); - r = parse_env_filev(f, p, NEWLINE, ap); + r = parse_env_filev(f, p, ap); va_end(ap); return r; @@ -113,5 +113,5 @@ int load_os_release_pairs(const char *root, char ***ret) { if (r < 0) return r; - return load_env_file_pairs(f, p, NEWLINE, ret); + return load_env_file_pairs(f, p, ret); } diff --git a/src/basic/util.c b/src/basic/util.c index b6e874c3b8..b860753756 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -248,7 +248,7 @@ int container_get_leader(const char *machine, pid_t *pid) { return -EINVAL; p = strjoina("/run/systemd/machines/", machine); - r = parse_env_file(NULL, p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL); + r = parse_env_file(NULL, p, "LEADER", &s, "CLASS", &class, NULL); if (r == -ENOENT) return -EHOSTDOWN; if (r < 0) diff --git a/src/core/execute.c b/src/core/execute.c index 435d94a86d..cf3c055167 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -3961,7 +3961,7 @@ static int exec_context_load_environment(const Unit *unit, const ExecContext *c, assert(pglob.gl_pathc > 0); for (n = 0; n < pglob.gl_pathc; n++) { - k = load_env_file(NULL, pglob.gl_pathv[n], NULL, &p); + k = load_env_file(NULL, pglob.gl_pathv[n], &p); if (k < 0) { if (ignore) continue; diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c index dc6157624d..e13f21f90f 100644 --- a/src/core/locale-setup.c +++ b/src/core/locale-setup.c @@ -40,7 +40,7 @@ int locale_setup(char ***environment) { /* Hmm, nothing set on the kernel cmd line? Then let's try /etc/locale.conf */ if (r <= 0) { - r = parse_env_file(NULL, "/etc/locale.conf", NEWLINE, + r = parse_env_file(NULL, "/etc/locale.conf", "LANG", &variables[VARIABLE_LANG], "LANGUAGE", &variables[VARIABLE_LANGUAGE], "LC_CTYPE", &variables[VARIABLE_LC_CTYPE], diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index a0535070b3..b8facaf47d 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -89,7 +89,7 @@ static int context_read_data(Context *c) { if (r < 0 && r != -ENOENT) return r; - r = parse_env_file(NULL, "/etc/machine-info", NEWLINE, + r = parse_env_file(NULL, "/etc/machine-info", "PRETTY_HOSTNAME", &c->data[PROP_PRETTY_HOSTNAME], "ICON_NAME", &c->data[PROP_ICON_NAME], "CHASSIS", &c->data[PROP_CHASSIS], @@ -314,7 +314,7 @@ static int context_write_data_machine_info(Context *c) { assert(c); - r = load_env_file(NULL, "/etc/machine-info", NULL, &l); + r = load_env_file(NULL, "/etc/machine-info", &l); if (r < 0 && r != -ENOENT) return r; diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c index 88fc51ec26..0fa915f4c3 100644 --- a/src/journal-remote/journal-upload.c +++ b/src/journal-remote/journal-upload.c @@ -149,7 +149,7 @@ static int load_cursor_state(Uploader *u) { if (!u->state_file) return 0; - r = parse_env_file(NULL, u->state_file, NEWLINE, + r = parse_env_file(NULL, u->state_file, "LAST_CURSOR", &u->last_cursor, NULL); diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c index 9ddcbb9d9d..ca102010bc 100644 --- a/src/journal/journald-stream.c +++ b/src/journal/journald-stream.c @@ -651,7 +651,7 @@ static int stdout_stream_load(StdoutStream *stream, const char *fname) { return log_oom(); } - r = parse_env_file(NULL, stream->state_file, NEWLINE, + r = parse_env_file(NULL, stream->state_file, "PRIORITY", &priority, "LEVEL_PREFIX", &level_prefix, "FORWARD_TO_SYSLOG", &forward_to_syslog, diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index b54e8020f1..dd556d01d6 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1888,7 +1888,7 @@ _public_ int sd_journal_open_container(sd_journal **ret, const char *machine, in assert_return(machine_name_is_valid(machine), -EINVAL); p = strjoina("/run/systemd/machines/", machine); - r = parse_env_file(NULL, p, NEWLINE, "ROOT", &root, "CLASS", &class, NULL); + r = parse_env_file(NULL, p, "ROOT", &root, "CLASS", &class, NULL); if (r == -ENOENT) return -EHOSTDOWN; if (r < 0) diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 863818d6da..8fe468d468 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -1016,7 +1016,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { if (r < 0) return r; - r = parse_env_file(NULL, lease_file, NEWLINE, + r = parse_env_file(NULL, lease_file, "ADDRESS", &address, "ROUTER", &router, "NETMASK", &netmask, diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index 5940eccead..b5ef781b40 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -268,7 +268,7 @@ _public_ int sd_uid_get_state(uid_t uid, char**state) { if (r < 0) return r; - r = parse_env_file(NULL, p, NEWLINE, "STATE", &s, NULL); + r = parse_env_file(NULL, p, "STATE", &s, NULL); if (r == -ENOENT) { free(s); s = strdup("offline"); @@ -299,7 +299,7 @@ _public_ int sd_uid_get_display(uid_t uid, char **session) { if (r < 0) return r; - r = parse_env_file(NULL, p, NEWLINE, "DISPLAY", &s, NULL); + r = parse_env_file(NULL, p, "DISPLAY", &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -354,7 +354,7 @@ _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) variable = require_active ? "ACTIVE_UID" : "UIDS"; - r = parse_env_file(NULL, p, NEWLINE, variable, &s, NULL); + r = parse_env_file(NULL, p, variable, &s, NULL); if (r == -ENOENT) return 0; if (r < 0) @@ -383,7 +383,7 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { if (r < 0) return r; - r = parse_env_file(NULL, p, NEWLINE, variable, &s, NULL); + r = parse_env_file(NULL, p, variable, &s, NULL); if (r == -ENOENT || (r >= 0 && isempty(s))) { if (array) *array = NULL; @@ -461,7 +461,7 @@ _public_ int sd_session_is_active(const char *session) { if (r < 0) return r; - r = parse_env_file(NULL, p, NEWLINE, "ACTIVE", &s, NULL); + r = parse_env_file(NULL, p, "ACTIVE", &s, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -480,7 +480,7 @@ _public_ int sd_session_is_remote(const char *session) { if (r < 0) return r; - r = parse_env_file(NULL, p, NEWLINE, "REMOTE", &s, NULL); + r = parse_env_file(NULL, p, "REMOTE", &s, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -501,7 +501,7 @@ _public_ int sd_session_get_state(const char *session, char **state) { if (r < 0) return r; - r = parse_env_file(NULL, p, NEWLINE, "STATE", &s, NULL); + r = parse_env_file(NULL, p, "STATE", &s, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -524,7 +524,7 @@ _public_ int sd_session_get_uid(const char *session, uid_t *uid) { if (r < 0) return r; - r = parse_env_file(NULL, p, NEWLINE, "UID", &s, NULL); + r = parse_env_file(NULL, p, "UID", &s, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -546,7 +546,7 @@ static int session_get_string(const char *session, const char *field, char **val if (r < 0) return r; - r = parse_env_file(NULL, p, NEWLINE, field, &s, NULL); + r = parse_env_file(NULL, p, field, &s, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -638,7 +638,7 @@ _public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { if (r < 0) return r; - r = parse_env_file(NULL, p, NEWLINE, + r = parse_env_file(NULL, p, "ACTIVE", &s, "ACTIVE_UID", &t, NULL); @@ -676,7 +676,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui if (r < 0) return r; - r = parse_env_file(NULL, p, NEWLINE, + r = parse_env_file(NULL, p, "SESSIONS", &s, "UIDS", &t, NULL); @@ -745,7 +745,7 @@ static int seat_get_can(const char *seat, const char *variable) { if (r < 0) return r; - r = parse_env_file(NULL, p, NEWLINE, + r = parse_env_file(NULL, p, variable, &s, NULL); if (r == -ENOENT) @@ -901,7 +901,7 @@ _public_ int sd_machine_get_class(const char *machine, char **class) { return -EINVAL; p = strjoina("/run/systemd/machines/", machine); - r = parse_env_file(NULL, p, NEWLINE, "CLASS", &c, NULL); + r = parse_env_file(NULL, p, "CLASS", &c, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -925,7 +925,7 @@ _public_ int sd_machine_get_ifindices(const char *machine, int **ifindices) { assert_return(ifindices, -EINVAL); p = strjoina("/run/systemd/machines/", machine); - r = parse_env_file(NULL, p, NEWLINE, "NETIF", &netif, NULL); + r = parse_env_file(NULL, p, "NETIF", &netif, NULL); if (r == -ENOENT) return -ENXIO; if (r < 0) diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index 3b8ce935b0..3d411dc5a4 100644 --- a/src/libsystemd/sd-network/sd-network.c +++ b/src/libsystemd/sd-network/sd-network.c @@ -24,7 +24,7 @@ _public_ int sd_network_get_operational_state(char **state) { assert_return(state, -EINVAL); - r = parse_env_file(NULL, "/run/systemd/netif/state", NEWLINE, "OPER_STATE", &s, NULL); + r = parse_env_file(NULL, "/run/systemd/netif/state", "OPER_STATE", &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -44,7 +44,7 @@ static int network_get_strv(const char *key, char ***ret) { assert_return(ret, -EINVAL); - r = parse_env_file(NULL, "/run/systemd/netif/state", NEWLINE, key, &s, NULL); + r = parse_env_file(NULL, "/run/systemd/netif/state", key, &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -92,7 +92,7 @@ static int network_link_get_string(int ifindex, const char *field, char **ret) { xsprintf(path, "/run/systemd/netif/links/%i", ifindex); - r = parse_env_file(NULL, path, NEWLINE, field, &s, NULL); + r = parse_env_file(NULL, path, field, &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -115,7 +115,7 @@ static int network_link_get_strv(int ifindex, const char *key, char ***ret) { assert_return(ret, -EINVAL); xsprintf(path, "/run/systemd/netif/links/%i", ifindex); - r = parse_env_file(NULL, path, NEWLINE, key, &s, NULL); + r = parse_env_file(NULL, path, key, &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -216,7 +216,7 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) { assert_return(ret, -EINVAL); xsprintf(path, "/run/systemd/netif/links/%i", ifindex); - r = parse_env_file(NULL, path, NEWLINE, key, &s, NULL); + r = parse_env_file(NULL, path, key, &s, NULL); if (r == -ENOENT) return -ENODATA; if (r < 0) diff --git a/src/locale/keymap-util.c b/src/locale/keymap-util.c index 69fcb3543c..dadeef1f25 100644 --- a/src/locale/keymap-util.c +++ b/src/locale/keymap-util.c @@ -114,7 +114,7 @@ int locale_read_data(Context *c, sd_bus_message *m) { c->locale_mtime = t; context_free_locale(c); - r = parse_env_file(NULL, "/etc/locale.conf", NEWLINE, + r = parse_env_file(NULL, "/etc/locale.conf", "LANG", &c->locale[VARIABLE_LANG], "LANGUAGE", &c->locale[VARIABLE_LANGUAGE], "LC_CTYPE", &c->locale[VARIABLE_LC_CTYPE], @@ -186,7 +186,7 @@ int vconsole_read_data(Context *c, sd_bus_message *m) { c->vc_mtime = t; context_free_vconsole(c); - r = parse_env_file(NULL, "/etc/vconsole.conf", NEWLINE, + r = parse_env_file(NULL, "/etc/vconsole.conf", "KEYMAP", &c->vc_keymap, "KEYMAP_TOGGLE", &c->vc_keymap_toggle, NULL); @@ -341,7 +341,7 @@ int vconsole_write_data(Context *c) { struct stat st; int r; - r = load_env_file(NULL, "/etc/vconsole.conf", NULL, &l); + r = load_env_file(NULL, "/etc/vconsole.conf", &l); if (r < 0 && r != -ENOENT) return r; diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c index b1f45baaca..c45c9fd8c3 100644 --- a/src/login/logind-inhibit.c +++ b/src/login/logind-inhibit.c @@ -193,7 +193,7 @@ int inhibitor_load(Inhibitor *i) { char *cc; int r; - r = parse_env_file(NULL, i->state_file, NEWLINE, + r = parse_env_file(NULL, i->state_file, "WHAT", &what, "UID", &uid, "PID", &pid, diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 197154a897..0168fb0352 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -406,7 +406,7 @@ int session_load(Session *s) { assert(s); - r = parse_env_file(NULL, s->state_file, NEWLINE, + r = parse_env_file(NULL, s->state_file, "REMOTE", &remote, "SCOPE", &s->scope, "SCOPE_JOB", &s->scope_job, diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 0f4c5ccadb..78cfe35a40 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -312,7 +312,7 @@ int user_load(User *u) { assert(u); - r = parse_env_file(NULL, u->state_file, NEWLINE, + r = parse_env_file(NULL, u->state_file, "SERVICE_JOB", &u->service_job, "STOPPING", &stopping, "REALTIME", &realtime, diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 2f9f587973..c921974cbe 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -373,7 +373,7 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s pair[0] = -1; - r = load_env_file_pairs(f, "/etc/os-release", NULL, &l); + r = load_env_file_pairs(f, "/etc/os-release", &l); if (r < 0) return r; diff --git a/src/machine/machine.c b/src/machine/machine.c index d5e0d4953f..75fa94252d 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -251,7 +251,7 @@ int machine_load(Machine *m) { if (!m->state_file) return 0; - r = parse_env_file(NULL, m->state_file, NEWLINE, + r = parse_env_file(NULL, m->state_file, "SCOPE", &m->unit, "SCOPE_JOB", &m->scope_job, "SERVICE", &m->service, diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 1ccaf0e15b..8a62e07278 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -3210,7 +3210,7 @@ static int link_load(Link *link) { assert(link); - r = parse_env_file(NULL, link->state_file, NEWLINE, + r = parse_env_file(NULL, link->state_file, "NETWORK_FILE", &network_file, "ADDRESSES", &addresses, "ROUTES", &routes, diff --git a/src/network/networkd-lldp-tx.c b/src/network/networkd-lldp-tx.c index 51fadc8125..fa36e94a7c 100644 --- a/src/network/networkd-lldp-tx.c +++ b/src/network/networkd-lldp-tx.c @@ -244,7 +244,7 @@ static int link_send_lldp(Link *link) { return r; (void) gethostname_strict(&hostname); - (void) parse_env_file(NULL, "/etc/machine-info", NEWLINE, "PRETTY_HOSTNAME", &pretty_hostname, NULL); + (void) parse_env_file(NULL, "/etc/machine-info", "PRETTY_HOSTNAME", &pretty_hostname, NULL); assert_cc(LLDP_TX_INTERVAL_USEC * LLDP_TX_HOLD + 1 <= (UINT16_MAX - 1) * USEC_PER_SEC); ttl = DIV_ROUND_UP(LLDP_TX_INTERVAL_USEC * LLDP_TX_HOLD + 1, USEC_PER_SEC); diff --git a/src/portable/portablectl.c b/src/portable/portablectl.c index 21e66def50..1b77e4bcb0 100644 --- a/src/portable/portablectl.c +++ b/src/portable/portablectl.c @@ -279,7 +279,7 @@ static int inspect_image(int argc, char *argv[], void *userdata) { if (!f) return log_error_errno(errno, "Failed to open /etc/os-release buffer: %m"); - r = parse_env_file(f, "/etc/os-release", NEWLINE, + r = parse_env_file(f, "/etc/os-release", "PORTABLE_PRETTY_NAME", &pretty_portable, "PRETTY_NAME", &pretty_os, NULL); diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index ff2be12415..54bb805475 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -1257,7 +1257,7 @@ int link_load_user(Link *l) { if (l->is_managed) return 0; /* if the device is managed, then networkd is our configuration source, not the bus API */ - r = parse_env_file(NULL, l->state_file, NEWLINE, + r = parse_env_file(NULL, l->state_file, "LLMNR", &llmnr, "MDNS", &mdns, "DNSSEC", &dnssec, diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c index 801cf133f9..b43a7879ec 100644 --- a/src/shared/cgroup-show.c +++ b/src/shared/cgroup-show.c @@ -339,7 +339,7 @@ int show_cgroup_get_path_and_warn( const char *m; m = strjoina("/run/systemd/machines/", machine); - r = parse_env_file(NULL, m, NEWLINE, "SCOPE", &unit, NULL); + r = parse_env_file(NULL, m, "SCOPE", &unit, NULL); if (r < 0) return log_error_errno(r, "Failed to load machine data: %m"); diff --git a/src/shared/condition.c b/src/shared/condition.c index 2acf36d468..852bdda082 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -471,7 +471,7 @@ static int condition_test_needs_update(Condition *c) { uint64_t timestamp; int r; - r = parse_env_file(NULL, p, NULL, "TIMESTAMP_NSEC", ×tamp_str, NULL); + r = parse_env_file(NULL, p, "TIMESTAMP_NSEC", ×tamp_str, NULL); if (r < 0) { log_error_errno(r, "Failed to parse timestamp file '%s', using mtime: %m", p); return true; diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index c6b7a02ad9..ec3e1a10bb 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1333,14 +1333,14 @@ int dissected_image_acquire_metadata(DissectedImage *m) { } case META_MACHINE_INFO: - r = load_env_file_pairs(f, "machine-info", NULL, &machine_info); + r = load_env_file_pairs(f, "machine-info", &machine_info); if (r < 0) log_debug_errno(r, "Failed to read /etc/machine-info: %m"); break; case META_OS_RELEASE: - r = load_env_file_pairs(f, "os-release", NULL, &os_release); + r = load_env_file_pairs(f, "os-release", &os_release); if (r < 0) log_debug_errno(r, "Failed to read OS release file: %m"); diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c index 0344771a60..d5f6ab8529 100644 --- a/src/shared/machine-image.c +++ b/src/shared/machine-image.c @@ -1114,7 +1114,7 @@ int image_read_metadata(Image *i) { if (r < 0 && r != -ENOENT) log_debug_errno(r, "Failed to chase /etc/machine-info in image %s: %m", i->name); else if (r >= 0) { - r = load_env_file_pairs(NULL, path, NULL, &machine_info); + r = load_env_file_pairs(NULL, path, &machine_info); if (r < 0) log_debug_errno(r, "Failed to parse machine-info data of %s: %m", i->name); } diff --git a/src/shared/tests.c b/src/shared/tests.c index d21bd22b40..bab39685ff 100644 --- a/src/shared/tests.c +++ b/src/shared/tests.c @@ -47,7 +47,7 @@ static void load_testdata_env(void) { dirname(s); envpath = path_join(NULL, s, "systemd-runtest.env"); - if (load_env_file_pairs(NULL, envpath, NULL, &pairs) < 0) + if (load_env_file_pairs(NULL, envpath, &pairs) < 0) return; STRV_FOREACH_PAIR(k, v, pairs) diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c index 959217c511..f847269e82 100644 --- a/src/shared/udev-util.c +++ b/src/shared/udev-util.c @@ -29,7 +29,7 @@ int udev_parse_config_full( _cleanup_free_ char *log_val = NULL, *children_max = NULL, *exec_delay = NULL, *event_timeout = NULL, *resolve_names = NULL; int r; - r = parse_env_file(NULL, "/etc/udev/udev.conf", NEWLINE, + r = parse_env_file(NULL, "/etc/udev/udev.conf", "udev_log", &log_val, "children_max", &children_max, "exec_delay", &exec_delay, diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index cabaef6ab8..8719ec26bb 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -55,7 +55,7 @@ static void test_parse_env_file(void) { fflush(f); fclose(f); - r = load_env_file(NULL, t, NULL, &a); + r = load_env_file(NULL, t, &a); assert_se(r >= 0); STRV_FOREACH(i, a) @@ -82,7 +82,7 @@ static void test_parse_env_file(void) { } r = parse_env_file( - NULL, t, NULL, + NULL, t, "one", &one, "two", &two, "three", &three, @@ -128,7 +128,7 @@ static void test_parse_env_file(void) { r = write_env_file(p, a); assert_se(r >= 0); - r = load_env_file(NULL, p, NULL, &b); + r = load_env_file(NULL, p, &b); assert_se(r >= 0); } @@ -157,7 +157,7 @@ static void test_parse_multiline_env_file(void) { fflush(f); fclose(f); - r = load_env_file(NULL, t, NULL, &a); + r = load_env_file(NULL, t, &a); assert_se(r >= 0); STRV_FOREACH(i, a) @@ -176,7 +176,7 @@ static void test_parse_multiline_env_file(void) { r = write_env_file(p, a); assert_se(r >= 0); - r = load_env_file(NULL, p, NULL, &b); + r = load_env_file(NULL, p, &b); assert_se(r >= 0); } @@ -467,7 +467,7 @@ static void test_load_env_file_pairs(void) { f = fdopen(fd, "r"); assert_se(f); - r = load_env_file_pairs(f, fn, NULL, &l); + r = load_env_file_pairs(f, fn, &l); assert_se(r >= 0); assert_se(strv_length(l) == 14); diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c index fe6da4fe2d..493ca50220 100644 --- a/src/test/test-unit-file.c +++ b/src/test/test-unit-file.c @@ -531,7 +531,7 @@ static void test_load_env_file_1(void) { assert_se(fd >= 0); assert_se(write(fd, env_file_1, sizeof(env_file_1)) == sizeof(env_file_1)); - r = load_env_file(NULL, name, NULL, &data); + r = load_env_file(NULL, name, &data); assert_se(r == 0); assert_se(streq(data[0], "a=a")); assert_se(streq(data[1], "b=bc")); @@ -553,7 +553,7 @@ static void test_load_env_file_2(void) { assert_se(fd >= 0); assert_se(write(fd, env_file_2, sizeof(env_file_2)) == sizeof(env_file_2)); - r = load_env_file(NULL, name, NULL, &data); + r = load_env_file(NULL, name, &data); assert_se(r == 0); assert_se(streq(data[0], "a=a")); assert_se(data[1] == NULL); @@ -570,7 +570,7 @@ static void test_load_env_file_3(void) { assert_se(fd >= 0); assert_se(write(fd, env_file_3, sizeof(env_file_3)) == sizeof(env_file_3)); - r = load_env_file(NULL, name, NULL, &data); + r = load_env_file(NULL, name, &data); assert_se(r == 0); assert_se(data == NULL); } @@ -585,7 +585,7 @@ static void test_load_env_file_4(void) { assert_se(fd >= 0); assert_se(write(fd, env_file_4, sizeof(env_file_4)) == sizeof(env_file_4)); - r = load_env_file(NULL, name, NULL, &data); + r = load_env_file(NULL, name, &data); assert_se(r == 0); assert_se(streq(data[0], "HWMON_MODULES=coretemp f71882fg")); assert_se(streq(data[1], "MODULE_0=coretemp")); @@ -604,7 +604,7 @@ static void test_load_env_file_5(void) { assert_se(fd >= 0); assert_se(write(fd, env_file_5, sizeof(env_file_5)) == sizeof(env_file_5)); - r = load_env_file(NULL, name, NULL, &data); + r = load_env_file(NULL, name, &data); assert_se(r == 0); assert_se(streq(data[0], "a=")); assert_se(streq(data[1], "b=")); diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index dc409eef7e..9917729427 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -418,7 +418,7 @@ int main(int argc, char **argv) { utf8 = is_locale_utf8(); - r = parse_env_file(NULL, "/etc/vconsole.conf", NEWLINE, + r = parse_env_file(NULL, "/etc/vconsole.conf", "KEYMAP", &vc_keymap, "KEYMAP_TOGGLE", &vc_keymap_toggle, "FONT", &vc_font, From 608eea8ea0ad89cea964237b732de230c8b11970 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 14:06:22 +0100 Subject: [PATCH 13/18] localed: be more careful with the used types --- src/locale/localed.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/locale/localed.c b/src/locale/localed.c index 01bb5a74c2..043fffaccb 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -33,7 +33,8 @@ static int locale_update_system_manager(Context *c, sd_bus *bus) { _cleanup_strv_free_ char **l_set = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; sd_bus_error error = SD_BUS_ERROR_NULL; - unsigned c_set, c_unset, p; + size_t c_set, c_unset; + LocaleVariable p; int r; assert(bus); From 13df9c398d60e441a65b11ada491f750947649bf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 14:18:03 +0100 Subject: [PATCH 14/18] fileio: automatically add NULL sentinel to parse_env_file() Let's modernize things a bit. --- src/basic/fileio.c | 2 +- src/basic/fileio.h | 3 +- src/basic/util.c | 4 +- src/core/locale-setup.c | 4 +- src/hostname/hostnamed.c | 3 +- src/journal-remote/journal-upload.c | 5 +-- src/journal/journald-stream.c | 3 +- src/journal/sd-journal.c | 4 +- src/libsystemd-network/sd-dhcp-lease.c | 3 +- src/libsystemd/sd-login/sd-login.c | 53 ++++++++++---------------- src/libsystemd/sd-network/sd-network.c | 10 ++--- src/locale/keymap-util.c | 6 +-- src/login/logind-inhibit.c | 3 +- src/login/logind-session.c | 3 +- src/login/logind-user.c | 3 +- src/machine/machine.c | 3 +- src/network/networkd-link.c | 3 +- src/network/networkd-lldp-tx.c | 2 +- src/portable/portablectl.c | 3 +- src/resolve/resolved-link.c | 3 +- src/shared/cgroup-show.c | 2 +- src/shared/condition.c | 2 +- src/shared/udev-util.c | 3 +- src/test/test-fileio.c | 3 +- src/vconsole/vconsole-setup.c | 3 +- 25 files changed, 55 insertions(+), 81 deletions(-) diff --git a/src/basic/fileio.c b/src/basic/fileio.c index 45c0b4a840..6c8305c2f8 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -710,7 +710,7 @@ int parse_env_filev( return n_pushed; } -int parse_env_file( +int parse_env_file_sentinel( FILE *f, const char *fname, ...) { diff --git a/src/basic/fileio.h b/src/basic/fileio.h index 66d9582ee7..8be593512d 100644 --- a/src/basic/fileio.h +++ b/src/basic/fileio.h @@ -43,7 +43,8 @@ int read_full_stream(FILE *f, char **contents, size_t *size); int verify_file(const char *fn, const char *blob, bool accept_extra_nl); int parse_env_filev(FILE *f, const char *fname, va_list ap); -int parse_env_file(FILE *f, const char *fname, ...) _sentinel_; +int parse_env_file_sentinel(FILE *f, const char *fname, ...) _sentinel_; +#define parse_env_file(f, fname, ...) parse_env_file_sentinel(f, fname, __VA_ARGS__, NULL) int load_env_file(FILE *f, const char *fname, char ***l); int load_env_file_pairs(FILE *f, const char *fname, char ***l); diff --git a/src/basic/util.c b/src/basic/util.c index b860753756..cd75529cfe 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -248,7 +248,9 @@ int container_get_leader(const char *machine, pid_t *pid) { return -EINVAL; p = strjoina("/run/systemd/machines/", machine); - r = parse_env_file(NULL, p, "LEADER", &s, "CLASS", &class, NULL); + r = parse_env_file(NULL, p, + "LEADER", &s, + "CLASS", &class); if (r == -ENOENT) return -EHOSTDOWN; if (r < 0) diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c index e13f21f90f..64fddca48c 100644 --- a/src/core/locale-setup.c +++ b/src/core/locale-setup.c @@ -54,9 +54,7 @@ int locale_setup(char ***environment) { "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], - "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], - NULL); - + "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION]); if (r < 0 && r != -ENOENT) log_warning_errno(r, "Failed to read /etc/locale.conf: %m"); } diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index b8facaf47d..4cbf2bde8b 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -94,8 +94,7 @@ static int context_read_data(Context *c) { "ICON_NAME", &c->data[PROP_ICON_NAME], "CHASSIS", &c->data[PROP_CHASSIS], "DEPLOYMENT", &c->data[PROP_DEPLOYMENT], - "LOCATION", &c->data[PROP_LOCATION], - NULL); + "LOCATION", &c->data[PROP_LOCATION]); if (r < 0 && r != -ENOENT) return r; diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c index 0fa915f4c3..b91d520cf0 100644 --- a/src/journal-remote/journal-upload.c +++ b/src/journal-remote/journal-upload.c @@ -149,10 +149,7 @@ static int load_cursor_state(Uploader *u) { if (!u->state_file) return 0; - r = parse_env_file(NULL, u->state_file, - "LAST_CURSOR", &u->last_cursor, - NULL); - + r = parse_env_file(NULL, u->state_file, "LAST_CURSOR", &u->last_cursor); if (r == -ENOENT) log_debug("State file %s is not present.", u->state_file); else if (r < 0) diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c index ca102010bc..81aa7bd99f 100644 --- a/src/journal/journald-stream.c +++ b/src/journal/journald-stream.c @@ -659,8 +659,7 @@ static int stdout_stream_load(StdoutStream *stream, const char *fname) { "FORWARD_TO_CONSOLE", &forward_to_console, "IDENTIFIER", &stream->identifier, "UNIT", &stream->unit_id, - "STREAM_ID", &stream_id, - NULL); + "STREAM_ID", &stream_id); if (r < 0) return log_error_errno(r, "Failed to read: %s", stream->state_file); diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index dd556d01d6..1edabbde72 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1888,7 +1888,9 @@ _public_ int sd_journal_open_container(sd_journal **ret, const char *machine, in assert_return(machine_name_is_valid(machine), -EINVAL); p = strjoina("/run/systemd/machines/", machine); - r = parse_env_file(NULL, p, "ROOT", &root, "CLASS", &class, NULL); + r = parse_env_file(NULL, p, + "ROOT", &root, + "CLASS", &class); if (r == -ENOENT) return -EHOSTDOWN; if (r < 0) diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 8fe468d468..a90c01d7db 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -1067,8 +1067,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { "OPTION_251", &options[27], "OPTION_252", &options[28], "OPTION_253", &options[29], - "OPTION_254", &options[30], - NULL); + "OPTION_254", &options[30]); if (r < 0) return r; diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index b5ef781b40..e048d2ce18 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -258,8 +258,7 @@ static int file_of_uid(uid_t uid, char **p) { } _public_ int sd_uid_get_state(uid_t uid, char**state) { - _cleanup_free_ char *p = NULL; - char *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; int r; assert_return(state, -EINVAL); @@ -268,24 +267,17 @@ _public_ int sd_uid_get_state(uid_t uid, char**state) { if (r < 0) return r; - r = parse_env_file(NULL, p, "STATE", &s, NULL); + r = parse_env_file(NULL, p, "STATE", &s); if (r == -ENOENT) { - free(s); - s = strdup("offline"); - if (!s) - return -ENOMEM; - - } - else if (r < 0) { - free(s); + r = free_and_strdup(&s, "offline"); + if (r < 0) + return r; + } else if (r < 0) return r; - } - if (isempty(s)) { - free(s); + else if (isempty(s)) return -EIO; - } - *state = s; + *state = TAKE_PTR(s); return 0; } @@ -299,7 +291,7 @@ _public_ int sd_uid_get_display(uid_t uid, char **session) { if (r < 0) return r; - r = parse_env_file(NULL, p, "DISPLAY", &s, NULL); + r = parse_env_file(NULL, p, "DISPLAY", &s); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -354,7 +346,7 @@ _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) variable = require_active ? "ACTIVE_UID" : "UIDS"; - r = parse_env_file(NULL, p, variable, &s, NULL); + r = parse_env_file(NULL, p, variable, &s); if (r == -ENOENT) return 0; if (r < 0) @@ -383,7 +375,7 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { if (r < 0) return r; - r = parse_env_file(NULL, p, variable, &s, NULL); + r = parse_env_file(NULL, p, variable, &s); if (r == -ENOENT || (r >= 0 && isempty(s))) { if (array) *array = NULL; @@ -461,7 +453,7 @@ _public_ int sd_session_is_active(const char *session) { if (r < 0) return r; - r = parse_env_file(NULL, p, "ACTIVE", &s, NULL); + r = parse_env_file(NULL, p, "ACTIVE", &s); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -480,7 +472,7 @@ _public_ int sd_session_is_remote(const char *session) { if (r < 0) return r; - r = parse_env_file(NULL, p, "REMOTE", &s, NULL); + r = parse_env_file(NULL, p, "REMOTE", &s); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -501,7 +493,7 @@ _public_ int sd_session_get_state(const char *session, char **state) { if (r < 0) return r; - r = parse_env_file(NULL, p, "STATE", &s, NULL); + r = parse_env_file(NULL, p, "STATE", &s); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -524,7 +516,7 @@ _public_ int sd_session_get_uid(const char *session, uid_t *uid) { if (r < 0) return r; - r = parse_env_file(NULL, p, "UID", &s, NULL); + r = parse_env_file(NULL, p, "UID", &s); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -546,7 +538,7 @@ static int session_get_string(const char *session, const char *field, char **val if (r < 0) return r; - r = parse_env_file(NULL, p, field, &s, NULL); + r = parse_env_file(NULL, p, field, &s); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -640,8 +632,7 @@ _public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { r = parse_env_file(NULL, p, "ACTIVE", &s, - "ACTIVE_UID", &t, - NULL); + "ACTIVE_UID", &t); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -678,8 +669,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui r = parse_env_file(NULL, p, "SESSIONS", &s, - "UIDS", &t, - NULL); + "UIDS", &t); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -746,8 +736,7 @@ static int seat_get_can(const char *seat, const char *variable) { return r; r = parse_env_file(NULL, p, - variable, &s, - NULL); + variable, &s); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -901,7 +890,7 @@ _public_ int sd_machine_get_class(const char *machine, char **class) { return -EINVAL; p = strjoina("/run/systemd/machines/", machine); - r = parse_env_file(NULL, p, "CLASS", &c, NULL); + r = parse_env_file(NULL, p, "CLASS", &c); if (r == -ENOENT) return -ENXIO; if (r < 0) @@ -925,7 +914,7 @@ _public_ int sd_machine_get_ifindices(const char *machine, int **ifindices) { assert_return(ifindices, -EINVAL); p = strjoina("/run/systemd/machines/", machine); - r = parse_env_file(NULL, p, "NETIF", &netif, NULL); + r = parse_env_file(NULL, p, "NETIF", &netif); if (r == -ENOENT) return -ENXIO; if (r < 0) diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index 3d411dc5a4..fc66d41b63 100644 --- a/src/libsystemd/sd-network/sd-network.c +++ b/src/libsystemd/sd-network/sd-network.c @@ -24,7 +24,7 @@ _public_ int sd_network_get_operational_state(char **state) { assert_return(state, -EINVAL); - r = parse_env_file(NULL, "/run/systemd/netif/state", "OPER_STATE", &s, NULL); + r = parse_env_file(NULL, "/run/systemd/netif/state", "OPER_STATE", &s); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -44,7 +44,7 @@ static int network_get_strv(const char *key, char ***ret) { assert_return(ret, -EINVAL); - r = parse_env_file(NULL, "/run/systemd/netif/state", key, &s, NULL); + r = parse_env_file(NULL, "/run/systemd/netif/state", key, &s); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -92,7 +92,7 @@ static int network_link_get_string(int ifindex, const char *field, char **ret) { xsprintf(path, "/run/systemd/netif/links/%i", ifindex); - r = parse_env_file(NULL, path, field, &s, NULL); + r = parse_env_file(NULL, path, field, &s); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -115,7 +115,7 @@ static int network_link_get_strv(int ifindex, const char *key, char ***ret) { assert_return(ret, -EINVAL); xsprintf(path, "/run/systemd/netif/links/%i", ifindex); - r = parse_env_file(NULL, path, key, &s, NULL); + r = parse_env_file(NULL, path, key, &s); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -216,7 +216,7 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) { assert_return(ret, -EINVAL); xsprintf(path, "/run/systemd/netif/links/%i", ifindex); - r = parse_env_file(NULL, path, key, &s, NULL); + r = parse_env_file(NULL, path, key, &s); if (r == -ENOENT) return -ENODATA; if (r < 0) diff --git a/src/locale/keymap-util.c b/src/locale/keymap-util.c index dadeef1f25..18668a99ab 100644 --- a/src/locale/keymap-util.c +++ b/src/locale/keymap-util.c @@ -128,8 +128,7 @@ int locale_read_data(Context *c, sd_bus_message *m) { "LC_ADDRESS", &c->locale[VARIABLE_LC_ADDRESS], "LC_TELEPHONE", &c->locale[VARIABLE_LC_TELEPHONE], "LC_MEASUREMENT", &c->locale[VARIABLE_LC_MEASUREMENT], - "LC_IDENTIFICATION", &c->locale[VARIABLE_LC_IDENTIFICATION], - NULL); + "LC_IDENTIFICATION", &c->locale[VARIABLE_LC_IDENTIFICATION]); if (r < 0) return r; } else { @@ -188,8 +187,7 @@ int vconsole_read_data(Context *c, sd_bus_message *m) { r = parse_env_file(NULL, "/etc/vconsole.conf", "KEYMAP", &c->vc_keymap, - "KEYMAP_TOGGLE", &c->vc_keymap_toggle, - NULL); + "KEYMAP_TOGGLE", &c->vc_keymap_toggle); if (r < 0) return r; diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c index c45c9fd8c3..71eea72da5 100644 --- a/src/login/logind-inhibit.c +++ b/src/login/logind-inhibit.c @@ -200,8 +200,7 @@ int inhibitor_load(Inhibitor *i) { "WHO", &who, "WHY", &why, "MODE", &mode, - "FIFO", &i->fifo_path, - NULL); + "FIFO", &i->fifo_path); if (r < 0) return r; diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 0168fb0352..90af6bf070 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -431,8 +431,7 @@ int session_load(Session *s) { "CONTROLLER", &controller, "ACTIVE", &active, "DEVICES", &devices, - "IS_DISPLAY", &is_display, - NULL); + "IS_DISPLAY", &is_display); if (r < 0) return log_error_errno(r, "Failed to read %s: %m", s->state_file); diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 78cfe35a40..8d82944618 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -317,8 +317,7 @@ int user_load(User *u) { "STOPPING", &stopping, "REALTIME", &realtime, "MONOTONIC", &monotonic, - "LAST_SESSION_TIMESTAMP", &last_session_timestamp, - NULL); + "LAST_SESSION_TIMESTAMP", &last_session_timestamp); if (r == -ENOENT) return 0; if (r < 0) diff --git a/src/machine/machine.c b/src/machine/machine.c index 75fa94252d..e114541b3f 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -261,8 +261,7 @@ int machine_load(Machine *m) { "CLASS", &class, "REALTIME", &realtime, "MONOTONIC", &monotonic, - "NETIF", &netif, - NULL); + "NETIF", &netif); if (r < 0) { if (r == -ENOENT) return 0; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 8a62e07278..4af1a559b2 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -3215,8 +3215,7 @@ static int link_load(Link *link) { "ADDRESSES", &addresses, "ROUTES", &routes, "DHCP4_ADDRESS", &dhcp4_address, - "IPV4LL_ADDRESS", &ipv4ll_address, - NULL); + "IPV4LL_ADDRESS", &ipv4ll_address); if (r < 0 && r != -ENOENT) return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file); diff --git a/src/network/networkd-lldp-tx.c b/src/network/networkd-lldp-tx.c index fa36e94a7c..de39568eca 100644 --- a/src/network/networkd-lldp-tx.c +++ b/src/network/networkd-lldp-tx.c @@ -244,7 +244,7 @@ static int link_send_lldp(Link *link) { return r; (void) gethostname_strict(&hostname); - (void) parse_env_file(NULL, "/etc/machine-info", "PRETTY_HOSTNAME", &pretty_hostname, NULL); + (void) parse_env_file(NULL, "/etc/machine-info", "PRETTY_HOSTNAME", &pretty_hostname); assert_cc(LLDP_TX_INTERVAL_USEC * LLDP_TX_HOLD + 1 <= (UINT16_MAX - 1) * USEC_PER_SEC); ttl = DIV_ROUND_UP(LLDP_TX_INTERVAL_USEC * LLDP_TX_HOLD + 1, USEC_PER_SEC); diff --git a/src/portable/portablectl.c b/src/portable/portablectl.c index 1b77e4bcb0..1ce3f72ecb 100644 --- a/src/portable/portablectl.c +++ b/src/portable/portablectl.c @@ -281,8 +281,7 @@ static int inspect_image(int argc, char *argv[], void *userdata) { r = parse_env_file(f, "/etc/os-release", "PORTABLE_PRETTY_NAME", &pretty_portable, - "PRETTY_NAME", &pretty_os, - NULL); + "PRETTY_NAME", &pretty_os); if (r < 0) return log_error_errno(r, "Failed to parse /etc/os-release: %m"); diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index 54bb805475..0ae3b40018 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -1263,8 +1263,7 @@ int link_load_user(Link *l) { "DNSSEC", &dnssec, "SERVERS", &servers, "DOMAINS", &domains, - "NTAS", &ntas, - NULL); + "NTAS", &ntas); if (r == -ENOENT) return 0; if (r < 0) diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c index b43a7879ec..36a611c3c1 100644 --- a/src/shared/cgroup-show.c +++ b/src/shared/cgroup-show.c @@ -339,7 +339,7 @@ int show_cgroup_get_path_and_warn( const char *m; m = strjoina("/run/systemd/machines/", machine); - r = parse_env_file(NULL, m, "SCOPE", &unit, NULL); + r = parse_env_file(NULL, m, "SCOPE", &unit); if (r < 0) return log_error_errno(r, "Failed to load machine data: %m"); diff --git a/src/shared/condition.c b/src/shared/condition.c index 852bdda082..ecc32beadf 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -471,7 +471,7 @@ static int condition_test_needs_update(Condition *c) { uint64_t timestamp; int r; - r = parse_env_file(NULL, p, "TIMESTAMP_NSEC", ×tamp_str, NULL); + r = parse_env_file(NULL, p, "TIMESTAMP_NSEC", ×tamp_str); if (r < 0) { log_error_errno(r, "Failed to parse timestamp file '%s', using mtime: %m", p); return true; diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c index f847269e82..e0c198eb6a 100644 --- a/src/shared/udev-util.c +++ b/src/shared/udev-util.c @@ -33,8 +33,7 @@ int udev_parse_config_full( "udev_log", &log_val, "children_max", &children_max, "exec_delay", &exec_delay, - "event_timeout", &event_timeout, - NULL); + "event_timeout", &event_timeout); if (r == -ENOENT) return 0; if (r < 0) diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index 8719ec26bb..ac86d6d588 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -92,8 +92,7 @@ static void test_parse_env_file(void) { "seven", &seven, "eight", &eight, "export nine", &nine, - "ten", &ten, - NULL); + "ten", &ten); assert_se(r >= 0); diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index 9917729427..41059bae04 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -423,8 +423,7 @@ int main(int argc, char **argv) { "KEYMAP_TOGGLE", &vc_keymap_toggle, "FONT", &vc_font, "FONT_MAP", &vc_font_map, - "FONT_UNIMAP", &vc_font_unimap, - NULL); + "FONT_UNIMAP", &vc_font_unimap); if (r < 0 && r != -ENOENT) log_warning_errno(r, "Failed to read /etc/vconsole.conf: %m"); From e6755a33509f425463ddbbf99839ba3ae6979216 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 16:50:58 +0100 Subject: [PATCH 15/18] locale-util: introduce common helper locale_variables_free() for freeing locale variable arrays --- src/basic/locale-util.c | 10 ++++++++++ src/basic/locale-util.h | 5 +++++ src/core/locale-setup.c | 34 ++++++++++------------------------ src/locale/localectl.c | 11 ++++------- src/locale/localed.c | 13 +++---------- 5 files changed, 32 insertions(+), 41 deletions(-) diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c index 8b89bd0024..9ad51a1972 100644 --- a/src/basic/locale-util.c +++ b/src/basic/locale-util.c @@ -389,6 +389,16 @@ const char *special_glyph(SpecialGlyph code) { return draw_table[is_locale_utf8()][code]; } +void locale_variables_free(char*l[_VARIABLE_LC_MAX]) { + LocaleVariable i; + + if (!l) + return; + + for (i = 0; i < _VARIABLE_LC_MAX; i++) + l[i] = mfree(l[i]); +} + static const char * const locale_variable_table[_VARIABLE_LC_MAX] = { [VARIABLE_LANG] = "LANG", [VARIABLE_LANGUAGE] = "LANGUAGE", diff --git a/src/basic/locale-util.h b/src/basic/locale-util.h index 7762254940..14beece6d8 100644 --- a/src/basic/locale-util.h +++ b/src/basic/locale-util.h @@ -66,3 +66,8 @@ static inline void freelocalep(locale_t *p) { freelocale(*p); } + +void locale_variables_free(char* l[_VARIABLE_LC_MAX]); +static inline void locale_variables_freep(char*(*l)[_VARIABLE_LC_MAX]) { + locale_variables_free(*l); +} diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c index 64fddca48c..fff3a798c4 100644 --- a/src/core/locale-setup.c +++ b/src/core/locale-setup.c @@ -15,7 +15,7 @@ #include "virt.h" int locale_setup(char ***environment) { - char *variables[_VARIABLE_LC_MAX] = {}; + _cleanup_(locale_variables_freep) char *variables[_VARIABLE_LC_MAX] = {}; _cleanup_strv_free_ char **add = NULL; LocaleVariable i; int r; @@ -66,25 +66,19 @@ int locale_setup(char ***environment) { continue; s = strjoin(locale_variable_to_string(i), "=", variables[i]); - if (!s) { - r = -ENOMEM; - goto finish; - } + if (!s) + return -ENOMEM; - if (strv_consume(&add, s) < 0) { - r = -ENOMEM; - goto finish; - } + if (strv_consume(&add, s) < 0) + return -ENOMEM; } if (strv_isempty(add)) { /* If no locale is configured then default to C.UTF-8. */ add = strv_new("LANG=C.UTF-8"); - if (!add) { - r = -ENOMEM; - goto finish; - } + if (!add) + return -ENOMEM; } if (strv_isempty(*environment)) @@ -93,19 +87,11 @@ int locale_setup(char ***environment) { char **merged; merged = strv_env_merge(2, *environment, add); - if (!merged) { - r = -ENOMEM; - goto finish; - } + if (!merged) + return -ENOMEM; strv_free_and_replace(*environment, merged); } - r = 0; - -finish: - for (i = 0; i < _VARIABLE_LC_MAX; i++) - free(variables[i]); - - return r; + return 0; } diff --git a/src/locale/localectl.c b/src/locale/localectl.c index c8278a383d..75e7a55676 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -49,10 +49,10 @@ static void status_info_clear(StatusInfo *info) { } static void print_overridden_variables(void) { - int r; - char *variables[_VARIABLE_LC_MAX] = {}; - LocaleVariable j; + _cleanup_(locale_variables_freep) char *variables[_VARIABLE_LC_MAX] = {}; bool print_warning = true; + LocaleVariable j; + int r; if (arg_transport != BUS_TRANSPORT_LOCAL) return; @@ -75,7 +75,7 @@ static void print_overridden_variables(void) { "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION]); if (r < 0 && r != -ENOENT) { log_warning_errno(r, "Failed to read /proc/cmdline: %m"); - goto finish; + return; } for (j = 0; j < _VARIABLE_LC_MAX; j++) @@ -88,9 +88,6 @@ static void print_overridden_variables(void) { } else log_warning(" %s=%s", locale_variable_to_string(j), variables[j]); } - finish: - for (j = 0; j < _VARIABLE_LC_MAX; j++) - free(variables[j]); } static void print_status_info(StatusInfo *i) { diff --git a/src/locale/localed.c b/src/locale/localed.c index 043fffaccb..21d1ded65c 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -255,20 +255,13 @@ static int property_get_xkb( return -EINVAL; } -static void locale_free(char ***l) { - int p; - - for (p = 0; p < _VARIABLE_LC_MAX; p++) - (*l)[p] = mfree((*l)[p]); -} - static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *error) { - Context *c = userdata; + _cleanup_(locale_variables_freep) char *new_locale[_VARIABLE_LC_MAX] = {}; _cleanup_strv_free_ char **settings = NULL, **l = NULL; - char *new_locale[_VARIABLE_LC_MAX] = {}, **i; - _cleanup_(locale_free) _unused_ char **dummy = new_locale; + Context *c = userdata; bool modified = false; int interactive, p, r; + char **i; assert(m); assert(c); From 8a7cf15733009bbc6a5af37ce71214f34aeea2d5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 13:19:07 +0100 Subject: [PATCH 16/18] update TODO --- TODO | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 34db15c177..86db6fcd47 100644 --- a/TODO +++ b/TODO @@ -28,12 +28,11 @@ Features: * systemd-gpt-auto: if we find the root dir mounted read-only and the gpt flag doesn't say so generate job that remounts it writable +* when no locale is configured, default to UEFI's PlatformLang variable + * When logind.conf contains HandleLidSwitch=suspend-then-hibernate and we can't hibernate because the swap partition isn't large enough, still suspend -* Now that C.UTF-8 is standardized in glibc, default to it if locale.conf - doesn't set anything otherwise - * bootctl: implement Type #2 boot loader entry discovery * bootctl,sd-boot: actually honour the "architecture" key From 4f7dc24f8bbb3c312a46dc8d8f25658d02d47bfe Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Nov 2018 17:00:32 +0100 Subject: [PATCH 17/18] update NEWS --- NEWS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NEWS b/NEWS index d378b08b70..d9f4e2be94 100644 --- a/NEWS +++ b/NEWS @@ -63,6 +63,13 @@ CHANGES WITH 240 in spe: has been added to revert this change in behaviour, which might be an option for systems that turn off memcg in the kernel. + * When no /etc/locale.conf file exists (and hence no locale settings + are in place), systemd will now use the "C.UTF-8" locale by default, + and set LANG= to it. This locale is supported by various + distributions including Fedora, with clear indications that upstream + glibc is going to make it available too. This locale enables UTF-8 + mode by default, which appears appropriate for 2018. + CHANGES WITH 239: * NETWORK INTERFACE DEVICE NAMING CHANGES: systemd-udevd's "net_id" From 483d713e0a39ecfe028ec49b9d9b0e67658ea79f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 14 Nov 2018 17:22:18 +0100 Subject: [PATCH 18/18] tests: add some tests for cmdline args containing spaces --- src/test/test-proc-cmdline.c | 37 +++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/test/test-proc-cmdline.c b/src/test/test-proc-cmdline.c index 3edc75f554..00cc2f48aa 100644 --- a/src/test/test-proc-cmdline.c +++ b/src/test/test-proc-cmdline.c @@ -28,15 +28,22 @@ static void test_proc_cmdline_parse(void) { static void test_proc_cmdline_override(void) { log_info("/* %s */", __func__); - assert_se(putenv((char*) "SYSTEMD_PROC_CMDLINE=foo_bar=quux wuff-piep=tuet zumm") == 0); + assert_se(putenv((char*) "SYSTEMD_PROC_CMDLINE=foo_bar=quux wuff-piep=tuet zumm some_arg_with_space='foo bar' and_one_more=\"zzz aaa\"") == 0); /* Test if the override works */ _cleanup_free_ char *line = NULL, *value = NULL; assert_se(proc_cmdline(&line) >= 0); /* Test if parsing makes uses of the override */ - assert_se(streq(line, "foo_bar=quux wuff-piep=tuet zumm")); + assert_se(streq(line, "foo_bar=quux wuff-piep=tuet zumm some_arg_with_space='foo bar' and_one_more=\"zzz aaa\"")); assert_se(proc_cmdline_get_key("foo_bar", 0, &value) > 0 && streq_ptr(value, "quux")); + value = mfree(value); + + assert_se(proc_cmdline_get_key("some_arg_with_space", 0, &value) > 0 && streq_ptr(value, "foo bar")); + value = mfree(value); + + assert_se(proc_cmdline_get_key("and_one_more", 0, &value) > 0 && streq_ptr(value, "zzz aaa")); + value = mfree(value); } static int parse_item_given(const char *key, const char *value, void *data) { @@ -50,6 +57,10 @@ static int parse_item_given(const char *key, const char *value, void *data) { assert_se(streq(value, "quux")); else if (streq(key, "wuff-piep")) assert_se(streq(value, "tuet ")); + else if (streq(key, "space")) + assert_se(streq(value, "x y z")); + else if (streq(key, "miepf")) + assert_se(streq(value, "uuu")); else if (in_initrd() && *strip && streq(key, "zumm")) assert_se(!value); else if (in_initrd() && !*strip && streq(key, "rd.zumm")) @@ -67,13 +78,12 @@ static void test_proc_cmdline_given(bool flip_initrd) { in_initrd_force(!in_initrd()); bool t = true, f = false; - assert_se(proc_cmdline_parse_given("foo_bar=quux wuff-piep=\"tuet \" rd.zumm", + assert_se(proc_cmdline_parse_given("foo_bar=quux wuff-piep=\"tuet \" rd.zumm space='x y z' miepf=\"uuu\"", parse_item_given, &t, PROC_CMDLINE_STRIP_RD_PREFIX) >= 0); - assert_se(proc_cmdline_parse_given("foo_bar=quux wuff-piep=\"tuet \" rd.zumm", + assert_se(proc_cmdline_parse_given("foo_bar=quux wuff-piep=\"tuet \" rd.zumm space='x y z' miepf=\"uuu\"", parse_item_given, &f, 0) >= 0); - if (flip_initrd) in_initrd_force(!in_initrd()); } @@ -82,7 +92,7 @@ static void test_proc_cmdline_get_key(void) { _cleanup_free_ char *value = NULL; log_info("/* %s */", __func__); - assert_se(putenv((char*) "SYSTEMD_PROC_CMDLINE=foo_bar=quux wuff-piep=tuet zumm") == 0); + assert_se(putenv((char*) "SYSTEMD_PROC_CMDLINE=foo_bar=quux wuff-piep=tuet zumm spaaace='ö ü ß' ticks=\"''\"") == 0); assert_se(proc_cmdline_get_key("", 0, &value) == -EINVAL); assert_se(proc_cmdline_get_key("abc", 0, NULL) == 0); @@ -114,6 +124,11 @@ static void test_proc_cmdline_get_key(void) { assert_se(proc_cmdline_get_key("zumm", 0, &value) == 0 && value == NULL); assert_se(proc_cmdline_get_key("zumm", PROC_CMDLINE_VALUE_OPTIONAL, &value) > 0 && value == NULL); assert_se(proc_cmdline_get_key("zumm", 0, NULL) > 0); + + assert_se(proc_cmdline_get_key("spaaace", 0, &value) > 0 && streq_ptr(value, "ö ü ß")); + value = mfree(value); + + assert_se(proc_cmdline_get_key("ticks", 0, &value) > 0 && streq_ptr(value, "''")); } static void test_proc_cmdline_get_bool(void) { @@ -136,21 +151,25 @@ static void test_proc_cmdline_get_bool(void) { } static void test_proc_cmdline_get_key_many(void) { - _cleanup_free_ char *value1 = NULL, *value2 = NULL, *value3 = NULL, *value4 = NULL; + _cleanup_free_ char *value1 = NULL, *value2 = NULL, *value3 = NULL, *value4 = NULL, *value5 = NULL, *value6 = NULL; log_info("/* %s */", __func__); - assert_se(putenv((char*) "SYSTEMD_PROC_CMDLINE=foo_bar=quux wuff-piep=tuet zumm") == 0); + assert_se(putenv((char*) "SYSTEMD_PROC_CMDLINE=foo_bar=quux wuff-piep=tuet zumm SPACE='one two' doubleticks=\" aaa aaa \"") == 0); assert_se(proc_cmdline_get_key_many(0, "wuff-piep", &value3, "foo_bar", &value1, "idontexist", &value2, - "zumm", &value4) == 2); + "zumm", &value4, + "SPACE", &value5, + "doubleticks", &value6) == 4); assert_se(streq_ptr(value1, "quux")); assert_se(!value2); assert_se(streq_ptr(value3, "tuet")); assert_se(!value4); + assert_se(streq_ptr(value5, "one two")); + assert_se(streq_ptr(value6, " aaa aaa ")); } static void test_proc_cmdline_key_streq(void) {