diff --git a/src/org.gnome.Sysprof3.Service.xml b/src/org.gnome.Sysprof3.Service.xml index 1be4e137..d39f68c2 100644 --- a/src/org.gnome.Sysprof3.Service.xml +++ b/src/org.gnome.Sysprof3.Service.xml @@ -62,6 +62,7 @@ - pid: (int32): the process identifier, always included - cmdline: (string): Provides the command line + - comm: (string): Provide the comm, useful when cmdline is empty - maps: (string): Provide the contents of /proc/pid/maps - statm: (string): Provide the contents of /proc/pid/statm - mountinfo: (string): Provide the contents of/proc/pid/mountinfo diff --git a/src/sysprofd/ipc-service-impl.c b/src/sysprofd/ipc-service-impl.c index 961239c8..b1be1081 100644 --- a/src/sysprofd/ipc-service-impl.c +++ b/src/sysprofd/ipc-service-impl.c @@ -189,17 +189,76 @@ ipc_service_impl_g_authorize_method (GDBusInterfaceSkeleton *skeleton, return ret; } +static gboolean +needs_escape (const gchar *str) +{ + for (; *str; str++) + { + if (g_ascii_isspace (*str) || *str == '\'' || *str == '"') + return TRUE; + } + + return FALSE; +} + static void postprocess_cmdline (gchar **str, gsize len) { + g_autoptr(GPtrArray) parts = g_ptr_array_new_with_free_func (g_free); + g_autofree gchar *instr = NULL; + const gchar *begin = NULL; + + if (len == 0) + return; + + instr = *str; + + for (gsize i = 0; i < len; i++) + { + if (!begin && instr[i]) + { + begin = &instr[i]; + } + else if (begin && instr[i] == '\0') + { + if (needs_escape (begin)) + g_ptr_array_add (parts, g_shell_quote (begin)); + else + g_ptr_array_add (parts, g_strdup (begin)); + + begin = NULL; + } + } + + /* If the last byte was not \0, as can happen with prctl(), then we need + * to add it here manually. + */ + if (begin) + { + if (needs_escape (begin)) + g_ptr_array_add (parts, g_shell_quote (begin)); + else + g_ptr_array_add (parts, g_strdup (begin)); + } + + g_ptr_array_add (parts, NULL); + + *str = g_strjoinv (" ", (gchar **)parts->pdata); +} + +static void +postprocess_rstrip (gchar **str, + gsize len) +{ + g_strchomp (*str); } static void add_pid_proc_file_to (gint pid, const gchar *name, GVariantDict *dict, - void (*postprocess) (gchar **, gsize)) + void (*postprocess) (gchar **, gsize)) { g_autofree gchar *path = NULL; g_autofree gchar *contents = NULL; @@ -229,6 +288,7 @@ ipc_service_impl_handle_get_process_info (IpcService *service, gsize n_processes = 0; gboolean want_statm; gboolean want_cmdline; + gboolean want_comm; gboolean want_maps; gboolean want_mountinfo; @@ -240,6 +300,7 @@ ipc_service_impl_handle_get_process_info (IpcService *service, want_cmdline = !!strstr (attributes, "cmdline"); want_maps = !!strstr (attributes, "maps"); want_mountinfo = !!strstr (attributes, "mountinfo"); + want_comm = !!strstr (attributes, "comm"); g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); @@ -254,16 +315,19 @@ ipc_service_impl_handle_get_process_info (IpcService *service, g_variant_dict_insert (&dict, "pid", "i", pid, NULL); if (want_statm) - add_pid_proc_file_to (pid, "statm", &dict, NULL); + add_pid_proc_file_to (pid, "statm", &dict, postprocess_rstrip); if (want_cmdline) add_pid_proc_file_to (pid, "cmdline", &dict, postprocess_cmdline); + if (want_comm) + add_pid_proc_file_to (pid, "comm", &dict, postprocess_rstrip); + if (want_maps) - add_pid_proc_file_to (pid, "maps", &dict, NULL); + add_pid_proc_file_to (pid, "maps", &dict, postprocess_rstrip); if (want_mountinfo) - add_pid_proc_file_to (pid, "mountinfo", &dict, NULL); + add_pid_proc_file_to (pid, "mountinfo", &dict, postprocess_rstrip); g_variant_builder_add_value (&builder, g_variant_dict_end (&dict)); }