diff --git a/src/basic/process-util.c b/src/basic/process-util.c index fd708eed98..1b8e663efe 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -208,7 +208,10 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags if (full < 0) return full; - if (flags & PROCESS_CMDLINE_QUOTE) { + if (flags & (PROCESS_CMDLINE_QUOTE | PROCESS_CMDLINE_QUOTE_POSIX)) { + ShellEscapeFlags shflags = SHELL_ESCAPE_EMPTY | + FLAGS_SET(flags, PROCESS_CMDLINE_QUOTE_POSIX) * SHELL_ESCAPE_POSIX; + assert(!(flags & PROCESS_CMDLINE_USE_LOCALE)); _cleanup_strv_free_ char **args = NULL; @@ -220,7 +223,7 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags for (size_t i = 0; args[i]; i++) { char *e; - e = shell_maybe_quote(args[i], SHELL_ESCAPE_EMPTY); + e = shell_maybe_quote(args[i], shflags); if (!e) return -ENOMEM; diff --git a/src/basic/process-util.h b/src/basic/process-util.h index 3121d82d3f..8ce6d60f39 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -36,6 +36,7 @@ typedef enum ProcessCmdlineFlags { PROCESS_CMDLINE_COMM_FALLBACK = 1 << 0, PROCESS_CMDLINE_USE_LOCALE = 1 << 1, PROCESS_CMDLINE_QUOTE = 1 << 2, + PROCESS_CMDLINE_QUOTE_POSIX = 1 << 3, } ProcessCmdlineFlags; int get_process_comm(pid_t pid, char **name); diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c index 957d23ffc5..f79df46d29 100644 --- a/src/test/test-process-util.c +++ b/src/test/test-process-util.c @@ -431,6 +431,7 @@ static void test_get_process_cmdline_harder(void) { #define CMDLINE1 "foo\0'bar'\0\"bar$\"\0x y z\0!``\0" #define EXPECT1 "foo \"'bar'\" \"\\\"bar\\$\\\"\" \"x y z\" \"!\\`\\`\" \"\"" +#define EXPECT1p "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``' \"\"" assert_se(lseek(fd, SEEK_SET, 0) == 0); assert_se(write(fd, CMDLINE1, sizeof CMDLINE1) == sizeof CMDLINE1); assert_se(ftruncate(fd, sizeof CMDLINE1) == 0); @@ -441,8 +442,15 @@ static void test_get_process_cmdline_harder(void) { assert_se(streq(line, EXPECT1)); line = mfree(line); + assert_se(get_process_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line) >= 0); + log_debug("got: ==%s==", line); + log_debug("exp: ==%s==", EXPECT1p); + assert_se(streq(line, EXPECT1p)); + line = mfree(line); + #define CMDLINE2 "foo\0\1\2\3\0\0" #define EXPECT2 "foo \"\\001\\002\\003\" \"\" \"\"" +#define EXPECT2p "foo $'\\001\\002\\003' \"\" \"\"" assert_se(lseek(fd, SEEK_SET, 0) == 0); assert_se(write(fd, CMDLINE2, sizeof CMDLINE2) == sizeof CMDLINE2); assert_se(ftruncate(fd, sizeof CMDLINE2) == 0); @@ -453,6 +461,12 @@ static void test_get_process_cmdline_harder(void) { assert_se(streq(line, EXPECT2)); line = mfree(line); + assert_se(get_process_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line) >= 0); + log_debug("got: ==%s==", line); + log_debug("exp: ==%s==", EXPECT2p); + assert_se(streq(line, EXPECT2p)); + line = mfree(line); + safe_close(fd); _exit(EXIT_SUCCESS); }