From 7221c8c22dd527700204eb5cc4d0651af4273f4f Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Mon, 3 Dec 2007 10:45:14 +0000 Subject: lineedit: reduce stack usage netstat: reduce stack usage; fix handling of NULs in unix socket filenames static.has_inode 1 - -1 do_info 119 116 -3 deinit_S 60 51 -9 unix_do_one 578 451 -127 parse_and_put_prompt 966 825 -141 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 0/4 up/down: 0/-281) Total: -281 bytes --- networking/netstat.c | 70 +++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 33 deletions(-) (limited to 'networking/netstat.c') diff --git a/networking/netstat.c b/networking/netstat.c index 11f141947..d86c2ff5e 100644 --- a/networking/netstat.c +++ b/networking/netstat.c @@ -148,7 +148,7 @@ static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int return host_port; } -static void tcp_do_one(int lnr, const char *line) +static void tcp_do_one(int lnr, char *line) { char local_addr[64], rem_addr[64]; char more[512]; @@ -201,7 +201,7 @@ static void tcp_do_one(int lnr, const char *line) } } -static void udp_do_one(int lnr, const char *line) +static void udp_do_one(int lnr, char *line) { char local_addr[64], rem_addr[64]; const char *state_str; @@ -283,7 +283,7 @@ static void udp_do_one(int lnr, const char *line) } } -static void raw_do_one(int lnr, const char *line) +static void raw_do_one(int lnr, char *line) { char local_addr[64], rem_addr[64]; char more[512]; @@ -339,31 +339,37 @@ static void raw_do_one(int lnr, const char *line) } } -static void unix_do_one(int nr, const char *line) +static void unix_do_one(int nr, char *line) { - static smallint has_inode = 0; - - char path[PATH_MAX], ss_flags[32]; - const char *ss_proto, *ss_state, *ss_type; - int num, state, type, inode; - void *d; unsigned long refcnt, proto, unix_flags; + unsigned long inode; + int type, state; + int num, path_ofs; + void *d; + const char *ss_proto, *ss_state, *ss_type; + char ss_flags[32]; - if (nr == 0) { - if (strstr(line, "Inode")) - has_inode = 1; - return; + if (nr == 0) + return; /* skip header */ + + { + char *last = last_char_is(line, '\n'); + if (last) + *last = '\0'; } - path[0] = '\0'; - num = sscanf(line, "%p: %lX %lX %lX %X %X %d %s", - &d, &refcnt, &proto, &unix_flags, &type, &state, &inode, path); - if (num < 6) { - bb_error_msg("warning, got bogus unix line"); + + /* 2.6.15 may report lines like "... @/tmp/fam-user-^@^@^@^@^@^@^@..." + * (those ^@ are NUL bytes). fgets sees them as tons of empty lines. */ + if (!line[0]) return; - } - if (!has_inode) - sprintf(path, "%d", inode); + path_ofs = 0; /* paranoia */ + num = sscanf(line, "%p: %lX %lX %lX %X %X %lu %n", + &d, &refcnt, &proto, &unix_flags, &type, &state, &inode, &path_ofs); + if (num < 7) { + bb_error_msg("got bogus unix line '%s'", line); + return; + } if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) != (NETSTAT_LISTENING|NETSTAT_CONNECTED)) { if ((state == SS_UNCONNECTED) && (unix_flags & SO_ACCEPTCON)) { if (!(flags & NETSTAT_LISTENING)) @@ -439,13 +445,9 @@ static void unix_do_one(int nr, const char *line) strcat(ss_flags, "N "); strcat(ss_flags, "]"); - printf("%-5s %-6ld %-11s %-10s %-13s ", - ss_proto, refcnt, ss_flags, ss_type, ss_state); - if (has_inode) - printf("%-6d ", inode); - else - printf("- "); - puts(path); + printf("%-5s %-6ld %-11s %-10s %-13s %6lu %s\n", + ss_proto, refcnt, ss_flags, ss_type, ss_state, inode, + line + path_ofs); } #define _PATH_PROCNET_UDP "/proc/net/udp" @@ -456,10 +458,11 @@ static void unix_do_one(int nr, const char *line) #define _PATH_PROCNET_RAW6 "/proc/net/raw6" #define _PATH_PROCNET_UNIX "/proc/net/unix" -static void do_info(const char *file, const char *name, void (*proc)(int, const char *)) +static void do_info(const char *file, const char *name, void (*proc)(int, char *)) { - int lnr = 0; + int lnr; FILE *procinfo; + char *buffer; procinfo = fopen(file, "r"); if (procinfo == NULL) { @@ -470,13 +473,14 @@ static void do_info(const char *file, const char *name, void (*proc)(int, const } return; } + lnr = 0; do { - char *buffer = xmalloc_fgets(procinfo); + buffer = xmalloc_fgets(procinfo); if (buffer) { (proc)(lnr++, buffer); free(buffer); } - } while (!feof(procinfo)); + } while (buffer); fclose(procinfo); } -- cgit v1.2.3