]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/process-util: add mode where posix shell escape is used for quoting
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 10 Mar 2021 23:10:02 +0000 (00:10 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 5 May 2021 11:59:23 +0000 (13:59 +0200)
The new flag is not used, except in tests, so no functional change yet.

This way, the command as shown can be copied-and-pasted into the shell
in more cases. For simple cases, shell quoting with "" is enough. But
$'' is needed when there are control characters in the command.

src/basic/process-util.c
src/basic/process-util.h
src/test/test-process-util.c

index fd708eed98a90f3f43bd8152b756a72b8b7fa4c3..1b8e663efea51456ef504b4516d722e13120f482 100644 (file)
@@ -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;
 
index 3121d82d3ff1d54d7a5e64f8dff73d7d490e42e9..8ce6d60f39b066330217ea7eecfd36df15a81dcb 100644 (file)
@@ -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);
index 957d23ffc54d317b30fbb6687156e9e7fe53bd91..f79df46d293341db0d4145a575eedc9ab25d2be3 100644 (file)
@@ -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);
 }