diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-05-02 22:31:01 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-05-02 22:31:01 -0700 |
commit | e61a2da6f7509d0ce2766bf46095279036646329 (patch) | |
tree | 89cea209b00a558049e29a20336be18815cd442b | |
parent | b06d9454f395f007a7ef6081fb43c4298b66b09b (diff) | |
download | pw-e61a2da6f7509d0ce2766bf46095279036646329.tar.gz pw-e61a2da6f7509d0ce2766bf46095279036646329.tar.bz2 pw-e61a2da6f7509d0ce2766bf46095279036646329.zip |
Relax restrictions on stdout; improve error reporting.
-rw-r--r-- | pw.1 | 10 | ||||
-rw-r--r-- | pw.c | 46 |
2 files changed, 27 insertions, 29 deletions
@@ -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 @@ -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: <command> | %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" + "<command> 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"); |