aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-03-05 18:28:04 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-03-05 18:30:33 +0100
commitd51ba0b5ab13aa09ab0482bd2dc63f39e8b40fad (patch)
tree96a325fe39b26b2af47eced6c33e85cdc4cfa6d3
parent82ec89480d524a219ad027d1f7c5aa42cc6373d5 (diff)
downloadbusybox-w32-d51ba0b5ab13aa09ab0482bd2dc63f39e8b40fad.tar.gz
busybox-w32-d51ba0b5ab13aa09ab0482bd2dc63f39e8b40fad.tar.bz2
busybox-w32-d51ba0b5ab13aa09ab0482bd2dc63f39e8b40fad.zip
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 <vda.linux@googlemail.com>
-rw-r--r--networking/interface.c121
1 files changed, 36 insertions, 85 deletions
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 {
341#endif 341#endif
342}; 342};
343 343
344 344struct iface_list {
345static struct interface *int_list, *int_last; 345 struct interface *int_list, *int_last;
346};
346 347
347 348
348#if 0 349#if 0
@@ -373,11 +374,11 @@ static int nstrcmp(const char *a, const char *b)
373} 374}
374#endif 375#endif
375 376
376static struct interface *add_interface(char *name) 377static struct interface *add_interface(struct iface_list *ilist, char *name)
377{ 378{
378 struct interface *ife, **nextp, *new; 379 struct interface *ife, **nextp, *new;
379 380
380 for (ife = int_last; ife; ife = ife->prev) { 381 for (ife = ilist->int_last; ife; ife = ife->prev) {
381 int n = /*n*/strcmp(ife->name, name); 382 int n = /*n*/strcmp(ife->name, name);
382 383
383 if (n == 0) 384 if (n == 0)
@@ -388,13 +389,14 @@ static struct interface *add_interface(char *name)
388 389
389 new = xzalloc(sizeof(*new)); 390 new = xzalloc(sizeof(*new));
390 strncpy_IFNAMSIZ(new->name, name); 391 strncpy_IFNAMSIZ(new->name, name);
391 nextp = ife ? &ife->next : &int_list; 392
393 nextp = ife ? &ife->next : &ilist->int_list;
392 new->prev = ife; 394 new->prev = ife;
393 new->next = *nextp; 395 new->next = *nextp;
394 if (new->next) 396 if (new->next)
395 new->next->prev = new; 397 new->next->prev = new;
396 else 398 else
397 int_last = new; 399 ilist->int_last = new;
398 *nextp = new; 400 *nextp = new;
399 return new; 401 return new;
400} 402}
@@ -500,12 +502,12 @@ static int procnetdev_version(char *buf)
500 return 0; 502 return 0;
501} 503}
502 504
503static int if_readconf(void) 505static void if_readconf(struct iface_list *ilist)
504{ 506{
505 int numreqs = 30; 507 int numreqs = 30;
506 struct ifconf ifc; 508 struct ifconf ifc;
507 struct ifreq *ifr; 509 struct ifreq *ifr;
508 int n, err; 510 int n;
509 int skfd; 511 int skfd;
510 512
511 ifc.ifc_buf = NULL; 513 ifc.ifc_buf = NULL;
@@ -518,10 +520,7 @@ static int if_readconf(void)
518 ifc.ifc_len = sizeof(struct ifreq) * numreqs; 520 ifc.ifc_len = sizeof(struct ifreq) * numreqs;
519 ifc.ifc_buf = xrealloc(ifc.ifc_buf, ifc.ifc_len); 521 ifc.ifc_buf = xrealloc(ifc.ifc_buf, ifc.ifc_len);
520 522
521 err = ioctl_or_warn(skfd, SIOCGIFCONF, &ifc); 523 xioctl(skfd, SIOCGIFCONF, &ifc);
522 if (err < 0) {
523 goto out;
524 }
525 if (ifc.ifc_len == (int)(sizeof(struct ifreq) * numreqs)) { 524 if (ifc.ifc_len == (int)(sizeof(struct ifreq) * numreqs)) {
526 /* assume it overflowed and try again */ 525 /* assume it overflowed and try again */
527 numreqs += 10; 526 numreqs += 10;
@@ -532,71 +531,54 @@ static int if_readconf(void)
532 531
533 ifr = ifc.ifc_req; 532 ifr = ifc.ifc_req;
534 for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) { 533 for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) {
535 add_interface(ifr->ifr_name); 534 add_interface(ilist, ifr->ifr_name);
536 ifr++; 535 ifr++;
537 } 536 }
538 err = 0;
539 537
540 out:
541 close(skfd); 538 close(skfd);
542 free(ifc.ifc_buf); 539 free(ifc.ifc_buf);
543 return err;
544} 540}
545 541
546static int if_readlist_proc(char *target) 542static int if_readlist_proc(struct iface_list *ilist, char *ifname)
547{ 543{
548 static smallint proc_read;
549
550 FILE *fh; 544 FILE *fh;
551 char buf[512]; 545 char buf[512];
552 struct interface *ife; 546 struct interface *ife;
553 int err, procnetdev_vsn; 547 int procnetdev_vsn;
554 548 int ret;
555 if (proc_read)
556 return 0;
557 if (!target)
558 proc_read = 1;
559 549
560 fh = fopen_or_warn(_PATH_PROCNET_DEV, "r"); 550 fh = fopen_or_warn(_PATH_PROCNET_DEV, "r");
561 if (!fh) { 551 if (!fh) {
562 return if_readconf(); 552 return 0; /* "not found" */
563 } 553 }
564 fgets(buf, sizeof buf, fh); /* eat line */ 554 fgets(buf, sizeof buf, fh); /* eat line */
565 fgets(buf, sizeof buf, fh); 555 fgets(buf, sizeof buf, fh);
566 556
567 procnetdev_vsn = procnetdev_version(buf); 557 procnetdev_vsn = procnetdev_version(buf);
568 558
569 err = 0; 559 ret = 0;
570 while (fgets(buf, sizeof buf, fh)) { 560 while (fgets(buf, sizeof buf, fh)) {
571 char *s, name[IFNAMSIZ]; 561 char *s, name[IFNAMSIZ];
572 562
573 s = get_name(name, buf); 563 s = get_name(name, buf);
574 ife = add_interface(name); 564 ife = add_interface(ilist, name);
575 get_dev_fields(s, ife, procnetdev_vsn); 565 get_dev_fields(s, ife, procnetdev_vsn);
576 ife->statistics_valid = 1; 566 ife->statistics_valid = 1;
577 if (target && strcmp(target, name) == 0) 567 if (ifname && strcmp(ifname, name) == 0) {
568 ret = 1; /* found */
578 break; 569 break;
570 }
579 } 571 }
580
581#if 0 /* we trust kernel to not be buggy, /proc/net/dev reads never fail */
582 if (ferror(fh)) {
583 bb_perror_msg(_PATH_PROCNET_DEV);
584 err = -1;
585 proc_read = 0;
586 }
587#endif
588
589 fclose(fh); 572 fclose(fh);
590 return err; 573 return ret;
591} 574}
592 575
593static int if_readlist(void) 576static void if_readlist(struct iface_list *ilist, char *ifname)
594{ 577{
595 int err = if_readlist_proc(NULL); 578 int found = if_readlist_proc(ilist, ifname);
596 /* Needed in order to get ethN:M aliases */ 579 /* Needed in order to get ethN:M aliases */
597 if (!err) 580 if (!found)
598 err = if_readconf(); 581 if_readconf(ilist);
599 return err;
600} 582}
601 583
602/* Fetch the interface configuration from the kernel. */ 584/* Fetch the interface configuration from the kernel. */
@@ -1096,50 +1078,21 @@ static int do_if_print(struct interface *ife, int show_downed_too)
1096 return res; 1078 return res;
1097} 1079}
1098 1080
1099static struct interface *lookup_interface(char *name)
1100{
1101 struct interface *ife = NULL;
1102
1103 if (if_readlist_proc(name) < 0)
1104 return NULL;
1105 ife = add_interface(name);
1106 return ife;
1107}
1108
1109#ifdef UNUSED
1110static int for_all_interfaces(int (*doit) (struct interface *, void *),
1111 void *cookie)
1112{
1113 struct interface *ife;
1114
1115 if (!int_list) {
1116 int err = if_readlist();
1117 if (err < 0)
1118 return err;
1119 }
1120 for (ife = int_list; ife; ife = ife->next) {
1121 int err = doit(ife, cookie);
1122 if (err)
1123 return err;
1124 }
1125 return 0;
1126}
1127#endif
1128
1129int FAST_FUNC display_interfaces(char *ifname) 1081int FAST_FUNC display_interfaces(char *ifname)
1130{ 1082{
1131 struct interface *ife; 1083 struct interface *ife;
1132 int res; 1084 int res;
1085 struct iface_list ilist;
1086
1087 ilist.int_list = NULL;
1088 ilist.int_last = NULL;
1089 if_readlist(&ilist, ifname != IFNAME_SHOW_DOWNED_TOO ? ifname : NULL);
1133 1090
1134 if (!ifname || ifname == IFNAME_SHOW_DOWNED_TOO) { 1091 if (!ifname || ifname == IFNAME_SHOW_DOWNED_TOO) {
1135 /*res = for_all_interfaces(do_if_print, &interface_opt_a);*/ 1092 for (ife = ilist.int_list; ife; ife = ife->next) {
1136 if (!int_list) { 1093
1137 res = if_readlist();
1138 if (res < 0)
1139 goto ret;
1140 }
1141 for (ife = int_list; ife; ife = ife->next) {
1142 BUILD_BUG_ON((int)(intptr_t)IFNAME_SHOW_DOWNED_TOO != 1); 1094 BUILD_BUG_ON((int)(intptr_t)IFNAME_SHOW_DOWNED_TOO != 1);
1095
1143 res = do_if_print(ife, (int)(intptr_t)ifname); 1096 res = do_if_print(ife, (int)(intptr_t)ifname);
1144 if (res < 0) 1097 if (res < 0)
1145 goto ret; 1098 goto ret;
@@ -1147,10 +1100,8 @@ int FAST_FUNC display_interfaces(char *ifname)
1147 return 0; 1100 return 0;
1148 } 1101 }
1149 1102
1150 ife = lookup_interface(ifname); 1103 ife = add_interface(&ilist, ifname);
1151 res = do_if_fetch(ife); 1104 res = do_if_print(ife, /*show_downed_too:*/ 1);
1152 if (res >= 0)
1153 ife_print(ife);
1154 ret: 1105 ret:
1155 return (res < 0); /* status < 0 == 1 -- error */ 1106 return (res < 0); /* status < 0 == 1 -- error */
1156} 1107}