From: Masatake YAMATO Date: Tue, 28 Feb 2023 13:56:57 +0000 (+0900) Subject: lsfd: implement -i/--inet option X-Git-Tag: v2.39-rc1~46^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cd7f9b8670a63ae9ce3f3bd1fffbc613791fb071;p=thirdparty%2Futil-linux.git lsfd: implement -i/--inet option Reviewed-by: Thomas Weißschuh Signed-off-by: Masatake YAMATO --- diff --git a/misc-utils/lsfd.1.adoc b/misc-utils/lsfd.1.adoc index 5ac4bd8a6d..28c11115bb 100644 --- a/misc-utils/lsfd.1.adoc +++ b/misc-utils/lsfd.1.adoc @@ -65,6 +65,9 @@ and *-p* option, e.g. -p 1, may print the same output but using *-p* option is much more efficient because *-p* option works at a much earlier stage of processing than the *-Q* option. +*-i[4|6]*, *--inet[=4|6]:: +List only IPv4 sockets and/or IPv6 sockets. + *-Q*, *--filter* _expr_:: Print only the files matching the condition represented by the _expr_. See also *FILTER EXAMPLES*. diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index b2cf0963ee..8c366e68e2 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -1443,19 +1443,20 @@ static void __attribute__((__noreturn__)) usage(void) fprintf(out, _(" %s [options]\n"), program_invocation_short_name); fputs(USAGE_OPTIONS, out); - fputs(_(" -l, --threads list in threads level\n"), out); - fputs(_(" -J, --json use JSON output format\n"), out); - fputs(_(" -n, --noheadings don't print headings\n"), out); - fputs(_(" -o, --output output columns\n"), out); - fputs(_(" -r, --raw use raw output format\n"), out); - fputs(_(" -u, --notruncate don't truncate text in columns\n"), out); - fputs(_(" -p, --pid collect information only specified processes\n"), out); - fputs(_(" -Q, --filter apply display filter\n"), out); - fputs(_(" --debug-filter dump the internal data structure of filter and exit\n"), out); - fputs(_(" -C, --counter :\n" - " define custom counter for --summary output\n"), out); - fputs(_(" --dump-counters dump counter definitions\n"), out); - fputs(_(" --summary[=when] print summary information (only, append, or never)\n"), out); + fputs(_(" -l, --threads list in threads level\n"), out); + fputs(_(" -J, --json use JSON output format\n"), out); + fputs(_(" -n, --noheadings don't print headings\n"), out); + fputs(_(" -o, --output output columns\n"), out); + fputs(_(" -r, --raw use raw output format\n"), out); + fputs(_(" -u, --notruncate don't truncate text in columns\n"), out); + fputs(_(" -p, --pid collect information only specified processes\n"), out); + fputs(_(" -i[4|6], --inet[=4|6] list only IPv4 and/or IPv6 sockets\n"), out); + fputs(_(" -Q, --filter apply display filter\n"), out); + fputs(_(" --debug-filter dump the internal data structure of filter and exit\n"), out); + fputs(_(" -C, --counter :\n" + " define custom counter for --summary output\n"), out); + fputs(_(" --dump-counters dump counter definitions\n"), out); + fputs(_(" --summary[=] print summary information (only, append, or never)\n"), out); fputs(USAGE_SEPARATOR, out); printf(USAGE_HELP_OPTIONS(23)); @@ -1701,6 +1702,29 @@ static void attach_xinfos(struct list_head *procs) } } +/* Filter expressions for implementing -i option. + * + * To list up the protocol names, use the following command line + * + * cd linux/net; + * find . -type f -exec grep -A 1 --color=auto -nH --null -e 'struct proto .*{' \{\} + + * + */ +#define INET_SUBEXP_BEGIN "(SOCK.PROTONAME =~ \"^(" +#define INET4_REG "TCP|UDP|RAW|PING|UDP-Lite|SCTP|DCCP|L2TP/IP|SMC" +#define INET6_REG "TCPv6|UDPv6|RAWv6|PINGv6|UDPLITEv6|SCTPv6|DCCPv6|L2TP/IPv6|SMC6" +#define INET_SUBEXP_END ")$\")" + +static const char *inet4_subexpr = INET_SUBEXP_BEGIN + INET4_REG + INET_SUBEXP_END; +static const char *inet6_subexpr = INET_SUBEXP_BEGIN + INET6_REG + INET_SUBEXP_END; +static const char *inet46_subexpr = INET_SUBEXP_BEGIN + INET4_REG "|" INET6_REG + INET_SUBEXP_END; + int main(int argc, char *argv[]) { int c; @@ -1734,6 +1758,7 @@ int main(int argc, char *argv[]) { "threads", no_argument, NULL, 'l' }, { "notruncate", no_argument, NULL, 'u' }, { "pid", required_argument, NULL, 'p' }, + { "inet", optional_argument, NULL, 'i' }, { "filter", required_argument, NULL, 'Q' }, { "debug-filter",no_argument, NULL, OPT_DEBUG_FILTER }, { "summary", optional_argument, NULL, OPT_SUMMARY }, @@ -1747,7 +1772,7 @@ int main(int argc, char *argv[]) textdomain(PACKAGE); close_stdout_atexit(); - while ((c = getopt_long(argc, argv, "no:JrVhluQ:p:C:s", longopts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "no:JrVhluQ:p:i::C:s", longopts, NULL)) != -1) { switch (c) { case 'n': ctl.noheadings = 1; @@ -1770,6 +1795,22 @@ int main(int argc, char *argv[]) case 'p': parse_pids(optarg, &pids, &n_pids); break; + case 'i': { + const char *subexpr = NULL; + if (optarg == NULL) + subexpr = inet46_subexpr; + else if (strcmp(optarg, "4") == 0) + subexpr = inet4_subexpr; + else if (strcmp(optarg, "6") == 0) + subexpr = inet6_subexpr; + else + errx(EXIT_FAILURE, + _("unknown -i/--inet argument: %s"), + optarg); + + append_filter_expr(&filter_expr, subexpr, true); + break; + } case 'Q': append_filter_expr(&filter_expr, optarg, true); break;