[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <9da4822eb4ee33501d2d3970515189dda2b1ec0e.1540910943.git.sbrivio@redhat.com>
Date: Tue, 30 Oct 2018 16:05:19 +0100
From: Stefano Brivio <sbrivio@...hat.com>
To: David Ahern <dsahern@...il.com>
Cc: "Yoann P." <yoann.p.public@...il.com>,
Stephen Hemminger <stephen@...workplumber.org>,
netdev@...r.kernel.org
Subject: [PATCH iproute2 net-next 2/3] ss: Introduce option to display selected columns only
The new option --columns (short: -c) allows to select columns to be
displayed. Note that this doesn't affect the order in which columns are
displayed.
Reported-by: Yoann P. <yoann.p.public@...il.com>
Signed-off-by: Stefano Brivio <sbrivio@...hat.com>
---
man/man8/ss.8 | 5 +++++
misc/ss.c | 62 ++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 57 insertions(+), 10 deletions(-)
diff --git a/man/man8/ss.8 b/man/man8/ss.8
index 7a6572b17364..c987dec6bcd7 100644
--- a/man/man8/ss.8
+++ b/man/man8/ss.8
@@ -24,6 +24,11 @@ Output version information.
.B \-H, \-\-no-header
Suppress header line.
.TP
+.B \-c COLS, \-\-columns=COLS
+Only display selected columns, separated by commas. The following column names
+are understood: netid, state, local, lport, peer, pport, ext. This does not
+define the order of columns.
+.TP
.B \-n, \-\-numeric
Do not try to resolve service names.
.TP
diff --git a/misc/ss.c b/misc/ss.c
index c3f61ef66258..91be3c6db151 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -132,6 +132,7 @@ enum col_align {
struct column {
const enum col_align align;
+ const char *optname;
const char *header;
const char *ldelim;
int disabled;
@@ -140,15 +141,15 @@ struct column {
};
static struct column columns[] = {
- { ALIGN_LEFT, "Netid", "", 0, 0, 0 },
- { ALIGN_LEFT, "State", " ", 0, 0, 0 },
- { ALIGN_LEFT, "Recv-Q", " ", 0, 0, 0 },
- { ALIGN_LEFT, "Send-Q", " ", 0, 0, 0 },
- { ALIGN_RIGHT, "Local Address:", " ", 0, 0, 0 },
- { ALIGN_LEFT, "Port", "", 0, 0, 0 },
- { ALIGN_RIGHT, "Peer Address:", " ", 0, 0, 0 },
- { ALIGN_LEFT, "Port", "", 0, 0, 0 },
- { ALIGN_LEFT, "", "", 0, 0, 0 },
+ { ALIGN_LEFT, "netid", "Netid", "", 0, 0, 0 },
+ { ALIGN_LEFT, "state", "State", " ", 0, 0, 0 },
+ { ALIGN_LEFT, "recvq", "Recv-Q", " ", 0, 0, 0 },
+ { ALIGN_LEFT, "sendq", "Send-Q", " ", 0, 0, 0 },
+ { ALIGN_RIGHT, "local", "Local Address:", " ", 0, 0, 0 },
+ { ALIGN_LEFT, "lport", "Port", "", 0, 0, 0 },
+ { ALIGN_RIGHT, "peer", "Peer Address:", " ", 0, 0, 0 },
+ { ALIGN_LEFT, "pport", "Port", "", 0, 0, 0 },
+ { ALIGN_LEFT, "ext", "", "", 0, 0, 0 },
};
static struct column *current_field = columns;
@@ -1073,6 +1074,11 @@ static int field_is_last(struct column *f)
return f - columns == COL_MAX - 1;
}
+static int field_is_valid(struct column *f)
+{
+ return f >= columns && f - columns < COL_MAX;
+}
+
static void field_next(void)
{
field_flush(current_field);
@@ -4666,6 +4672,8 @@ static void _usage(FILE *dest)
"\n"
" -K, --kill forcibly close sockets, display what was closed\n"
" -H, --no-header Suppress header line\n"
+" -c, --columns=COLS display only COLS columns\n"
+" COLS := {netid|state|local|lport|peer|pport|ext}[,COLS]\n"
"\n"
" -A, --query=QUERY, --socket=QUERY\n"
" QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]\n"
@@ -4785,6 +4793,7 @@ static const struct option long_opts[] = {
{ "tipcinfo", 0, 0, OPT_TIPCINFO},
{ "kill", 0, 0, 'K' },
{ "no-header", 0, 0, 'H' },
+ { "columns", 1, 0, 'c' },
{ 0 }
};
@@ -4800,7 +4809,7 @@ int main(int argc, char *argv[])
int state_filter = 0;
while ((ch = getopt_long(argc, argv,
- "dhaletuwxnro460spbEf:miA:D:F:vVzZN:KHS",
+ "dhaletuwxnro460spbEf:miA:D:F:vVzZN:KHc:S",
long_opts, NULL)) != EOF) {
switch (ch) {
case 'n':
@@ -4966,6 +4975,39 @@ int main(int argc, char *argv[])
case 'H':
show_header = 0;
break;
+ case 'c':
+ {
+ struct column *f;
+ char *p, *p1;
+
+ if (!optarg) {
+ fprintf(stderr, "ss: No columns given.\n");
+ usage();
+ }
+
+ for (f = columns; field_is_valid(f); f++)
+ f->disabled = 1;
+
+ p = optarg;
+ do {
+ p1 = strchr(p, ',');
+ if (p1)
+ *p1 = 0;
+ for (f = columns; field_is_valid(f); f++) {
+ if (!strcmp(f->optname, p)) {
+ f->disabled = 0;
+ break;
+ }
+ }
+ if (!field_is_valid(f)) {
+ fprintf(stderr, "ss: No column %s\n",
+ p);
+ usage();
+ }
+ p = p1 + 1;
+ } while (p1);
+ break;
+ }
case 'h':
help();
case '?':
--
2.19.1
Powered by blists - more mailing lists