Re: [PATCH 1/3] irqtop: add batch mode support
zhenwei pi <[email protected]>
| Newsgroups | org.kernel.vger.util-linux |
|---|---|
| Message-ID | <[email protected]> |
Hi Joe, I'm a little confused about 'batch'... Rather than the original terminal formatted style, the new change brings 'raw' style? What about 'raw'? Hi Karel, what do you think of this? On 2/27/25 12:49, Joe Jin wrote: > Add batch mode support, which could be useful for sending output to > other programs or to a file. > > Signed-off-by: Joe Jin <[email protected]> > Cc: Zhenwei Pi <[email protected]> > Cc: Sami Kerola <[email protected]> > --- > bash-completion/irqtop | 6 +++- > sys-utils/irqtop.1.adoc | 3 ++ > sys-utils/irqtop.c | 79 ++++++++++++++++++++++++++++------------- > 3 files changed, 63 insertions(+), 25 deletions(-) > > diff --git a/bash-completion/irqtop b/bash-completion/irqtop > index b9e454d4c..215281ee8 100644 > --- a/bash-completion/irqtop > +++ b/bash-completion/irqtop > @@ -5,6 +5,9 @@ _irqtop_module() > cur="${COMP_WORDS[COMP_CWORD]}" > prev="${COMP_WORDS[COMP_CWORD-1]}" > case $prev in > + '-b'|'--batch') > + return 0 > + ;; > '-c'|'--cpu-stat') > COMPREPLY=( $(compgen -W "auto enable disable" -- $cur) ) > return 0 > @@ -40,7 +43,8 @@ _irqtop_module() > return 0 > ;; > esac > - OPTS=" --cpu-stat > + OPTS=" --batch > + --cpu-stat > --cpu-list > --delay > --sort > diff --git a/sys-utils/irqtop.1.adoc b/sys-utils/irqtop.1.adoc > index 443e23b84..e81f4fbb6 100644 > --- a/sys-utils/irqtop.1.adoc > +++ b/sys-utils/irqtop.1.adoc > @@ -25,6 +25,9 @@ The default output is subject to change. So whenever possible, you should avoid > *-o*, *--output* _list_:: > Specify which output columns to print. Use *--help* to get a list of all supported columns. The default list of columns may be extended if list is specified in the format _+list_. > > +*-b*, *--batch*:: > +Starts irqtop in batch mode, which could be useful for sending output to other programs or to a file. > + > *-c*, *--cpu-stat* _mode_:: > Show per-cpu statistics by specified mode. Available modes are: *auto*, *enable*, *disable*. The default option *auto* detects the width of window, then shows the per-cpu statistics if the width of window is large enough to show a full line of statistics. > > diff --git a/sys-utils/irqtop.c b/sys-utils/irqtop.c > index 8fbedb16a..00bf8fe50 100644 > --- a/sys-utils/irqtop.c > +++ b/sys-utils/irqtop.c > @@ -83,10 +83,22 @@ struct irqtop_ctl { > cpu_set_t *cpuset; > > enum irqtop_cpustat_mode cpustat_mode; > + bool batch; > bool request_exit, > softirq; > }; > > +#define irqtop_batch_mode(ctl) ((ctl)->batch == true) > +#define irqtop_printf(ctl, fmt, args...) \ > + do { \ > + if (irqtop_batch_mode(ctl)) \ > + fprintf(stdout, fmt, ##args); \ > + else { \ > + wprintw(ctl->win, fmt, ##args); \ > + } \ > + }while(0) > + > + > /* user's input parser */ > static void parse_input(struct irqtop_ctl *ctl, struct irq_output *out, char c) > { > @@ -128,16 +140,19 @@ static int update_screen(struct irqtop_ctl *ctl, struct irq_output *out) > scols_table_enable_nowrap(cpus, 1); > } > > - /* print header */ > - move(0, 0); > strtime_iso(&now, ISO_TIMESTAMP, timestr, sizeof(timestr)); > - wprintw(ctl->win, _("irqtop | total: %ld delta: %ld | %s | %s\n\n"), > + if (!irqtop_batch_mode(ctl)) > + move(0, 0); > + > + /* print header */ > + irqtop_printf(ctl, _("irqtop | total: %ld delta: %ld | %s | %s\n\n"), > stat->total_irq, stat->delta_irq, ctl->hostname, timestr); > > + > /* print cpus table or not by -c option */ > if (cpus) { > scols_print_table_to_string(cpus, &data); > - wprintw(ctl->win, "%s\n\n", data); > + irqtop_printf(ctl, "%s\n\n", data); > free(data); > } > > @@ -149,13 +164,15 @@ static int update_screen(struct irqtop_ctl *ctl, struct irq_output *out) > if (p) { > /* print header in reverse mode */ > *p = '\0'; > - attron(A_REVERSE); > - wprintw(ctl->win, "%s\n", data); > - attroff(A_REVERSE); > + if (!irqtop_batch_mode(ctl)) > + attron(A_REVERSE); > + irqtop_printf(ctl, "%s\n", data); > + if (!irqtop_batch_mode(ctl)) > + attroff(A_REVERSE); > data = p + 1; > } > > - wprintw(ctl->win, "%s", data); > + irqtop_printf(ctl, "%s\n", data); > free(data0); > > /* clean up */ > @@ -212,7 +229,8 @@ static int event_loop(struct irqtop_ctl *ctl, struct irq_output *out) > err(EXIT_FAILURE, _("epoll_ctl failed")); > > retval |= update_screen(ctl, out); > - refresh(); > + if (!irqtop_batch_mode(ctl)) > + refresh(); > > while (!ctl->request_exit) { > const ssize_t nr_events = epoll_wait(efd, events, MAX_EVENTS, -1); > @@ -227,10 +245,12 @@ static int event_loop(struct irqtop_ctl *ctl, struct irq_output *out) > continue; > } > if (siginfo.ssi_signo == SIGWINCH) { > - get_terminal_dimension(&ctl->cols, &ctl->rows); > + if (!irqtop_batch_mode(ctl)) { > + get_terminal_dimension(&ctl->cols, &ctl->rows); > #if HAVE_RESIZETERM > - resizeterm(ctl->rows, ctl->cols); > + resizeterm(ctl->rows, ctl->cols); > #endif > + } > } > else { > ctl->request_exit = 1; > @@ -245,7 +265,8 @@ static int event_loop(struct irqtop_ctl *ctl, struct irq_output *out) > } else > abort(); > retval |= update_screen(ctl, out); > - refresh(); > + if (!irqtop_batch_mode(ctl)) > + refresh(); > } > } > return retval; > @@ -260,6 +281,7 @@ static void __attribute__((__noreturn__)) usage(void) > puts(_("Interactive utility to display kernel interrupt information.")); > > fputs(USAGE_OPTIONS, stdout); > + fputs(_(" -b, --batch batch mode\n"), stdout); > fputs(_(" -c, --cpu-stat <mode> show per-cpu stat (auto, enable, disable)\n"), stdout); > fputs(_(" -C, --cpu-list <list> specify cpus in list format\n"), stdout); > fputs(_(" -d, --delay <secs> delay updates\n"), stdout); > @@ -291,6 +313,7 @@ static void parse_args( struct irqtop_ctl *ctl, > { > const char *outarg = NULL; > static const struct option longopts[] = { > + {"batch", no_argument, NULL, 'b'}, > {"cpu-stat", required_argument, NULL, 'c'}, > {"cpu-list", required_argument, NULL, 'C'}, > {"delay", required_argument, NULL, 'd'}, > @@ -304,8 +327,11 @@ static void parse_args( struct irqtop_ctl *ctl, > }; > int o; > > - while ((o = getopt_long(argc, argv, "c:C:d:o:s:St:hV", longopts, NULL)) != -1) { > + while ((o = getopt_long(argc, argv, "bc:C:d:o:s:St:hV", longopts, NULL)) != -1) { > switch (o) { > + case 'b': > + ctl->batch = true; > + break; > case 'c': > if (!strcmp(optarg, "auto")) > ctl->cpustat_mode = IRQTOP_CPUSTAT_AUTO; > @@ -394,16 +420,18 @@ int main(int argc, char **argv) > > parse_args(&ctl, &out, argc, argv); > > - is_tty = isatty(STDIN_FILENO); > - if (is_tty && tcgetattr(STDIN_FILENO, &saved_tty) == -1) > - fputs(_("terminal setting retrieval"), stdout); > + if (ctl.batch == false) { > + is_tty = isatty(STDIN_FILENO); > + if (is_tty && tcgetattr(STDIN_FILENO, &saved_tty) == -1) > + fputs(_("terminal setting retrieval"), stdout); > > - ctl.win = initscr(); > - get_terminal_dimension(&ctl.cols, &ctl.rows); > + ctl.win = initscr(); > + get_terminal_dimension(&ctl.cols, &ctl.rows); > #if HAVE_RESIZETERM > - resizeterm(ctl.rows, ctl.cols); > + resizeterm(ctl.rows, ctl.cols); > #endif > - curs_set(0); > + curs_set(0); > + } > > ctl.hostname = xgethostname(); > event_loop(&ctl, &out); > @@ -412,10 +440,13 @@ int main(int argc, char **argv) > free(ctl.hostname); > cpuset_free(ctl.cpuset); > > - if (is_tty) > - tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_tty); > - delwin(ctl.win); > - endwin(); > + if (ctl.batch == false) { > + if (is_tty) > + tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_tty); > + > + delwin(ctl.win); > + endwin(); > + } > > return EXIT_SUCCESS; > }