diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-03-05 18:28:04 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-03-05 18:30:33 +0100 |
commit | d51ba0b5ab13aa09ab0482bd2dc63f39e8b40fad (patch) | |
tree | 96a325fe39b26b2af47eced6c33e85cdc4cfa6d3 | |
parent | 82ec89480d524a219ad027d1f7c5aa42cc6373d5 (diff) | |
download | busybox-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.c | 121 |
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 | 344 | struct iface_list { | |
345 | static 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 | ||
376 | static struct interface *add_interface(char *name) | 377 | static 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 | ||
503 | static int if_readconf(void) | 505 | static 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 | ||
546 | static int if_readlist_proc(char *target) | 542 | static 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 | ||
593 | static int if_readlist(void) | 576 | static 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 | ||
1099 | static 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 | ||
1110 | static 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 | |||
1129 | int FAST_FUNC display_interfaces(char *ifname) | 1081 | int 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 | } |