diff options
author | Benoît Dejean <bdejean@src.gnome.org> | 2005-01-21 23:30:54 +0000 |
---|---|---|
committer | Benoît Dejean <bdejean@src.gnome.org> | 2005-01-21 23:30:54 +0000 |
commit | 46380bf655e7c034a09936c388b71aef0e6365fe (patch) | |
tree | b79c05ee83553580e87f8e850c7d7f19801f8ccc /sysdeps | |
parent | 91dda5b70de3b30676061310308419669417dc69 (diff) | |
download | libgtop-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.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/linux/ChangeLog | 7 | ||||
-rw-r--r-- | sysdeps/linux/procopenfiles.c | 178 |
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; |