/proc/net parsing optimizations
This commit is contained in:
		
							parent
							
								
									f26a733bfa
								
							
						
					
					
						commit
						b313b3ec27
					
				@ -1545,13 +1545,13 @@ int sigar_cpu_info_list_get(sigar_t *sigar,
 | 
				
			|||||||
    return SIGAR_OK;
 | 
					    return SIGAR_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned int hex2int(const char *x)
 | 
					static SIGAR_INLINE unsigned int hex2int(const char *x, int len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int i, ch;
 | 
					    int i;
 | 
				
			||||||
    unsigned int j;
 | 
					    unsigned int j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i=0, j=0; i<8; i++) {
 | 
					    for (i=0, j=0; i<len; i++) {
 | 
				
			||||||
        ch = x[i];
 | 
					        register int ch = x[i];
 | 
				
			||||||
        j <<= 4;
 | 
					        j <<= 4;
 | 
				
			||||||
        if (isdigit(ch)) {
 | 
					        if (isdigit(ch)) {
 | 
				
			||||||
            j |= ch - '0';
 | 
					            j |= ch - '0';
 | 
				
			||||||
@ -1567,6 +1567,8 @@ static unsigned int hex2int(const char *x)
 | 
				
			|||||||
    return j;
 | 
					    return j;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HEX_ENT_LEN 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __LP64__
 | 
					#ifdef __LP64__
 | 
				
			||||||
#define ROUTE_FMT "%16s %128s %128s %X %ld %ld %ld %128s %ld %ld %ld\n"
 | 
					#define ROUTE_FMT "%16s %128s %128s %X %ld %ld %ld %128s %ld %ld %ld\n"
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
@ -1611,9 +1613,9 @@ int sigar_net_route_list_get(sigar_t *sigar,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        route->flags = flags;
 | 
					        route->flags = flags;
 | 
				
			||||||
        route->destination = hex2int(net_addr);
 | 
					        route->destination = hex2int(net_addr, HEX_ENT_LEN);
 | 
				
			||||||
        route->gateway = hex2int(gate_addr);
 | 
					        route->gateway = hex2int(gate_addr, HEX_ENT_LEN);
 | 
				
			||||||
        route->mask = hex2int(mask_addr);
 | 
					        route->mask = hex2int(mask_addr, HEX_ENT_LEN);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fclose(fp);
 | 
					    fclose(fp);
 | 
				
			||||||
@ -1683,25 +1685,13 @@ int sigar_net_interface_stat_get(sigar_t *sigar, const char *name,
 | 
				
			|||||||
    return found ? SIGAR_OK : ENXIO;
 | 
					    return found ? SIGAR_OK : ENXIO;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IS_NULL_PTR(ptr) ((ptr == NULL) || (*(ptr) == '\0'))
 | 
					static SIGAR_INLINE int ip_format(char *buffer, int buflen, char *ptr, int len)
 | 
				
			||||||
#define HEX_ENT_LEN 8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static SIGAR_INLINE int ip_format(char *buffer, int buflen, char *ptr)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int alen;
 | 
					    if (len > HEX_ENT_LEN) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (IS_NULL_PTR(ptr)) {
 | 
					 | 
				
			||||||
        alen = 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
        alen = strlen(ptr);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (alen > HEX_ENT_LEN) {
 | 
					 | 
				
			||||||
        struct in6_addr addr;
 | 
					        struct in6_addr addr;
 | 
				
			||||||
        int i;
 | 
					        int i;
 | 
				
			||||||
        for (i=0; i<=3; i++, ptr+=8) {
 | 
					        for (i=0; i<=3; i++, ptr+=HEX_ENT_LEN) {
 | 
				
			||||||
            addr.s6_addr32[i] = hex2int(ptr);
 | 
					            addr.s6_addr32[i] = hex2int(ptr, HEX_ENT_LEN);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (!inet_ntop(AF_INET6, &addr, buffer, buflen)) {
 | 
					        if (!inet_ntop(AF_INET6, &addr, buffer, buflen)) {
 | 
				
			||||||
            return errno;
 | 
					            return errno;
 | 
				
			||||||
@ -1709,7 +1699,7 @@ static SIGAR_INLINE int ip_format(char *buffer, int buflen, char *ptr)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        struct in_addr addr;
 | 
					        struct in_addr addr;
 | 
				
			||||||
        addr.s_addr = (alen == HEX_ENT_LEN) ? hex2int(ptr) : 0;
 | 
					        addr.s_addr = (len == HEX_ENT_LEN) ? hex2int(ptr, HEX_ENT_LEN) : 0;
 | 
				
			||||||
        if (!inet_ntop(AF_INET, &addr, buffer, buflen)) {
 | 
					        if (!inet_ntop(AF_INET, &addr, buffer, buflen)) {
 | 
				
			||||||
            return errno;
 | 
					            return errno;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -1747,12 +1737,18 @@ static int proc_net_walker(sigar_net_connection_walker_t *walker,
 | 
				
			|||||||
    return SIGAR_OK; /* continue loop */
 | 
					    return SIGAR_OK; /* continue loop */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SKIP_WHILE(p, c) while (*p == c) p++
 | 
				
			||||||
 | 
					#define SKIP_PAST(p, c) \
 | 
				
			||||||
 | 
					   while(*p && (*p != c)) p++; \
 | 
				
			||||||
 | 
					   SKIP_WHILE(p, c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int proc_net_read(sigar_net_connection_walker_t *walker,
 | 
					static int proc_net_read(sigar_net_connection_walker_t *walker,
 | 
				
			||||||
                         const char *fname,
 | 
					                         const char *fname,
 | 
				
			||||||
                         int type)
 | 
					                         int type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    FILE *fp;
 | 
					    FILE *fp;
 | 
				
			||||||
    char buffer[8192], *ptr;
 | 
					    char buffer[8192];
 | 
				
			||||||
 | 
					    char *ptr;
 | 
				
			||||||
    int flags = walker->flags;
 | 
					    int flags = walker->flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(fp = fopen(fname, "r"))) {
 | 
					    if (!(fp = fopen(fname, "r"))) {
 | 
				
			||||||
@ -1763,56 +1759,37 @@ static int proc_net_read(sigar_net_connection_walker_t *walker,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    while ((ptr = fgets(buffer, sizeof(buffer), fp))) {
 | 
					    while ((ptr = fgets(buffer, sizeof(buffer), fp))) {
 | 
				
			||||||
        sigar_net_connection_t conn;
 | 
					        sigar_net_connection_t conn;
 | 
				
			||||||
        char *port = NULL;
 | 
					 | 
				
			||||||
        char *laddr, *raddr;
 | 
					        char *laddr, *raddr;
 | 
				
			||||||
 | 
					        int laddr_len=0, raddr_len=0;
 | 
				
			||||||
        int status, more;
 | 
					        int status, more;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SIGAR_SKIP_SPACE(ptr);
 | 
					        /* skip leading space */
 | 
				
			||||||
        if (IS_NULL_PTR(ptr)) {
 | 
					        SKIP_WHILE(ptr, ' ');
 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ptr = sigar_skip_token(ptr); /* skip number */
 | 
					        /* skip "%d: " */
 | 
				
			||||||
        while (isspace(*ptr)) {
 | 
					        SKIP_PAST(ptr, ' ');
 | 
				
			||||||
            ptr++;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (IS_NULL_PTR(ptr)) {
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!(port = strchr(ptr, ':'))) {
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        *port = '\0';
 | 
					 | 
				
			||||||
        ++port;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        conn.local_port = (strtoul(port, &port, 16) & 0xffff);
 | 
					 | 
				
			||||||
        laddr = ptr;
 | 
					        laddr = ptr;
 | 
				
			||||||
 | 
					        while (*ptr && (*ptr != ':')) {
 | 
				
			||||||
        ptr = port;
 | 
					            laddr_len++;
 | 
				
			||||||
        while (isspace(*ptr)) {
 | 
					 | 
				
			||||||
            ptr++;
 | 
					            ptr++;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (IS_NULL_PTR(ptr)) {
 | 
					        SKIP_WHILE(ptr, ':');
 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!(port = strchr(ptr, ':'))) {
 | 
					        conn.local_port = (strtoul(ptr, &ptr, 16) & 0xffff);
 | 
				
			||||||
            continue;
 | 
					
 | 
				
			||||||
        }
 | 
					        SKIP_WHILE(ptr, ' ');
 | 
				
			||||||
        *port = '\0';
 | 
					 | 
				
			||||||
        ++port;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        conn.remote_port = (strtoul(port, &port, 16) & 0xffff);
 | 
					 | 
				
			||||||
        raddr = ptr;
 | 
					        raddr = ptr;
 | 
				
			||||||
 | 
					        while (*ptr && (*ptr != ':')) {
 | 
				
			||||||
        ptr = port;
 | 
					            raddr_len++;
 | 
				
			||||||
        while (isspace(*ptr)) {
 | 
					 | 
				
			||||||
            ptr++;
 | 
					            ptr++;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (IS_NULL_PTR(ptr)) {
 | 
					        SKIP_WHILE(ptr, ':');
 | 
				
			||||||
            continue;
 | 
					
 | 
				
			||||||
        }
 | 
					        conn.remote_port = (strtoul(ptr, &ptr, 16) & 0xffff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SKIP_WHILE(ptr, ' ');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!((conn.remote_port && (flags & SIGAR_NETCONN_CLIENT)) ||
 | 
					        if (!((conn.remote_port && (flags & SIGAR_NETCONN_CLIENT)) ||
 | 
				
			||||||
              (!conn.remote_port && (flags & SIGAR_NETCONN_SERVER))))
 | 
					              (!conn.remote_port && (flags & SIGAR_NETCONN_SERVER))))
 | 
				
			||||||
@ -1824,7 +1801,7 @@ static int proc_net_read(sigar_net_connection_walker_t *walker,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        status = ip_format(conn.local_address,
 | 
					        status = ip_format(conn.local_address,
 | 
				
			||||||
                           sizeof(conn.local_address),
 | 
					                           sizeof(conn.local_address),
 | 
				
			||||||
                           laddr);
 | 
					                           laddr, laddr_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (status != SIGAR_OK) {
 | 
					        if (status != SIGAR_OK) {
 | 
				
			||||||
            return status;
 | 
					            return status;
 | 
				
			||||||
@ -1832,46 +1809,30 @@ static int proc_net_read(sigar_net_connection_walker_t *walker,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        status = ip_format(conn.remote_address,
 | 
					        status = ip_format(conn.remote_address,
 | 
				
			||||||
                           sizeof(conn.remote_address),
 | 
					                           sizeof(conn.remote_address),
 | 
				
			||||||
                           raddr);
 | 
					                           raddr, raddr_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (status != SIGAR_OK) {
 | 
					        if (status != SIGAR_OK) {
 | 
				
			||||||
            return status;
 | 
					            return status;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* SIGAR_TCP_* currently matches TCP_* in linux/tcp.h */
 | 
					        /* SIGAR_TCP_* currently matches TCP_* in linux/tcp.h */
 | 
				
			||||||
        sscanf(ptr, "%2x", &conn.state);
 | 
					        conn.state = hex2int(ptr, 2);
 | 
				
			||||||
        ptr = sigar_skip_token(ptr);
 | 
					        ptr += 2;
 | 
				
			||||||
        SIGAR_SKIP_SPACE(ptr);
 | 
					        SKIP_WHILE(ptr, ' ');
 | 
				
			||||||
        if (IS_NULL_PTR(ptr)) {
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (strlen(ptr) < ((HEX_ENT_LEN*2) + 1)) {
 | 
					        conn.send_queue = hex2int(ptr, HEX_ENT_LEN);
 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        conn.send_queue = hex2int(ptr);
 | 
					 | 
				
			||||||
        ptr += HEX_ENT_LEN+1; /* tx + ':' */;
 | 
					        ptr += HEX_ENT_LEN+1; /* tx + ':' */;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        conn.receive_queue = hex2int(ptr);
 | 
					        conn.receive_queue = hex2int(ptr, HEX_ENT_LEN);
 | 
				
			||||||
        ptr += HEX_ENT_LEN;
 | 
					        ptr += HEX_ENT_LEN;
 | 
				
			||||||
 | 
					        SKIP_WHILE(ptr, ' ');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SIGAR_SKIP_SPACE(ptr);
 | 
					        SKIP_PAST(ptr, ' '); /* tr:tm->whem */
 | 
				
			||||||
        if (IS_NULL_PTR(ptr)) {
 | 
					        SKIP_PAST(ptr, ' '); /* retrnsmt */
 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ptr = sigar_skip_multiple_token(ptr, 2); /* tr:tm->when retrnsmt */
 | 
					 | 
				
			||||||
        if (IS_NULL_PTR(ptr)) {
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        conn.uid = sigar_strtoul(ptr);
 | 
					        conn.uid = sigar_strtoul(ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ptr = sigar_skip_token(ptr);
 | 
					        SKIP_PAST(ptr, ' '); /* timeout */
 | 
				
			||||||
        if (IS_NULL_PTR(ptr)) {
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        conn.inode = sigar_strtoul(ptr);
 | 
					        conn.inode = sigar_strtoul(ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user