From d51ba0b5ab13aa09ab0482bd2dc63f39e8b40fad Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 5 Mar 2018 18:28:04 +0100 Subject: networking/interface.c: get rid of global data These were data/bss: static.proc_read 1 - -1 int_list 4 - -4 int_last 4 - -4 We never call display_interfaces() twice, thus code to not scan /proc twice never triggers. function old new delta do_if_print - 1998 +1998 display_interfaces 145 249 +104 static.proc_read 1 - -1 add_interface 104 103 -1 int_list 4 - -4 int_last 4 - -4 if_readlist_proc 560 542 -18 if_readconf 141 - -141 do_if_fetch 643 - -643 ife_print 1296 - -1296 ------------------------------------------------------------------------------ (add/remove: 1/6 grow/shrink: 1/2 up/down: 2102/-2108) Total: -6 bytes text data bss dec hex filename 933084 473 6844 940401 e5971 busybox_old 933087 473 6836 940396 e596c busybox_unstripped Signed-off-by: Denys Vlasenko --- networking/interface.c | 121 +++++++++++++++---------------------------------- 1 file changed, 36 insertions(+), 85 deletions(-) (limited to 'networking/interface.c') diff --git a/networking/interface.c b/networking/interface.c index ff99c2981..e5e55d8d4 100644 --- a/networking/interface.c +++ b/networking/interface.c @@ -341,8 +341,9 @@ struct interface { #endif }; - -static struct interface *int_list, *int_last; +struct iface_list { + struct interface *int_list, *int_last; +}; #if 0 @@ -373,11 +374,11 @@ static int nstrcmp(const char *a, const char *b) } #endif -static struct interface *add_interface(char *name) +static struct interface *add_interface(struct iface_list *ilist, char *name) { struct interface *ife, **nextp, *new; - for (ife = int_last; ife; ife = ife->prev) { + for (ife = ilist->int_last; ife; ife = ife->prev) { int n = /*n*/strcmp(ife->name, name); if (n == 0) @@ -388,13 +389,14 @@ static struct interface *add_interface(char *name) new = xzalloc(sizeof(*new)); strncpy_IFNAMSIZ(new->name, name); - nextp = ife ? &ife->next : &int_list; + + nextp = ife ? &ife->next : &ilist->int_list; new->prev = ife; new->next = *nextp; if (new->next) new->next->prev = new; else - int_last = new; + ilist->int_last = new; *nextp = new; return new; } @@ -500,12 +502,12 @@ static int procnetdev_version(char *buf) return 0; } -static int if_readconf(void) +static void if_readconf(struct iface_list *ilist) { int numreqs = 30; struct ifconf ifc; struct ifreq *ifr; - int n, err; + int n; int skfd; ifc.ifc_buf = NULL; @@ -518,10 +520,7 @@ static int if_readconf(void) ifc.ifc_len = sizeof(struct ifreq) * numreqs; ifc.ifc_buf = xrealloc(ifc.ifc_buf, ifc.ifc_len); - err = ioctl_or_warn(skfd, SIOCGIFCONF, &ifc); - if (err < 0) { - goto out; - } + xioctl(skfd, SIOCGIFCONF, &ifc); if (ifc.ifc_len == (int)(sizeof(struct ifreq) * numreqs)) { /* assume it overflowed and try again */ numreqs += 10; @@ -532,71 +531,54 @@ static int if_readconf(void) ifr = ifc.ifc_req; for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) { - add_interface(ifr->ifr_name); + add_interface(ilist, ifr->ifr_name); ifr++; } - err = 0; - out: close(skfd); free(ifc.ifc_buf); - return err; } -static int if_readlist_proc(char *target) +static int if_readlist_proc(struct iface_list *ilist, char *ifname) { - static smallint proc_read; - FILE *fh; char buf[512]; struct interface *ife; - int err, procnetdev_vsn; - - if (proc_read) - return 0; - if (!target) - proc_read = 1; + int procnetdev_vsn; + int ret; fh = fopen_or_warn(_PATH_PROCNET_DEV, "r"); if (!fh) { - return if_readconf(); + return 0; /* "not found" */ } fgets(buf, sizeof buf, fh); /* eat line */ fgets(buf, sizeof buf, fh); procnetdev_vsn = procnetdev_version(buf); - err = 0; + ret = 0; while (fgets(buf, sizeof buf, fh)) { char *s, name[IFNAMSIZ]; s = get_name(name, buf); - ife = add_interface(name); + ife = add_interface(ilist, name); get_dev_fields(s, ife, procnetdev_vsn); ife->statistics_valid = 1; - if (target && strcmp(target, name) == 0) + if (ifname && strcmp(ifname, name) == 0) { + ret = 1; /* found */ break; + } } - -#if 0 /* we trust kernel to not be buggy, /proc/net/dev reads never fail */ - if (ferror(fh)) { - bb_perror_msg(_PATH_PROCNET_DEV); - err = -1; - proc_read = 0; - } -#endif - fclose(fh); - return err; + return ret; } -static int if_readlist(void) +static void if_readlist(struct iface_list *ilist, char *ifname) { - int err = if_readlist_proc(NULL); + int found = if_readlist_proc(ilist, ifname); /* Needed in order to get ethN:M aliases */ - if (!err) - err = if_readconf(); - return err; + if (!found) + if_readconf(ilist); } /* Fetch the interface configuration from the kernel. */ @@ -1096,50 +1078,21 @@ static int do_if_print(struct interface *ife, int show_downed_too) return res; } -static struct interface *lookup_interface(char *name) -{ - struct interface *ife = NULL; - - if (if_readlist_proc(name) < 0) - return NULL; - ife = add_interface(name); - return ife; -} - -#ifdef UNUSED -static int for_all_interfaces(int (*doit) (struct interface *, void *), - void *cookie) -{ - struct interface *ife; - - if (!int_list) { - int err = if_readlist(); - if (err < 0) - return err; - } - for (ife = int_list; ife; ife = ife->next) { - int err = doit(ife, cookie); - if (err) - return err; - } - return 0; -} -#endif - int FAST_FUNC display_interfaces(char *ifname) { struct interface *ife; int res; + struct iface_list ilist; + + ilist.int_list = NULL; + ilist.int_last = NULL; + if_readlist(&ilist, ifname != IFNAME_SHOW_DOWNED_TOO ? ifname : NULL); if (!ifname || ifname == IFNAME_SHOW_DOWNED_TOO) { - /*res = for_all_interfaces(do_if_print, &interface_opt_a);*/ - if (!int_list) { - res = if_readlist(); - if (res < 0) - goto ret; - } - for (ife = int_list; ife; ife = ife->next) { + for (ife = ilist.int_list; ife; ife = ife->next) { + BUILD_BUG_ON((int)(intptr_t)IFNAME_SHOW_DOWNED_TOO != 1); + res = do_if_print(ife, (int)(intptr_t)ifname); if (res < 0) goto ret; @@ -1147,10 +1100,8 @@ int FAST_FUNC display_interfaces(char *ifname) return 0; } - ife = lookup_interface(ifname); - res = do_if_fetch(ife); - if (res >= 0) - ife_print(ife); + ife = add_interface(&ilist, ifname); + res = do_if_print(ife, /*show_downed_too:*/ 1); ret: return (res < 0); /* status < 0 == 1 -- error */ } -- cgit v1.2.3