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 | } |
