From b279cfa785b1b58311e7a729eab3b03d6e2f2abf Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Thu, 15 Jun 2006 20:50:00 +0000 Subject: [PATCH] start alternative to sigar_net_connection_list_get --- include/sigar.h | 11 +++++ src/os/linux/linux_sigar.c | 96 +++++++++++++++++++++++--------------- 2 files changed, 69 insertions(+), 38 deletions(-) diff --git a/include/sigar.h b/include/sigar.h index edfd6e15..109538ba 100644 --- a/include/sigar.h +++ b/include/sigar.h @@ -567,6 +567,17 @@ SIGAR_DECLARE(int) sigar_net_connection_list_destroy(sigar_t *sigar, sigar_net_connection_list_t *connlist); +typedef struct sigar_net_connection_walker_t sigar_net_connection_walker_t; + +/* alternative to sigar_net_connection_list_get */ +struct sigar_net_connection_walker_t { + sigar_t *sigar; + int flags; + void *data; /* user data */ + int (*add_connection)(sigar_net_connection_walker_t *walker, + sigar_net_connection_t *connection); +}; + SIGAR_DECLARE(const char *)sigar_net_connection_type_get(int type); SIGAR_DECLARE(const char *)sigar_net_connection_state_get(int state); diff --git a/src/os/linux/linux_sigar.c b/src/os/linux/linux_sigar.c index 1eb5ae19..f730f63c 100644 --- a/src/os/linux/linux_sigar.c +++ b/src/os/linux/linux_sigar.c @@ -1691,14 +1691,36 @@ typedef struct { unsigned long port; } net_conn_getter_t; -#define CONN_GET_DONE -2 +static int proc_net_walker(sigar_net_connection_walker_t *walker, + sigar_net_connection_t *conn) +{ + net_conn_getter_t *getter = + (net_conn_getter_t *)walker->data; -static int proc_net_read(net_conn_getter_t *getter, + if (getter->connlist) { + SIGAR_NET_CONNLIST_GROW(getter->connlist); + memcpy(&getter->connlist->data[getter->connlist->number++], + conn, sizeof(*conn)); + } + else { + if ((getter->port == conn->local_port) && + (conn->remote_port == 0)) + { + memcpy(getter->conn, conn, sizeof(*conn)); + return !SIGAR_OK; /* break loop */ + } + } + + return SIGAR_OK; /* continue loop */ +} + +static int proc_net_read(sigar_net_connection_walker_t *walker, const char *fname, - int flags, int type) + int type) { FILE *fp; char buffer[8192], *ptr; + int flags = walker->flags; if (!(fp = fopen(fname, "r"))) { return errno; @@ -1710,7 +1732,7 @@ static int proc_net_read(net_conn_getter_t *getter, sigar_net_connection_t conn; char *port = NULL; char *laddr, *raddr; - int status; + int status, more; SIGAR_SKIP_SPACE(ptr); if (IS_NULL_PTR(ptr)) { @@ -1820,19 +1842,10 @@ static int proc_net_read(net_conn_getter_t *getter, conn.inode = sigar_strtoul(ptr); - if (getter->connlist) { - SIGAR_NET_CONNLIST_GROW(getter->connlist); - memcpy(&getter->connlist->data[getter->connlist->number++], - &conn, sizeof(conn)); - } - else { - if ((getter->port == conn.local_port) && - (conn.remote_port == 0)) - { - memcpy(getter->conn, &conn, sizeof(conn)); - fclose(fp); - return CONN_GET_DONE; - } + more = walker->add_connection(walker, &conn); + if (more != SIGAR_OK) { + fclose(fp); + return SIGAR_OK; } } @@ -1841,24 +1854,23 @@ static int proc_net_read(net_conn_getter_t *getter, return SIGAR_OK; } -static int net_conn_get(sigar_t *sigar, - net_conn_getter_t *getter, - int flags) +static int net_conn_get(sigar_net_connection_walker_t *walker) { + int flags = walker->flags; int status; if (flags & SIGAR_NETCONN_TCP) { - status = proc_net_read(getter, + status = proc_net_read(walker, PROC_FS_ROOT "net/tcp", - flags, SIGAR_NETCONN_TCP); + SIGAR_NETCONN_TCP); if (status != SIGAR_OK) { return status; } - status = proc_net_read(getter, + status = proc_net_read(walker, PROC_FS_ROOT "net/tcp6", - flags, SIGAR_NETCONN_TCP); + SIGAR_NETCONN_TCP); if (!((status == SIGAR_OK) || (status == ENOENT))) { return status; @@ -1866,17 +1878,17 @@ static int net_conn_get(sigar_t *sigar, } if (flags & SIGAR_NETCONN_UDP) { - status = proc_net_read(getter, + status = proc_net_read(walker, PROC_FS_ROOT "net/udp", - flags, SIGAR_NETCONN_UDP); + SIGAR_NETCONN_UDP); if (status != SIGAR_OK) { return status; } - status = proc_net_read(getter, + status = proc_net_read(walker, PROC_FS_ROOT "net/udp6", - flags, SIGAR_NETCONN_UDP); + SIGAR_NETCONN_UDP); if (!((status == SIGAR_OK) || (status == ENOENT))) { return status; @@ -1884,17 +1896,17 @@ static int net_conn_get(sigar_t *sigar, } if (flags & SIGAR_NETCONN_RAW) { - status = proc_net_read(getter, + status = proc_net_read(walker, PROC_FS_ROOT "net/raw", - flags, SIGAR_NETCONN_RAW); - + SIGAR_NETCONN_RAW); + if (status != SIGAR_OK) { return status; } - status = proc_net_read(getter, + status = proc_net_read(walker, PROC_FS_ROOT "net/raw6", - flags, SIGAR_NETCONN_RAW); + SIGAR_NETCONN_RAW); if (!((status == SIGAR_OK) || (status == ENOENT))) { return status; @@ -1911,6 +1923,7 @@ int sigar_net_connection_list_get(sigar_t *sigar, int flags) { int status; + sigar_net_connection_walker_t walker; net_conn_getter_t getter; sigar_net_connection_list_create(connlist); @@ -1918,7 +1931,12 @@ int sigar_net_connection_list_get(sigar_t *sigar, getter.conn = NULL; getter.connlist = connlist; - status = net_conn_get(sigar, &getter, flags); + walker.sigar = sigar; + walker.flags = flags; + walker.data = &getter; + walker.add_connection = proc_net_walker; + + status = net_conn_get(&walker); if (status != SIGAR_OK) { sigar_net_connection_list_destroy(sigar, connlist); @@ -1933,17 +1951,19 @@ static int sigar_net_connection_get(sigar_t *sigar, int flags) { int status; + sigar_net_connection_walker_t walker; net_conn_getter_t getter; getter.conn = netconn; getter.connlist = NULL; getter.port = port; - status = net_conn_get(sigar, &getter, flags); + walker.sigar = sigar; + walker.flags = flags; + walker.data = &getter; + walker.add_connection = proc_net_walker; - if (status == CONN_GET_DONE) { - return SIGAR_OK; - } + status = net_conn_get(&walker); return status; }