summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2015-03-17 07:33:07 +0000
committerIngo Schwarze <schwarze@openbsd.org>2015-03-17 07:33:07 +0000
commit27bcceb5c71e31ddc4c21e26e2161fd0b339c3f4 (patch)
tree5e5b45b5163922afec79bccfcf849f966c7fe3cf
parent45532c8b0d0090977b1e7e839c2340e456a6a6ab (diff)
downloadmandoc-27bcceb5c71e31ddc4c21e26e2161fd0b339c3f4.tar.gz
When the user exits the pager before the pager has drained all input
from man(1), man(1) dies from SIGPIPE. Exiting man(1) is fine in this case, generating more output would be pointless, but without handling SIGPIPE, the exit code from man(1) was wrong and csh(1) printed an ugly message "Broken pipe". Fix this by handling SIGPIPE explicitly. Issue noticed by deraadt@.
-rw-r--r--main.c13
-rw-r--r--read.c2
2 files changed, 14 insertions, 1 deletions
diff --git a/main.c b/main.c
index a2e1ed25..8ef9f73a 100644
--- a/main.c
+++ b/main.c
@@ -27,6 +27,7 @@
#include <errno.h>
#include <fcntl.h>
#include <glob.h>
+#include <signal.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@@ -92,6 +93,7 @@ static int fs_lookup(const struct manpaths *,
static void fs_search(const struct mansearch *,
const struct manpaths *, int, char**,
struct manpage **, size_t *);
+static void handle_sigpipe(int);
static int koptions(int *, char *);
#if HAVE_SQLITE3
int mandocdb(int, char**);
@@ -111,6 +113,7 @@ static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9};
static char help_arg[] = "help";
static char *help_argv[] = {help_arg, NULL};
static const char *progname;
+static enum mandoclevel rc;
int
@@ -127,7 +130,7 @@ main(int argc, char *argv[])
size_t isec, i, sz;
int prio, best_prio, synopsis_only;
char sec;
- enum mandoclevel rc, rctmp;
+ enum mandoclevel rctmp;
enum outmode outmode;
int fd;
int show_usage;
@@ -940,6 +943,13 @@ mmsg(enum mandocerr t, enum mandoclevel lvl,
fputc('\n', stderr);
}
+static void
+handle_sigpipe(int signum)
+{
+
+ exit(rc);
+}
+
static pid_t
spawn_pager(void)
{
@@ -972,6 +982,7 @@ spawn_pager(void)
exit((int)MANDOCLEVEL_SYSERR);
}
close(fildes[1]);
+ signal(SIGPIPE, handle_sigpipe);
return(pager_pid);
}
diff --git a/read.c b/read.c
index abad8e0c..511ce45e 100644
--- a/read.c
+++ b/read.c
@@ -29,6 +29,7 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <signal.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -846,6 +847,7 @@ mparse_open(struct mparse *curp, int *fd, const char *file)
perror("dup");
exit((int)MANDOCLEVEL_SYSERR);
}
+ signal(SIGPIPE, SIG_DFL);
execlp("gunzip", "gunzip", "-c", file, NULL);
perror("exec");
exit((int)MANDOCLEVEL_SYSERR);