From e61a2da6f7509d0ce2766bf46095279036646329 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Mon, 2 May 2022 22:31:01 -0700 Subject: Relax restrictions on stdout; improve error reporting. --- pw.1 | 10 ++++------ pw.c | 46 +++++++++++++++++++++++----------------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/pw.1 b/pw.1 index 00e106b..4da72ad 100644 --- a/pw.1 +++ b/pw.1 @@ -596,14 +596,12 @@ environment variable, requiring an ANSI terminal. requires the following conditions to hold in regard to its execution environment, otherwise it terminates with an error diagnostic: .IP 1. -Standard output must be a TTY device. -.IP 2. -Standard input is either not a TTY device, or else not the same TTY device -as standard output. -.IP 3. It must be possible to open the .B /dev/tty -device, which is the same TTY as standard output. +device, +.IP 2. +Standard input is either not a TTY device, or else not the same TTY device as +.BR /dev/tty . .PP .SH TERMINATION STATUS diff --git a/pw.c b/pw.c index b8f3fa3..a288d9f 100644 --- a/pw.c +++ b/pw.c @@ -93,6 +93,7 @@ typedef struct dstr { #define dstr_of(str) ((dstr *) ((str) - sizeof (dstr))) +static char *pw_name; static int poll_interval = 1000; static int long_interval = 10000; static int regex_flags = 0; @@ -117,6 +118,7 @@ static void panic(const char *fmt, ...) { va_list vl; va_start (vl, fmt); + fprintf(stderr, "%s: ", pw_name); vfprintf(stderr, fmt, vl); abort(); } @@ -126,8 +128,8 @@ static void error(const char *fmt, ...) { va_list vl; va_start (vl, fmt); + fprintf(stderr, "%s: ", pw_name); vfprintf(stderr, fmt, vl); - exit(EXIT_FAILURE); } static char *dsref(char *str) @@ -233,16 +235,22 @@ static char *addchesc(char *line, int ch) return line; } -static void usage(const char *name) +static void usage(void) { fprintf(stderr, - "\nUsage: %s [options]\n\n" + "\nUsage: | %s [options]\n\n" "-i realnum poll interval (s)\n" "-l realnum long update interval (s)\n" "-n integer display size (# of lines)\n" - "-d do not quit on end-of-input\n\n" + "-d do not quit on end-of-input\n" + "-E treat regular expressions as extended\n" + "-B treat regular expressions as basic (default)\n\n" + " represents an arbitrary command that generates the\n" + "output to be monitored by %s.\n\n" + "Standard input must be redirected; it cannot be the same device\n" + "as the controlling tty (/dev/tty) of the terminal session.\n\n" "For a full description, see the manual page.\n\n", - name); + pw_name, pw_name); exit(EXIT_FAILURE); } @@ -683,7 +691,6 @@ int main(int argc, char **argv) int maxlines = 15, nlines = 0, maxed = 0; int opt; int ifd = fileno(stdin); - int ofd = fileno(stdout); int ttyfd = tty ? fileno(tty) : -1; char **circbuf; struct termios tty_saved, tty_new; @@ -700,31 +707,22 @@ int main(int argc, char **argv) static struct sigaction sa; #endif - if (ifd < 0) - panic("unable to obtain input file descriptor\n"); + pw_name = argv[0] ? argv[0] : "pw"; - if (ofd < 0) + if (ifd < 0) panic("unable to obtain input file descriptor\n"); - if (!isatty(ofd)) - error("standard output must be a TTY\n"); - if (ttyfd < 0) panic("unable to open /dev/tty\n"); { - pid_t ogrp = tcgetpgrp(ofd); pid_t igrp = tcgetpgrp(ifd); pid_t tgrp = tcgetpgrp(ttyfd); - if (ogrp < 0) - error("standard output isn't a job control TTY\n"); - - if (ogrp != tgrp) - error("/dev/tty isn't the same as the standard output TTY\n"); - - if (igrp == ogrp) - error("standard input and standard output are the same TTY\n"); + if (igrp == tgrp) { + error("standard input cannot be the TTY used for display\n"); + usage(); + } } while ((opt = getopt(argc, argv, "n:i:l:dEB")) != -1) { @@ -764,12 +762,14 @@ int main(int argc, char **argv) regex_flags = 0; break; default: - usage(argv[0]); + usage(); } } - if (maxlines <= 0 || maxlines > 1000) + if (maxlines <= 0 || maxlines > 1000) { error("%d is an unreasonable number of lines to display\n", maxlines); + return EXIT_FAILURE; + } if ((circbuf = calloc(sizeof *circbuf, maxlines)) == 0) panic("out of memory"); -- cgit v1.2.3