summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoît Dejean <bdejean@src.gnome.org>2005-01-21 23:30:54 +0000
committerBenoît Dejean <bdejean@src.gnome.org>2005-01-21 23:30:54 +0000
commit46380bf655e7c034a09936c388b71aef0e6365fe (patch)
treeb79c05ee83553580e87f8e850c7d7f19801f8ccc
parent91dda5b70de3b30676061310308419669417dc69 (diff)
downloadlibgtop-46380bf655e7c034a09936c388b71aef0e6365fe.tar.gz
Total rewrite. socket/localsocket should be much faster.
* procopenfiles.c: (parse_file), (get_all), (inet_socket_parser), (get_all_inet_sockets), (local_socket_parser), (get_all_local_sockets), (glibtop_get_proc_open_files_s): Total rewrite. socket/localsocket should be much faster.
-rw-r--r--sysdeps/linux/ChangeLog7
-rw-r--r--sysdeps/linux/procopenfiles.c178
2 files changed, 137 insertions, 48 deletions
diff --git a/sysdeps/linux/ChangeLog b/sysdeps/linux/ChangeLog
index 3299bcc2..29a12377 100644
--- a/sysdeps/linux/ChangeLog
+++ b/sysdeps/linux/ChangeLog
@@ -1,3 +1,10 @@
+2005-01-22 Benoît Dejean <TazForEver@dlfp.org>
+
+ * procopenfiles.c: (parse_file), (get_all), (inet_socket_parser),
+ (get_all_inet_sockets), (local_socket_parser),
+ (get_all_local_sockets), (glibtop_get_proc_open_files_s): Total rewrite.
+ socket/localsocket should be much faster.
+
2005-01-16 Benoît Dejean <TazForEver@dlfp.org>
* glibtop_private.c: (skip_token):
diff --git a/sysdeps/linux/procopenfiles.c b/sysdeps/linux/procopenfiles.c
index d1f40963..02b21ba6 100644
--- a/sysdeps/linux/procopenfiles.c
+++ b/sysdeps/linux/procopenfiles.c
@@ -50,48 +50,126 @@ glibtop_init_proc_open_files_s (glibtop *server)
-struct SocketEndPoint
+typedef void (*LineParser)(GHashTable *dict, const char *line);
+
+
+static void
+parse_file(const char *filename, LineParser parser, GHashTable *dict)
+{
+ FILE *f;
+ char line[1024];
+
+ f = fopen(filename, "r");
+
+ if(!f) {
+ g_warning("Cannot open '%s'", filename);
+ return;
+ }
+
+ /* skip the first line */
+ if(!fgets(line, sizeof line, f)) goto eof;
+
+ while(fgets(line, sizeof line, f))
+ {
+ parser(dict, line);
+ }
+
+ eof:
+ fclose(f);
+}
+
+
+static GHashTable*
+get_all(const char *filename, LineParser parser)
+{
+ GHashTable *dict;
+
+ dict = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, g_free);
+
+ parse_file(filename, parser, dict);
+
+ return dict;
+}
+
+
+
+
+
+struct InetSocketEntry
{
char host[GLIBTOP_OPEN_DEST_HOST_LEN + 1];
int port;
- int sock;
};
+static void
+inet_socket_parser(GHashTable *dict, const char* line)
+{
+ struct InetSocketEntry *se;
+ int sock;
+ unsigned addr;
+
+ se = g_malloc0(sizeof *se);
+
+ if(sscanf(line, "%*d: %*x:%*x %8x:%4x %*x %*x:%*x %*x:%*x %*d %*d %*d %d",
+ &addr, &se->port, &sock) != 3)
+ goto error;
-static GArray* get_all_sockets()
+ if(!inet_ntop(AF_INET, &addr, se->host, sizeof se->host))
+ goto error;
+
+ g_hash_table_insert(dict, GINT_TO_POINTER(sock), se);
+ return;
+
+ error:
+ g_free(se);
+}
+
+
+static inline GHashTable *
+get_all_inet_sockets()
{
- GArray *socks;
- FILE *tcp;
- char line[1024];
+ return get_all("/proc/net/tcp", inet_socket_parser);
+}
- socks = g_array_new(FALSE, FALSE, sizeof(struct SocketEndPoint));
- g_return_val_if_fail((tcp = fopen("/proc/net/tcp", "r")), socks);
- if(!fgets(line, sizeof line, tcp)) goto eof;
- while(fgets(line, sizeof line, tcp))
- {
- struct SocketEndPoint sep;
- unsigned addr;
- if(sscanf(line, "%*d: %*x:%*x %8x:%4x %*x %*x:%*x %*x:%*x %*d %*d %*d %d",
- &addr, &sep.port, &sep.sock) != 3)
- continue;
+struct LocalSocketEntry
+{
+ char name[GLIBTOP_OPEN_DEST_HOST_LEN + 1];
+};
- if(!inet_ntop(AF_INET, &addr, sep.host, sizeof sep.host))
- continue;
- g_array_append_val(socks, sep);
- }
+static void
+local_socket_parser(GHashTable *dict, const char *line)
+{
+ int sock;
+ struct LocalSocketEntry *use;
+ char *p;
- eof:
- fclose(tcp);
- return socks;
+ use = g_malloc0(sizeof *use);
+
+ /* dfaf1640: 00000003 00000000 00000000 0001 03 6457 /dev/log */
+ p = skip_multiple_token(line, 6);
+
+ sock = strtoul(p, &p, 10);
+ g_strlcpy(use->name, p, sizeof use->name);
+ g_strstrip(use->name);
+ g_hash_table_insert(dict, GINT_TO_POINTER(sock), use);
+}
+
+
+static inline GHashTable *
+get_all_local_sockets()
+{
+ return get_all("/proc/net/unix", local_socket_parser);
}
+
/* Provides detailed information about a process' open files */
glibtop_open_files_entry *
@@ -99,7 +177,7 @@ glibtop_get_proc_open_files_s (glibtop *server, glibtop_proc_open_files *buf, pi
{
char fn [BUFSIZ];
GArray *entries;
- GArray *socks = NULL;
+ GHashTable *inet_sockets = NULL, *local_sockets = NULL;
struct dirent *direntry;
DIR *dir;
@@ -119,7 +197,6 @@ glibtop_get_proc_open_files_s (glibtop *server, glibtop_proc_open_files *buf, pi
int rv;
glibtop_open_files_entry entry = {0};
-
if(direntry->d_name[0] == '.')
continue;
@@ -134,33 +211,38 @@ glibtop_get_proc_open_files_s (glibtop *server, glibtop_proc_open_files *buf, pi
if(g_str_has_prefix(tgt, "socket:["))
{
- unsigned i;
int sockfd;
+ struct InetSocketEntry *ise;
+ struct LocalSocketEntry *lse;
- if(!socks)
- socks = get_all_sockets();
-
- entry.type = GLIBTOP_FILE_TYPE_INETSOCKET;
+ if(!inet_sockets) inet_sockets = get_all_inet_sockets();
+ if(!local_sockets) local_sockets = get_all_local_sockets();
sockfd = atoi(tgt + 8);
- for(i = 0; i < socks->len; ++i)
- {
- const struct SocketEndPoint *sep;
-
- sep = & g_array_index(socks,
- struct SocketEndPoint,
- i);
-
- if(sep->sock == sockfd)
- {
- entry.info.sock.dest_port = sep->port;
- memcpy(entry.info.sock.dest_host,
- sep->host,
- sizeof sep->host);
- break;
- }
+ ise = g_hash_table_lookup(inet_sockets,
+ GINT_TO_POINTER(sockfd));
+
+ if(ise) {
+ entry.type = GLIBTOP_FILE_TYPE_INETSOCKET;
+ entry.info.sock.dest_port = ise->port;
+ g_strlcpy(entry.info.sock.dest_host, ise->host,
+ sizeof entry.info.sock.dest_host);
+ goto found;
}
+
+ lse = g_hash_table_lookup(local_sockets,
+ GINT_TO_POINTER(sockfd));
+
+ if(lse) {
+ entry.type = GLIBTOP_FILE_TYPE_LOCALSOCKET;
+ g_strlcpy(entry.info.localsock.name, lse->name,
+ sizeof entry.info.localsock.name);
+ goto found;
+ }
+
+ found:
+ (void)0; /* kills warning */
}
else if(g_str_has_prefix(tgt, "pipe:["))
{
@@ -177,8 +259,8 @@ glibtop_get_proc_open_files_s (glibtop *server, glibtop_proc_open_files *buf, pi
closedir (dir);
- if(socks)
- g_array_free(socks, TRUE);
+ if(inet_sockets) g_hash_table_destroy(inet_sockets);
+ if(local_sockets) g_hash_table_destroy(local_sockets);
buf->flags = _glibtop_sysdeps_proc_open_files;
buf->number = entries->len;