mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-10 23:20:54 +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;
|
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
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
gboolean helpers_can_see_pids (void);
|
gboolean helpers_can_see_pids (void);
|
||||||
gboolean helpers_list_processes (gint32 **processes,
|
gboolean helpers_list_processes (gint32 **processes,
|
||||||
gsize *n_processes);
|
gsize *n_processes);
|
||||||
void helpers_list_processes_async (GCancellable *cancellable,
|
void helpers_list_processes_async (GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
gboolean helpers_list_processes_finish (GAsyncResult *result,
|
gboolean helpers_list_processes_finish (GAsyncResult *result,
|
||||||
gint32 **processes,
|
gint32 **processes,
|
||||||
gsize *n_processes,
|
gsize *n_processes,
|
||||||
GError **error);
|
GError **error);
|
||||||
gboolean helpers_perf_event_open (GVariant *options,
|
gboolean helpers_perf_event_open (GVariant *options,
|
||||||
gint32 pid,
|
gint32 pid,
|
||||||
gint32 cpu,
|
gint32 cpu,
|
||||||
gint group_fd,
|
gint group_fd,
|
||||||
guint64 flags,
|
guint64 flags,
|
||||||
gint *out_fd);
|
gint *out_fd);
|
||||||
gboolean helpers_get_proc_file (const gchar *path,
|
gboolean helpers_get_proc_file (const gchar *path,
|
||||||
gchar **contents,
|
gchar **contents,
|
||||||
gsize *len);
|
gsize *len);
|
||||||
gboolean helpers_get_proc_fd (const gchar *path,
|
gboolean helpers_get_proc_fd (const gchar *path,
|
||||||
gint *out_fd);
|
gint *out_fd);
|
||||||
|
GVariant *helpers_get_process_info (const gchar *attributes);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@ -627,6 +627,7 @@ sysprof_helpers_authorize_finish (SysprofHelpers *self,
|
|||||||
gboolean
|
gboolean
|
||||||
sysprof_helpers_get_process_info (SysprofHelpers *self,
|
sysprof_helpers_get_process_info (SysprofHelpers *self,
|
||||||
const gchar *attributes,
|
const gchar *attributes,
|
||||||
|
gboolean no_proxy,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GVariant **info,
|
GVariant **info,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -636,6 +637,12 @@ sysprof_helpers_get_process_info (SysprofHelpers *self,
|
|||||||
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
|
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
|
||||||
g_assert (info != NULL);
|
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);
|
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);
|
GError **error);
|
||||||
gboolean sysprof_helpers_get_process_info (SysprofHelpers *self,
|
gboolean sysprof_helpers_get_process_info (SysprofHelpers *self,
|
||||||
const gchar *attributes,
|
const gchar *attributes,
|
||||||
|
gboolean no_proxy,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GVariant **info,
|
GVariant **info,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|||||||
@ -32,8 +32,9 @@
|
|||||||
struct _SysprofProcessModel
|
struct _SysprofProcessModel
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
guint reload_source;
|
|
||||||
GPtrArray *items;
|
GPtrArray *items;
|
||||||
|
guint reload_source;
|
||||||
|
guint no_proxy : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void list_model_iface_init (GListModelInterface *iface);
|
static void list_model_iface_init (GListModelInterface *iface);
|
||||||
@ -181,6 +182,7 @@ sysprof_process_model_reload_worker (GTask *task,
|
|||||||
gpointer task_data,
|
gpointer task_data,
|
||||||
GCancellable *cancellable)
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
|
SysprofProcessModel *self = source_object;
|
||||||
SysprofHelpers *helpers = sysprof_helpers_get_default ();
|
SysprofHelpers *helpers = sysprof_helpers_get_default ();
|
||||||
g_autoptr(GPtrArray) ret = NULL;
|
g_autoptr(GPtrArray) ret = NULL;
|
||||||
g_autoptr(GVariant) info = 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);
|
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);
|
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_n_items = sysprof_process_model_get_n_items;
|
||||||
iface->get_item = sysprof_process_model_get_item;
|
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
|
SYSPROF_AVAILABLE_IN_ALL
|
||||||
SysprofProcessModel *sysprof_process_model_new (void);
|
SysprofProcessModel *sysprof_process_model_new (void);
|
||||||
SYSPROF_AVAILABLE_IN_ALL
|
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);
|
void sysprof_process_model_reload (SysprofProcessModel *self);
|
||||||
SYSPROF_AVAILABLE_IN_ALL
|
SYSPROF_AVAILABLE_IN_ALL
|
||||||
void sysprof_process_model_queue_reload (SysprofProcessModel *self);
|
void sysprof_process_model_queue_reload (SysprofProcessModel *self);
|
||||||
|
|||||||
@ -237,151 +237,19 @@ ipc_service_impl_g_authorize_method (GDBusInterfaceSkeleton *skeleton,
|
|||||||
return ret;
|
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
|
static gboolean
|
||||||
ipc_service_impl_handle_get_process_info (IpcService *service,
|
ipc_service_impl_handle_get_process_info (IpcService *service,
|
||||||
GDBusMethodInvocation *invocation,
|
GDBusMethodInvocation *invocation,
|
||||||
const gchar *attributes)
|
const gchar *attributes)
|
||||||
{
|
{
|
||||||
GVariantBuilder builder;
|
g_autoptr(GVariant) res = NULL;
|
||||||
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_assert (IPC_IS_SERVICE (service));
|
g_assert (IPC_IS_SERVICE (service));
|
||||||
g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
|
g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
|
||||||
g_assert (attributes != NULL);
|
g_assert (attributes != NULL);
|
||||||
|
|
||||||
want_statm = !!strstr (attributes, "statm");
|
res = helpers_get_process_info (attributes);
|
||||||
want_cmdline = !!strstr (attributes, "cmdline");
|
ipc_service_complete_get_process_info (service, invocation, res);
|
||||||
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));
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -143,6 +143,7 @@ test_process (void)
|
|||||||
|
|
||||||
filter = sysprof_model_filter_new (G_LIST_MODEL (model));
|
filter = sysprof_model_filter_new (G_LIST_MODEL (model));
|
||||||
|
|
||||||
|
sysprof_process_model_set_no_proxy (model, TRUE);
|
||||||
sysprof_process_model_reload (model);
|
sysprof_process_model_reload (model);
|
||||||
|
|
||||||
for (guint i = 0; i < G_N_ELEMENTS (searches); i++)
|
for (guint i = 0; i < G_N_ELEMENTS (searches); i++)
|
||||||
|
|||||||
@ -78,6 +78,7 @@ main (gint argc,
|
|||||||
gtk_container_add (GTK_CONTAINER (scroller), list);
|
gtk_container_add (GTK_CONTAINER (scroller), list);
|
||||||
|
|
||||||
model = sysprof_process_model_new ();
|
model = sysprof_process_model_new ();
|
||||||
|
sysprof_process_model_set_no_proxy (model, TRUE);
|
||||||
filter = sysprof_model_filter_new (G_LIST_MODEL (model));
|
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);
|
gtk_list_box_bind_model (GTK_LIST_BOX (list), G_LIST_MODEL (filter), create_row, NULL, NULL);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user