aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-05-02 22:31:01 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-05-02 22:31:01 -0700
commite61a2da6f7509d0ce2766bf46095279036646329 (patch)
tree89cea209b00a558049e29a20336be18815cd442b
parentb06d9454f395f007a7ef6081fb43c4298b66b09b (diff)
downloadpw-e61a2da6f7509d0ce2766bf46095279036646329.tar.gz
pw-e61a2da6f7509d0ce2766bf46095279036646329.tar.bz2
pw-e61a2da6f7509d0ce2766bf46095279036646329.zip
Relax restrictions on stdout; improve error reporting.
-rw-r--r--pw.110
-rw-r--r--pw.c46
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: <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");