CONTRIB: debug: also support reading values from stdin
This is convenient when processing large dumps, it allows to copy-paste
values to inspect from one window to another, or to directly transfer
a "show fd"/"show stream" output through sed. In order to do this, simply
pass "-" alone instead of the value and they will all be read one line at
a time from stdin. For example, in order to quickly print the different
set of connection flags from "show fd", this is sufficient:
sed -ne 's/^.* cflg=\([^ ]*\).*/\1/p' | contrib/debug/flags conn -
(cherry picked from commit e4f80a076c2d52a8b73f2f7350e047f6e39acd69)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 5399df74ed4ca5e7d847575beb4ad5817f0da9b3)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/contrib/debug/flags.c b/contrib/debug/flags.c
index 92facac..0a2fccf 100644
--- a/contrib/debug/flags.c
+++ b/contrib/debug/flags.c
@@ -412,7 +412,7 @@
void usage_exit(const char *name)
{
- fprintf(stderr, "Usage: %s [ana|chn|conn|cs|si|sierr|strm|task|txn]* [0x]value*\n", name);
+ fprintf(stderr, "Usage: %s [ana|chn|conn|cs|si|sierr|strm|task|txn]* { [+-][0x]value* | - }\n", name);
exit(1);
}
@@ -422,7 +422,10 @@
unsigned int show_as = 0;
unsigned int f;
const char *name = argv[0];
+ char line[20];
+ char *value;
int multi = 0;
+ int use_stdin = 0;
char *err;
while (argc > 0) {
@@ -442,14 +445,38 @@
if (argc > 1)
multi = 1;
+ if (strcmp(argv[0], "-") == 0)
+ use_stdin = 1;
+
while (argc > 0) {
- flags = strtoul(argv[0], &err, 0);
- if (!*argv[0] || *err) {
- fprintf(stderr, "Unparsable value: <%s>\n", argv[0]);
+ if (use_stdin) {
+ value = fgets(line, sizeof(line), stdin);
+ if (!value)
+ break;
+
+ /* skip common leading delimitors that slip from copy-paste */
+ while (*value == ' ' || *value == '\t' || *value == ':' || *value == '=')
+ value++;
+
+ /* stop at the end of the number and trim any C suffix like "UL" */
+ err = value;
+ while (*err == '-' || *err == '+' ||
+ (isalnum(*err) && toupper(*err) != 'U' && toupper(*err) != 'L'))
+ err++;
+ if (err)
+ *err = 0;
+ } else {
+ value = argv[0];
+ argv++; argc--;
+ }
+
+ flags = strtoul(value, &err, 0);
+ if (!*value || *err) {
+ fprintf(stderr, "Unparsable value: <%s>\n", value);
usage_exit(name);
}
- if (multi)
+ if (multi || use_stdin)
printf("### 0x%08x:\n", flags);
if (show_as & SHOW_AS_ANA) show_chn_ana(flags);
@@ -461,8 +488,6 @@
if (show_as & SHOW_AS_STRM) show_strm_flags(flags);
if (show_as & SHOW_AS_TASK) show_task_state(flags);
if (show_as & SHOW_AS_TXN) show_txn_flags(flags);
-
- argv++; argc--;
}
return 0;
}