From 2a69b89487a6ec7cc8ce9e43948a5c3357974a42 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 17 Jul 2009 16:47:23 +0100 Subject: Enable rudimentary TCP connections --- src/app.c | 71 ++++++++++++++++++++++++++++++++++++++++++++--------- src/lwp.c | 54 ++++++++++++++++++++++++++++++++++++++-- src/procmap-store.c | 10 +++++++- src/procmap.c | 6 ++++- 4 files changed, 126 insertions(+), 15 deletions(-) diff --git a/src/app.c b/src/app.c index cff3f7e..d30a019 100644 --- a/src/app.c +++ b/src/app.c @@ -73,7 +73,8 @@ struct _app { Client client; - GUnixSocket *lwp_events; + GUnixSocket *lwp_unix; + GTcpSocket *lwp_tcp; GTcpSocket *vg_events; GTcpSocket *vg_log; }; @@ -1954,9 +1955,9 @@ _update_client (App *app) } static gboolean -lwp_events_server_cb (GIOChannel *source, - GIOCondition condition, - gpointer data) +lwp_unix_server_cb (GIOChannel *source, + GIOCondition condition, + gpointer data) { App *app = data; @@ -1964,7 +1965,7 @@ lwp_events_server_cb (GIOChannel *source, GUnixSocket *client; gboolean update = FALSE; - client = gnet_unix_socket_server_accept (app->lwp_events); + client = gnet_unix_socket_server_accept (app->lwp_unix); do { GIOChannel *io = gnet_unix_socket_get_io_channel (client); int fd = g_io_channel_unix_get_fd (io); @@ -1978,7 +1979,47 @@ lwp_events_server_cb (GIOChannel *source, gnet_unix_socket_delete (client); - client = gnet_unix_socket_server_accept_nonblock (app->lwp_events); + client = gnet_unix_socket_server_accept_nonblock (app->lwp_unix); + } while (client != NULL); + + if (update) { + if (app->client.timeout == NULL) + app->client.timeout = _new_timeout (2000, (GSourceFunc) _update_client, app); + } + } + + if (condition & G_IO_HUP) + return FALSE; + + return TRUE; +} + +static gboolean +lwp_tcp_server_cb (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + App *app = data; + + if (condition & G_IO_IN) { + GTcpSocket *client; + gboolean update = FALSE; + + client = gnet_tcp_socket_server_accept (app->lwp_tcp); + do { + GIOChannel *io = gnet_tcp_socket_get_io_channel (client); + int fd = g_io_channel_unix_get_fd (io); + gzFile *file = gzdopen (dup (fd), "r"); + + if (lwp_read (file, app)) { + update = TRUE; + while (lwp_read (file, app)) ; + } + gzclose (file); + + gnet_tcp_socket_delete (client); + + client = gnet_tcp_socket_server_accept_nonblock (app->lwp_tcp); } while (client != NULL); if (update) { @@ -2296,7 +2337,7 @@ execute_cmdline_lwp (App *app, char **argv, gboolean attach_dbg, GError **error) return FALSE; } - path = gnet_unix_socket_get_path (app->lwp_events); + path = gnet_unix_socket_get_path (app->lwp_unix); n_client_env = 0; while (argv[n_client_env] != NULL) { @@ -2467,10 +2508,17 @@ int main g_remove (path); /* lwp interface */ - app.lwp_events = gnet_unix_socket_server_new (path); + app.lwp_unix = gnet_unix_socket_server_new (path); g_free (path); - io = gnet_unix_socket_get_io_channel (app.lwp_events); - g_io_add_watch (io, G_IO_IN, lwp_events_server_cb, &app); + io = gnet_unix_socket_get_io_channel (app.lwp_unix); + g_io_add_watch (io, G_IO_IN, lwp_unix_server_cb, &app); + g_io_channel_unref (io); + + iface = gnet_inetaddr_get_host_addr (); + app.lwp_tcp = gnet_tcp_socket_server_new_full (iface, 5320); + gnet_inetaddr_delete (iface); + io = gnet_tcp_socket_get_io_channel (app.lwp_tcp); + g_io_add_watch (io, G_IO_IN, lwp_tcp_server_cb, &app); g_io_channel_unref (io); /* restrict to IPv4 loopback */ @@ -2557,7 +2605,8 @@ int main _client_fini (&app.client); - gnet_unix_socket_delete (app.lwp_events); + gnet_unix_socket_delete (app.lwp_unix); + gnet_tcp_socket_delete (app.lwp_tcp); gnet_tcp_socket_delete (app.vg_events); gnet_tcp_socket_delete (app.vg_log); diff --git a/src/lwp.c b/src/lwp.c index 3986595..bfe7375 100644 --- a/src/lwp.c +++ b/src/lwp.c @@ -36,6 +36,9 @@ #include #include #include /* snprintf */ +#include +#include +#include /* gethostbyname */ #include #include /* types and macros */ @@ -290,8 +293,9 @@ static const char * _lwp_exe_path (void) { static char path[1024]; + int len; if (path[0] == '\0') - readlink ("/proc/self/exe", path, sizeof (path) - 1); + len = readlink ("/proc/self/exe", path, sizeof (path) - 1); return path; } @@ -401,12 +405,58 @@ _lwp_write_events (const LWP_EventRecord *events, gushort n_events) return FALSE; fd = socket (PF_UNIX, SOCK_STREAM, 0); - if (fd <0) + if (fd < 0) return FALSE; memset (&addr, 0, sizeof (addr)); addr.sun_family = AF_UNIX; strcpy (addr.sun_path, env + 5); + if (connect (fd, &addr, sizeof (addr)) < 0) + goto CLEAN_FD; + } else if (strncmp (env, "tcp:", 4) == 0) { + struct sockaddr_in addr; + struct hostent he, *result; + const char *colon; + char name[256], buf[256]; + size_t len; + int h_err; + + env += 4; + colon = strchr (env, ':'); + if (colon) + len = colon - env; + else + len = strlen (env); + + if (len > sizeof (name) - 1) + return FALSE; + + memcpy (name, env, len); + name[len] = '\0'; + + memset (&addr, 0, sizeof (addr)); + addr.sin_family = AF_INET; + addr.sin_port = 0; + if (colon != NULL) + addr.sin_port = htons (atoi (colon+1)); + if (addr.sin_port == 0) + addr.sin_port = htons (5320); + + if (! inet_aton (name, &addr.sin_addr)) { + if (! gethostbyname_r (name, + &he, buf, sizeof (buf), &result, &h_err)) + { + return FALSE; + } + + memcpy (&addr.sin_addr.s_addr, result->h_addr_list[0], + sizeof (addr.sin_addr.s_addr)); + } + + fd = socket (PF_INET, SOCK_STREAM, 0); + if (fd < 0) + return FALSE; + if (connect (fd, &addr, sizeof (addr)) < 0) goto CLEAN_FD; } else { diff --git a/src/procmap-store.c b/src/procmap-store.c index 08ade14..182af95 100644 --- a/src/procmap-store.c +++ b/src/procmap-store.c @@ -283,10 +283,18 @@ procmap_store_sort_by_dirty (gconstpointer A, gconstpointer B) return b->private_dirty - a->private_dirty; } +static gint +procmap_store_sort_by_addr (gconstpointer A, gconstpointer B) +{ + const glibtop_map_entry *a = A, *b = B; + return b->start - a->start; +} + static void procmap_store_init (ProcmapStore *self) { - self->sort_func = procmap_store_sort_by_dirty; + //self->sort_func = procmap_store_sort_by_dirty; + self->sort_func = procmap_store_sort_by_addr; } diff --git a/src/procmap.c b/src/procmap.c index 72853a5..0e6af6e 100644 --- a/src/procmap.c +++ b/src/procmap.c @@ -98,6 +98,7 @@ procmap_init (Procmap *self) renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Start", renderer, "text", PROCMAP_START, NULL); + gtk_tree_view_column_set_sort_column_id (column, PROCMAP_START); gtk_tree_view_append_column (&self->tv, column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("End", @@ -114,6 +115,7 @@ procmap_init (Procmap *self) gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer, cell_layout_pretty_print_uint, GUINT_TO_POINTER (PROCMAP_SIZE), NULL); + gtk_tree_view_column_set_sort_column_id (column, PROCMAP_SIZE); gtk_tree_view_append_column (&self->tv, column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("RSS", @@ -121,14 +123,16 @@ procmap_init (Procmap *self) gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer, cell_layout_pretty_print_uint, GUINT_TO_POINTER (PROCMAP_RSS), NULL); + gtk_tree_view_column_set_sort_column_id (column, PROCMAP_RSS); gtk_tree_view_append_column (&self->tv, column); renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Private Dirty", + column = gtk_tree_view_column_new_with_attributes ("Dirty", renderer, NULL); gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer, cell_layout_pretty_print_uint, GUINT_TO_POINTER (PROCMAP_PRIVATE_DIRTY), NULL); + gtk_tree_view_column_set_sort_column_id (column, PROCMAP_PRIVATE_DIRTY); gtk_tree_view_append_column (&self->tv, column); gtk_tree_view_set_grid_lines (&self->tv, GTK_TREE_VIEW_GRID_LINES_VERTICAL); -- cgit v1.2.3