From ede4a5f9b050e797582dfbde748a5cc3b4d072fb Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Wed, 25 Jul 2018 00:00:00 -0500 Subject: [PATCH] top: existing 'Inspect' pipe feature now more flexible Currently, it isn't possible to establish an 'Inspect' pipe that relies on SIGINT to end. That's because this signal will also end the parent process (top) as well. So this patch will temporarily ignore that signal when processing any 'Inspect' pipe, allowing one like this: . pipe ^I Trace Calls ^I /usr/bin/strace -r -p %d 2>&1 Signed-off-by: Jim Warner --- top/top.1 | 20 +++++++++++++------- top/top.c | 24 ++++++++++++++++++++---- top/top_nls.c | 3 ++- top/top_nls.h | 2 +- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/top/top.1 b/top/top.1 index b7d44cf0..ba52f472 100644 --- a/top/top.1 +++ b/top/top.1 @@ -62,7 +62,7 @@ . .\" Document ///////////////////////////////////////////////////////////// .\" ---------------------------------------------------------------------- -.TH TOP 1 "June 2018" "procps-ng" "User Commands" +.TH TOP 1 "July 2018" "procps-ng" "User Commands" .\" ---------------------------------------------------------------------- .\" ---------------------------------------------------------------------- @@ -2274,12 +2274,13 @@ enable backslash interpretation regardless of which shell you use. "pipe\\tLog\\ttail -n200 /var/log/syslog | sort -Mr" >> ~/.toprc .fi -\fBCaution\fR: If any inspect entry you create produces output with unprintable characters they will be displayed in either the ^C notation or hexadecimal form, depending on their value. This applies to tab characters as well, which will show as `^I'. If you want a truer representation, any embedded tabs should be expanded. +The following example takes what could have been a `file' entry but employs +a `pipe' instead so as to expand the embedded tabs. .nf # next would have contained `\\t' ... @@ -2288,18 +2289,23 @@ If you want a truer representation, any embedded tabs should be expanded. pipe ^I ^I cat /proc/%d/status | expand \- .fi -The above example takes what could have been a `file' entry but employs -a `pipe' instead so as to expand the embedded tabs. +\*(NT Some programs might rely on \fISIGINT\fR to end. +Therefore, if a `\fBpipe\fR' such as the following is established, one must +use Ctrl-C to terminate it in order to review the results. +This is the single occasion where a `^C' will not also terminate \*(We. -\*(NT While `\fBpipe\fR' type entries have been discussed in terms of pipelines +.nf + pipe ^I Trace ^I /usr/bin/strace -p %d 2>&1 +.fi + +Lastly, while `\fBpipe\fR' type entries have been discussed in terms of pipelines and commands, there is nothing to prevent you from including \fI shell scripts\fR as well. Perhaps even newly created scripts designed specifically for the `Y' \*(CI. -Lastly, as the number of your Inspect entries grows over time, the `Options:' +For example, as the number of your Inspect entries grows over time, the `Options:' row will be truncated when screen width is exceeded. That does not affect operation other than to make some selections invisible. - However, if some choices are lost to truncation but you want to see more options, there is an easy solution hinted at below. diff --git a/top/top.c b/top/top.c index 8a65918d..d538ddd2 100644 --- a/top/top.c +++ b/top/top.c @@ -2429,6 +2429,12 @@ static void sysinfo_refresh (int forced) { * # file ^I ^I /proc/%d/status * # but this will eliminate embedded '\t' ... * pipe ^I ^I cat /proc/%d/status | expand - + * + * Note: If a pipe such as the following was established, one must + * use Ctrl-C to terminate that pipe in order to review the results. + * This is the single occasion where a '^C' will not terminate top. + * + * pipe ^I Trace ^I /usr/bin/strace -p %d 2>&1 */ /* @@ -2472,8 +2478,8 @@ static struct I_ent *Insp_sel; // currently selected Inspect entry // Our 'row length' macro, equivalent to a strlen() call #define INSP_RLEN(idx) (int)(Insp_p[idx +1] - Insp_p[idx] -1) - // Our 'busy' (wait please) macro -#define INSP_BUSY { INSP_MKSL(0, N_txt(YINSP_workin_txt)); } + // Our 'busy/working' macro +#define INSP_BUSY(enu) { INSP_MKSL(0, N_txt(enu)) } /* @@ -2554,9 +2560,15 @@ static void insp_do_file (char *fmts, int pid) { * The generalized PIPE utility. */ static void insp_do_pipe (char *fmts, int pid) { char buf[LRGBUFSIZ]; + struct sigaction sa; FILE *fp; int rc; + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_IGN; + sigaction(SIGINT, &sa, NULL); + snprintf(buf, sizeof(buf), fmts, pid); fp = popen(buf, "r"); rc = readfile(fp, &Insp_buf, &Insp_bufsz, &Insp_bufrd); @@ -2564,6 +2576,9 @@ static void insp_do_pipe (char *fmts, int pid) { if (rc) Insp_bufrd = snprintf(Insp_buf, Insp_bufsz, "%s" , fmtmk(N_fmt(YINSP_failed_fmt), strerror(errno))); insp_cnt_nl(); + + sa.sa_handler = sig_endpgm; + sigaction(SIGINT, &sa, NULL); } // end: insp_do_pipe @@ -2621,7 +2636,7 @@ static void insp_find_str (int ch, int *col, int *row) { if (Insp_sel->fstr[0]) { int xx, yy; - INSP_BUSY; + INSP_BUSY(YINSP_waitin_txt); for (xx = *col, yy = *row; yy < Insp_nl; ) { xx = insp_find_ofs(xx, yy); if (xx < INSP_RLEN(yy)) { @@ -2988,7 +3003,8 @@ signify_that: key = INT_MAX; break; case kbd_ENTER: - INSP_BUSY; + INSP_BUSY(!strcmp("file", Inspect.tab[sel].type) + ? YINSP_waitin_txt : YINSP_workin_txt); Insp_sel = &Inspect.tab[sel]; Inspect.tab[sel].func(Inspect.tab[sel].fmts, pid); Insp_utf8 = utf8_delta(Insp_buf); diff --git a/top/top_nls.c b/top/top_nls.c index c52dbf79..493ae6a7 100644 --- a/top/top_nls.c +++ b/top/top_nls.c @@ -476,7 +476,8 @@ static void build_norm_nlstab (void) { Norm_nlstab[YINSP_pidbad_fmt] = _("unable to inspect, pid %d not found"); Norm_nlstab[YINSP_pidsee_fmt] = _("inspect at PID [default pid = %d]"); Norm_nlstab[YINSP_status_fmt] = _("%s: %*d-%-*d lines, %*d-%*d columns, %lu bytes read"); - Norm_nlstab[YINSP_workin_txt] = _("patience please, working..."); + Norm_nlstab[YINSP_waitin_txt] = _("patience please, working ..."); + Norm_nlstab[YINSP_workin_txt] = _("working, use Ctrl-C to end ..."); /* Translation Hint: Below are 2 abbreviations which can be as long as needed: . FLD = FIELD, VAL = VALUE */ Norm_nlstab[OSEL_prompts_fmt] = _("add filter #%d (%s) as: [!]FLD?VAL"); diff --git a/top/top_nls.h b/top/top_nls.h index d8bdf232..12ac7773 100644 --- a/top/top_nls.h +++ b/top/top_nls.h @@ -89,7 +89,7 @@ enum norm_nls { YINSP_deqtyp_txt, YINSP_dstory_txt, #endif YINSP_failed_fmt, YINSP_noents_txt, YINSP_pidbad_fmt, YINSP_pidsee_fmt, - YINSP_status_fmt, YINSP_workin_txt, + YINSP_status_fmt, YINSP_waitin_txt, YINSP_workin_txt, norm_MAX };