watch: Add no linewrap option

For long lines from a process, watch would wrap them around to the
next. While this default option has it uses, sometimes you want to
just cut those long lines down.

watch has a -w flag which will truncate the lines to the number
of columns. A few simple lines to do this new trick.

I think I caught all the ANSI state correctly but there might be
a chance it bleeds to the next row.

References:
 procps-ng/procps#182
This commit is contained in:
Craig Small 2020-10-19 22:03:44 +11:00
parent 6a2cc67bb6
commit e36fe38835
3 changed files with 34 additions and 2 deletions

1
NEWS
View File

@ -17,6 +17,7 @@ procps-ng NEXT
* top: fix potential SEGV involving -p switch merge #114 * top: fix potential SEGV involving -p switch merge #114
* vmstat: Wide mode gives wider proc columns merge #48 * vmstat: Wide mode gives wider proc columns merge #48
* watch: Add environment variable for interval merge #62 * watch: Add environment variable for interval merge #62
* watch: Add no linewrap option issue #182
procps-ng-3.3.16 procps-ng-3.3.16
---------------- ----------------

View File

@ -1,4 +1,4 @@
.TH WATCH 1 "2020-06-04" "procps-ng" "User Commands" .TH WATCH 1 "2020-10-19" "procps-ng" "User Commands"
.SH NAME .SH NAME
watch \- execute a program periodically, showing output fullscreen watch \- execute a program periodically, showing output fullscreen
.SH SYNOPSIS .SH SYNOPSIS
@ -64,6 +64,9 @@ instead of
.B sh \-c .B sh \-c
which reduces the need to use extra quoting to get the desired effect. which reduces the need to use extra quoting to get the desired effect.
.TP .TP
\fB\-w\fR, \fB\-\-no\-linewrap\fR
Turn off line wrapping. Long lines will be truncated instead of wrapped to the next line.
.TP
\fB\-h\fR, \fB\-\-help\fR \fB\-h\fR, \fB\-\-help\fR
Display help text and exit. Display help text and exit.
.TP .TP

30
watch.c
View File

@ -78,6 +78,7 @@ static int screen_size_changed = 0;
static int first_screen = 1; static int first_screen = 1;
static int show_title = 2; /* number of lines used, 2 or 0 */ static int show_title = 2; /* number of lines used, 2 or 0 */
static int precise_timekeeping = 0; static int precise_timekeeping = 0;
static int line_wrap = 1;
#define min(x,y) ((x) > (y) ? (y) : (x)) #define min(x,y) ((x) > (y) ? (y) : (x))
#define MAX_ANSIBUF 100 #define MAX_ANSIBUF 100
@ -98,6 +99,7 @@ static void __attribute__ ((__noreturn__))
fputs(_(" -n, --interval <secs> seconds to wait between updates\n"), out); fputs(_(" -n, --interval <secs> seconds to wait between updates\n"), out);
fputs(_(" -p, --precise attempt run command in precise intervals\n"), out); fputs(_(" -p, --precise attempt run command in precise intervals\n"), out);
fputs(_(" -t, --no-title turn off header\n"), out); fputs(_(" -t, --no-title turn off header\n"), out);
fputs(_(" -w, --no-wrap turn off line wrapping\n"), out);
fputs(_(" -x, --exec pass command to exec instead of \"sh -c\"\n"), out); fputs(_(" -x, --exec pass command to exec instead of \"sh -c\"\n"), out);
fputs(USAGE_SEPARATOR, out); fputs(USAGE_SEPARATOR, out);
fputs(USAGE_HELP, out); fputs(USAGE_HELP, out);
@ -450,6 +452,22 @@ static void output_header(char *restrict command, double interval)
return; return;
} }
static void find_eol(FILE *p)
{
int c;
#ifdef WITH_WATCH8BIT
do {
c = my_getwc(p);
} while (c != WEOF
&& c!= L'\n');
#else
do {
c = getc(p);
} while (c != EOF
&& c != '\n');
#endif /* WITH_WATCH8BIT */
}
static int run_command(char *restrict command, char **restrict command_argv) static int run_command(char *restrict command, char **restrict command_argv)
{ {
FILE *p; FILE *p;
@ -640,6 +658,12 @@ static int run_command(char *restrict command, char **restrict command_argv)
#endif #endif
} }
oldeolseen = eolseen; oldeolseen = eolseen;
if (!line_wrap) {
reset_ansi();
if (flags & WATCH_COLOR)
attrset(A_NORMAL);
find_eol(p);
}
} }
fclose(p); fclose(p);
@ -693,6 +717,7 @@ int main(int argc, char *argv[])
{"exec", no_argument, 0, 'x'}, {"exec", no_argument, 0, 'x'},
{"precise", no_argument, 0, 'p'}, {"precise", no_argument, 0, 'p'},
{"no-title", no_argument, 0, 't'}, {"no-title", no_argument, 0, 't'},
{"no-wrap", no_argument, 0, 'w'},
{"version", no_argument, 0, 'v'}, {"version", no_argument, 0, 'v'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
@ -710,7 +735,7 @@ int main(int argc, char *argv[])
interval = strtod_nol_or_err(interval_string, _("Could not parse interval from WATCH_INTERVAL")); interval = strtod_nol_or_err(interval_string, _("Could not parse interval from WATCH_INTERVAL"));
while ((optc = while ((optc =
getopt_long(argc, argv, "+bced::ghn:pvtx", longopts, (int *)0)) getopt_long(argc, argv, "+bced::ghn:pvtwx", longopts, (int *)0))
!= EOF) { != EOF) {
switch (optc) { switch (optc) {
case 'b': case 'b':
@ -733,6 +758,9 @@ int main(int argc, char *argv[])
case 't': case 't':
show_title = 0; show_title = 0;
break; break;
case 'w':
line_wrap = 0;
break;
case 'x': case 'x':
flags |= WATCH_EXEC; flags |= WATCH_EXEC;
break; break;