mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
libsysprof-ui: allow restricting remote proxy
This commit is contained in:
145
src/helpers.c
145
src/helpers.c
@ -404,3 +404,148 @@ helpers_list_processes_finish (GAsyncResult *result,
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
g_autofree gchar *path = NULL;
|
||||
g_autofree gchar *contents = NULL;
|
||||
gsize len;
|
||||
|
||||
g_assert (pid > -1);
|
||||
g_assert (name != NULL);
|
||||
g_assert (dict != NULL);
|
||||
|
||||
path = g_strdup_printf ("/proc/%d/%s", pid, name);
|
||||
|
||||
if (g_file_get_contents (path, &contents, &len, NULL))
|
||||
{
|
||||
if (postprocess)
|
||||
postprocess (&contents, len);
|
||||
g_variant_dict_insert (dict, name, "s", contents);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GVariant *
|
||||
helpers_get_process_info (const gchar *attributes)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
g_autofree gint *processes = NULL;
|
||||
gsize n_processes = 0;
|
||||
gboolean want_statm;
|
||||
gboolean want_cmdline;
|
||||
gboolean want_comm;
|
||||
gboolean want_maps;
|
||||
gboolean want_mountinfo;
|
||||
|
||||
if (attributes == NULL)
|
||||
attributes = "";
|
||||
|
||||
want_statm = !!strstr (attributes, "statm");
|
||||
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}"));
|
||||
|
||||
if (helpers_list_processes (&processes, &n_processes))
|
||||
{
|
||||
for (guint i = 0; i < n_processes; i++)
|
||||
{
|
||||
gint pid = processes[i];
|
||||
GVariantDict dict;
|
||||
|
||||
g_variant_dict_init (&dict, NULL);
|
||||
g_variant_dict_insert (&dict, "pid", "i", pid, NULL);
|
||||
|
||||
if (want_statm)
|
||||
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, postprocess_rstrip);
|
||||
|
||||
if (want_mountinfo)
|
||||
add_pid_proc_file_to (pid, "mountinfo", &dict, postprocess_rstrip);
|
||||
|
||||
g_variant_builder_add_value (&builder, g_variant_dict_end (&dict));
|
||||
}
|
||||
}
|
||||
|
||||
return g_variant_take_ref (g_variant_builder_end (&builder));
|
||||
}
|
||||
|
||||
@ -27,26 +27,27 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean helpers_can_see_pids (void);
|
||||
gboolean helpers_list_processes (gint32 **processes,
|
||||
gsize *n_processes);
|
||||
void helpers_list_processes_async (GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean helpers_list_processes_finish (GAsyncResult *result,
|
||||
gint32 **processes,
|
||||
gsize *n_processes,
|
||||
GError **error);
|
||||
gboolean helpers_perf_event_open (GVariant *options,
|
||||
gint32 pid,
|
||||
gint32 cpu,
|
||||
gint group_fd,
|
||||
guint64 flags,
|
||||
gint *out_fd);
|
||||
gboolean helpers_get_proc_file (const gchar *path,
|
||||
gchar **contents,
|
||||
gsize *len);
|
||||
gboolean helpers_get_proc_fd (const gchar *path,
|
||||
gint *out_fd);
|
||||
gboolean helpers_can_see_pids (void);
|
||||
gboolean helpers_list_processes (gint32 **processes,
|
||||
gsize *n_processes);
|
||||
void helpers_list_processes_async (GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean helpers_list_processes_finish (GAsyncResult *result,
|
||||
gint32 **processes,
|
||||
gsize *n_processes,
|
||||
GError **error);
|
||||
gboolean helpers_perf_event_open (GVariant *options,
|
||||
gint32 pid,
|
||||
gint32 cpu,
|
||||
gint group_fd,
|
||||
guint64 flags,
|
||||
gint *out_fd);
|
||||
gboolean helpers_get_proc_file (const gchar *path,
|
||||
gchar **contents,
|
||||
gsize *len);
|
||||
gboolean helpers_get_proc_fd (const gchar *path,
|
||||
gint *out_fd);
|
||||
GVariant *helpers_get_process_info (const gchar *attributes);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@ -627,6 +627,7 @@ sysprof_helpers_authorize_finish (SysprofHelpers *self,
|
||||
gboolean
|
||||
sysprof_helpers_get_process_info (SysprofHelpers *self,
|
||||
const gchar *attributes,
|
||||
gboolean no_proxy,
|
||||
GCancellable *cancellable,
|
||||
GVariant **info,
|
||||
GError **error)
|
||||
@ -636,6 +637,12 @@ sysprof_helpers_get_process_info (SysprofHelpers *self,
|
||||
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
|
||||
g_assert (info != NULL);
|
||||
|
||||
if (no_proxy)
|
||||
{
|
||||
*info = helpers_get_process_info (attributes);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return ipc_service_call_get_process_info_sync (self->proxy, attributes, info, cancellable, error);
|
||||
}
|
||||
|
||||
|
||||
@ -75,6 +75,7 @@ gboolean sysprof_helpers_get_proc_file_finish (SysprofHelpers
|
||||
GError **error);
|
||||
gboolean sysprof_helpers_get_process_info (SysprofHelpers *self,
|
||||
const gchar *attributes,
|
||||
gboolean no_proxy,
|
||||
GCancellable *cancellable,
|
||||
GVariant **info,
|
||||
GError **error);
|
||||
|
||||
@ -32,8 +32,9 @@
|
||||
struct _SysprofProcessModel
|
||||
{
|
||||
GObject parent_instance;
|
||||
guint reload_source;
|
||||
GPtrArray *items;
|
||||
guint reload_source;
|
||||
guint no_proxy : 1;
|
||||
};
|
||||
|
||||
static void list_model_iface_init (GListModelInterface *iface);
|
||||
@ -181,6 +182,7 @@ sysprof_process_model_reload_worker (GTask *task,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
SysprofProcessModel *self = source_object;
|
||||
SysprofHelpers *helpers = sysprof_helpers_get_default ();
|
||||
g_autoptr(GPtrArray) ret = NULL;
|
||||
g_autoptr(GVariant) info = NULL;
|
||||
@ -190,7 +192,7 @@ sysprof_process_model_reload_worker (GTask *task,
|
||||
|
||||
ret = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
if (sysprof_helpers_get_process_info (helpers, "pid,cmdline,comm", NULL, &info, NULL))
|
||||
if (sysprof_helpers_get_process_info (helpers, "pid,cmdline,comm", self->no_proxy, NULL, &info, NULL))
|
||||
{
|
||||
gsize n_children = g_variant_n_children (info);
|
||||
|
||||
@ -294,3 +296,12 @@ list_model_iface_init (GListModelInterface *iface)
|
||||
iface->get_n_items = sysprof_process_model_get_n_items;
|
||||
iface->get_item = sysprof_process_model_get_item;
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_process_model_set_no_proxy (SysprofProcessModel *self,
|
||||
gboolean no_proxy)
|
||||
{
|
||||
g_return_if_fail (SYSPROF_IS_PROCESS_MODEL (self));
|
||||
|
||||
self->no_proxy = !!no_proxy;
|
||||
}
|
||||
|
||||
@ -38,6 +38,9 @@ G_DECLARE_FINAL_TYPE (SysprofProcessModel, sysprof_process_model, SYSPROF, PROCE
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
SysprofProcessModel *sysprof_process_model_new (void);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
void sysprof_process_model_set_no_proxy (SysprofProcessModel *self,
|
||||
gboolean no_proxy);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
void sysprof_process_model_reload (SysprofProcessModel *self);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
void sysprof_process_model_queue_reload (SysprofProcessModel *self);
|
||||
|
||||
@ -237,151 +237,19 @@ 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))
|
||||
{
|
||||
g_autofree gchar *path = NULL;
|
||||
g_autofree gchar *contents = NULL;
|
||||
gsize len;
|
||||
|
||||
g_assert (pid > -1);
|
||||
g_assert (name != NULL);
|
||||
g_assert (dict != NULL);
|
||||
|
||||
path = g_strdup_printf ("/proc/%d/%s", pid, name);
|
||||
|
||||
if (g_file_get_contents (path, &contents, &len, NULL))
|
||||
{
|
||||
if (postprocess)
|
||||
postprocess (&contents, len);
|
||||
g_variant_dict_insert (dict, name, "s", contents);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ipc_service_impl_handle_get_process_info (IpcService *service,
|
||||
GDBusMethodInvocation *invocation,
|
||||
const gchar *attributes)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
g_autofree gint *processes = NULL;
|
||||
gsize n_processes = 0;
|
||||
gboolean want_statm;
|
||||
gboolean want_cmdline;
|
||||
gboolean want_comm;
|
||||
gboolean want_maps;
|
||||
gboolean want_mountinfo;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
g_assert (IPC_IS_SERVICE (service));
|
||||
g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
|
||||
g_assert (attributes != NULL);
|
||||
|
||||
want_statm = !!strstr (attributes, "statm");
|
||||
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}"));
|
||||
|
||||
if (helpers_list_processes (&processes, &n_processes))
|
||||
{
|
||||
for (guint i = 0; i < n_processes; i++)
|
||||
{
|
||||
gint pid = processes[i];
|
||||
GVariantDict dict;
|
||||
|
||||
g_variant_dict_init (&dict, NULL);
|
||||
g_variant_dict_insert (&dict, "pid", "i", pid, NULL);
|
||||
|
||||
if (want_statm)
|
||||
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, postprocess_rstrip);
|
||||
|
||||
if (want_mountinfo)
|
||||
add_pid_proc_file_to (pid, "mountinfo", &dict, postprocess_rstrip);
|
||||
|
||||
g_variant_builder_add_value (&builder, g_variant_dict_end (&dict));
|
||||
}
|
||||
}
|
||||
|
||||
ipc_service_complete_get_process_info (service, invocation, g_variant_builder_end (&builder));
|
||||
res = helpers_get_process_info (attributes);
|
||||
ipc_service_complete_get_process_info (service, invocation, res);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -143,6 +143,7 @@ test_process (void)
|
||||
|
||||
filter = sysprof_model_filter_new (G_LIST_MODEL (model));
|
||||
|
||||
sysprof_process_model_set_no_proxy (model, TRUE);
|
||||
sysprof_process_model_reload (model);
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (searches); i++)
|
||||
|
||||
@ -78,6 +78,7 @@ main (gint argc,
|
||||
gtk_container_add (GTK_CONTAINER (scroller), list);
|
||||
|
||||
model = sysprof_process_model_new ();
|
||||
sysprof_process_model_set_no_proxy (model, TRUE);
|
||||
filter = sysprof_model_filter_new (G_LIST_MODEL (model));
|
||||
gtk_list_box_bind_model (GTK_LIST_BOX (list), G_LIST_MODEL (filter), create_row, NULL, NULL);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user