From 0745ce7565b37e2f7d7150c8c531524f0bd01dd1 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 28 Jun 2018 18:18:55 +0900 Subject: [PATCH 1/3] strv: make strv_split() accept empty string --- src/basic/strv.c | 4 ++++ src/test/test-strv.c | 26 +++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/basic/strv.c b/src/basic/strv.c index b3716233b5a62..abf3fc4c7bd9b 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -253,6 +253,10 @@ char **strv_split(const char *s, const char *separator) { assert(s); + s += strspn(s, separator); + if (isempty(s)) + return new0(char*, 1); + n = 0; FOREACH_WORD_SEPARATOR(word, l, s, separator, state) n++; diff --git a/src/test/test-strv.c b/src/test/test-strv.c index 1c192239a28fb..340b5628f9b8c 100644 --- a/src/test/test-strv.c +++ b/src/test/test-strv.c @@ -180,12 +180,31 @@ static void test_strv_split(void) { const char str[] = "one,two,three"; l = strv_split(str, ","); - assert_se(l); + STRV_FOREACH(s, l) + assert_se(streq(*s, input_table_multiple[i++])); - STRV_FOREACH(s, l) { + i = 0; + strv_free(l); + + l = strv_split(" one two\t three", WHITESPACE); + assert_se(l); + STRV_FOREACH(s, l) assert_se(streq(*s, input_table_multiple[i++])); - } +} + +static void test_strv_split_empty(void) { + _cleanup_strv_free_ char **l = NULL; + + l = strv_split("", WHITESPACE); + assert_se(l); + assert_se(strv_isempty(l)); + + strv_free(l); + l = strv_split(" ", WHITESPACE); + assert_se(l); + assert_se(strv_isempty(l)); + } static void test_strv_split_extract(void) { @@ -733,6 +752,7 @@ int main(int argc, char *argv[]) { test_invalid_unquote("'x'y'g"); test_strv_split(); + test_strv_split_empty(); test_strv_split_extract(); test_strv_split_newlines(); test_strv_split_nulstr(); From 43942e8055bb01890e725bd5f06855e48caa251e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 28 Jun 2018 18:21:39 +0900 Subject: [PATCH 2/3] pager: split $PAGER or $SYSTEMD_PAGER and use execvp() This makes pager_open() correctly handle e.g. PAGER=' ' or PAGER=' cat '. --- src/basic/pager.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/basic/pager.c b/src/basic/pager.c index f241261119257..7d698666e9cd3 100644 --- a/src/basic/pager.c +++ b/src/basic/pager.c @@ -43,6 +43,7 @@ _noreturn_ static void pager_fallback(void) { int pager_open(bool no_pager, bool jump_to_end) { _cleanup_close_pair_ int fd[2] = { -1, -1 }; + _cleanup_strv_free_ char **pager_args = NULL; const char *pager; int r; @@ -62,9 +63,15 @@ int pager_open(bool no_pager, bool jump_to_end) { if (!pager) pager = getenv("PAGER"); - /* If the pager is explicitly turned off, honour it */ - if (pager && STR_IN_SET(pager, "", "cat")) - return 0; + if (pager) { + pager_args = strv_split(pager, WHITESPACE); + if (!pager_args) + return -ENOMEM; + + /* If the pager is explicitly turned off, honour it */ + if (strv_isempty(pager_args) || strv_equal(pager_args, STRV_MAKE("cat"))) + return 0; + } /* Determine and cache number of columns/lines before we spawn the pager so that we get the value from the * actual tty */ @@ -104,10 +111,8 @@ int pager_open(bool no_pager, bool jump_to_end) { setenv("LESSCHARSET", less_charset, 1) < 0) _exit(EXIT_FAILURE); - if (pager) { - execlp(pager, pager, NULL); - execl("/bin/sh", "sh", "-c", pager, NULL); - } + if (pager_args) + execvp(pager_args[0], pager_args); /* Debian's alternatives command for pagers is * called 'pager'. Note that we do not call From 70d6e5bd991a733fda60700848fa5469bd518e03 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 28 Jun 2018 22:31:47 +0900 Subject: [PATCH 3/3] systemctl: make variable which stores environment variable constant --- src/systemctl/systemctl.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 9c6156237a21e..05e253f5808d5 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -6778,11 +6778,9 @@ static int run_editor(char **paths) { if (r < 0) return r; if (r == 0) { - const char **args; - char *editor, **editor_args = NULL; - char **tmp_path, **original_path, *p; - size_t n_editor_args = 0, i = 1; - size_t argc; + char **editor_args = NULL, **tmp_path, **original_path, *p; + size_t n_editor_args = 0, i = 1, argc; + const char **args, *editor; argc = strv_length(paths)/2 + 1;