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 <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2018-07-25 00:00:00 -05:00 committed by Craig Small
parent 40dbd50056
commit ede4a5f9b0
4 changed files with 36 additions and 13 deletions

View File

@ -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 <FF> 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 <your_name> ^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.

View File

@ -2429,6 +2429,12 @@ static void sysinfo_refresh (int forced) {
* # file ^I <your_name> ^I /proc/%d/status
* # but this will eliminate embedded '\t' ...
* pipe ^I <your_name> ^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);

View File

@ -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");

View File

@ -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
};