mirror of
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git
synced 2024-11-15 05:55:11 +08:00
8589eb4efd
Every tool in the iproute2 package have one or more function to show an help message to the user. Some of these functions print the help line by line with a series of printf call, e.g. ip/xfrm_state.c does 60 fprintf calls. If we group all the calls to a single one and just concatenate strings, we save a lot of libc calls and thus object size. The size difference of the compiled binaries calculated with bloat-o-meter is: ip/ip: add/remove: 0/0 grow/shrink: 5/15 up/down: 103/-4796 (-4693) Total: Before=672591, After=667898, chg -0.70% ip/rtmon: add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-54 (-54) Total: Before=48879, After=48825, chg -0.11% tc/tc: add/remove: 0/2 grow/shrink: 31/10 up/down: 882/-6133 (-5251) Total: Before=351912, After=346661, chg -1.49% bridge/bridge: add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-459 (-459) Total: Before=70502, After=70043, chg -0.65% misc/lnstat: add/remove: 0/1 grow/shrink: 1/0 up/down: 48/-486 (-438) Total: Before=9960, After=9522, chg -4.40% tipc/tipc: add/remove: 0/0 grow/shrink: 1/1 up/down: 18/-62 (-44) Total: Before=79182, After=79138, chg -0.06% While at it, indent some strings which were starting at column 0, and use tabs where possible, to have a consistent style across helps. Signed-off-by: Matteo Croce <mcroce@redhat.com> Signed-off-by: David Ahern <dsahern@gmail.com>
109 lines
2.0 KiB
C
109 lines
2.0 KiB
C
/*
|
|
* tc_exec.c "tc exec".
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or (at your option) any later version.
|
|
*
|
|
* Authors: Daniel Borkmann <daniel@iogearbox.net>
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <dlfcn.h>
|
|
|
|
#include "utils.h"
|
|
|
|
#include "tc_util.h"
|
|
#include "tc_common.h"
|
|
|
|
static struct exec_util *exec_list;
|
|
static void *BODY;
|
|
|
|
static void usage(void)
|
|
{
|
|
fprintf(stderr,
|
|
"Usage: tc exec [ EXEC_TYPE ] [ help | OPTIONS ]\n"
|
|
"Where:\n"
|
|
"EXEC_TYPE := { bpf | etc. }\n"
|
|
"OPTIONS := ... try tc exec <desired EXEC_KIND> help\n");
|
|
}
|
|
|
|
static int parse_noeopt(struct exec_util *eu, int argc, char **argv)
|
|
{
|
|
if (argc) {
|
|
fprintf(stderr, "Unknown exec \"%s\", hence option \"%s\" is unparsable\n",
|
|
eu->id, *argv);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct exec_util *get_exec_kind(const char *name)
|
|
{
|
|
struct exec_util *eu;
|
|
char buf[256];
|
|
void *dlh;
|
|
|
|
for (eu = exec_list; eu; eu = eu->next)
|
|
if (strcmp(eu->id, name) == 0)
|
|
return eu;
|
|
|
|
snprintf(buf, sizeof(buf), "%s/e_%s.so", get_tc_lib(), name);
|
|
dlh = dlopen(buf, RTLD_LAZY);
|
|
if (dlh == NULL) {
|
|
dlh = BODY;
|
|
if (dlh == NULL) {
|
|
dlh = BODY = dlopen(NULL, RTLD_LAZY);
|
|
if (dlh == NULL)
|
|
goto noexist;
|
|
}
|
|
}
|
|
|
|
snprintf(buf, sizeof(buf), "%s_exec_util", name);
|
|
eu = dlsym(dlh, buf);
|
|
if (eu == NULL)
|
|
goto noexist;
|
|
reg:
|
|
eu->next = exec_list;
|
|
exec_list = eu;
|
|
|
|
return eu;
|
|
noexist:
|
|
eu = calloc(1, sizeof(*eu));
|
|
if (eu) {
|
|
strncpy(eu->id, name, sizeof(eu->id) - 1);
|
|
eu->parse_eopt = parse_noeopt;
|
|
goto reg;
|
|
}
|
|
|
|
return eu;
|
|
}
|
|
|
|
int do_exec(int argc, char **argv)
|
|
{
|
|
struct exec_util *eu;
|
|
char kind[FILTER_NAMESZ] = {};
|
|
|
|
if (argc < 1) {
|
|
fprintf(stderr, "No command given, try \"tc exec help\".\n");
|
|
return -1;
|
|
}
|
|
|
|
if (matches(*argv, "help") == 0) {
|
|
usage();
|
|
return 0;
|
|
}
|
|
|
|
strncpy(kind, *argv, sizeof(kind) - 1);
|
|
|
|
eu = get_exec_kind(kind);
|
|
|
|
argc--;
|
|
argv++;
|
|
|
|
return eu->parse_eopt(eu, argc, argv);
|
|
}
|