summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c58
1 files changed, 37 insertions, 21 deletions
diff --git a/main.c b/main.c
index 236c3c88d16aa..f0cd8ca0ccc60 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.222 2015/02/27 16:02:10 schwarze Exp $ */
+/* $Id: main.c,v 1.225 2015/03/10 13:50:03 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -20,6 +20,7 @@
#include <sys/types.h>
#include <sys/param.h> /* MACHINE */
+#include <sys/wait.h>
#include <assert.h>
#include <ctype.h>
@@ -101,7 +102,7 @@ static void mmsg(enum mandocerr, enum mandoclevel,
static void parse(struct curparse *, int,
const char *, enum mandoclevel *);
static enum mandoclevel passthrough(const char *, int, int);
-static void spawn_pager(void);
+static pid_t spawn_pager(void);
static int toptions(struct curparse *, char *);
static void usage(enum argmode) __attribute__((noreturn));
static int woptions(struct curparse *, char *);
@@ -130,9 +131,9 @@ main(int argc, char *argv[])
enum outmode outmode;
int fd;
int show_usage;
- int use_pager;
int options;
int c;
+ pid_t pager_pid; /* 0: don't use; 1: not yet spawned. */
if (argc < 1)
progname = "mandoc";
@@ -174,7 +175,7 @@ main(int argc, char *argv[])
options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1;
defos = NULL;
- use_pager = 1;
+ pager_pid = 1;
show_usage = 0;
synopsis_only = 0;
outmode = OUTMODE_DEF;
@@ -189,7 +190,7 @@ main(int argc, char *argv[])
conf_file = optarg;
break;
case 'c':
- use_pager = 0;
+ pager_pid = 0;
break;
case 'f':
search.argmode = ARG_WORD;
@@ -197,7 +198,7 @@ main(int argc, char *argv[])
case 'h':
(void)strlcat(curp.outopts, "synopsis,", BUFSIZ);
synopsis_only = 1;
- use_pager = 0;
+ pager_pid = 0;
outmode = OUTMODE_ALL;
break;
case 'I':
@@ -272,7 +273,7 @@ main(int argc, char *argv[])
switch (search.argmode) {
case ARG_FILE:
outmode = OUTMODE_ALL;
- use_pager = 0;
+ pager_pid = 0;
break;
case ARG_NAME:
outmode = OUTMODE_ONE;
@@ -303,18 +304,20 @@ main(int argc, char *argv[])
argc = 1;
}
} else if (argc > 1 &&
- ((uc = argv[0]) != NULL) &&
+ ((uc = (unsigned char *)argv[0]) != NULL) &&
((isdigit(uc[0]) && (uc[1] == '\0' ||
(isalpha(uc[1]) && uc[2] == '\0'))) ||
(uc[0] == 'n' && uc[1] == '\0'))) {
- search.sec = uc;
+ search.sec = (char *)uc;
argv++;
argc--;
}
if (search.arch == NULL)
search.arch = getenv("MACHINE");
+#ifdef MACHINE
if (search.arch == NULL)
search.arch = MACHINE;
+#endif
}
rc = MANDOCLEVEL_OK;
@@ -415,8 +418,8 @@ main(int argc, char *argv[])
mparse_keep(curp.mp);
if (argc < 1) {
- if (use_pager && isatty(STDOUT_FILENO))
- spawn_pager();
+ if (pager_pid == 1 && isatty(STDOUT_FILENO))
+ pager_pid = spawn_pager();
parse(&curp, STDIN_FILENO, "<stdin>", &rc);
}
@@ -427,9 +430,8 @@ main(int argc, char *argv[])
rc = rctmp;
if (fd != -1) {
- if (use_pager && isatty(STDOUT_FILENO))
- spawn_pager();
- use_pager = 0;
+ if (pager_pid == 1 && isatty(STDOUT_FILENO))
+ pager_pid = spawn_pager();
if (resp == NULL)
parse(&curp, fd, *argv, &rc);
@@ -479,6 +481,17 @@ out:
free(defos);
+ /*
+ * If a pager is attached, flush the pipe leading to it
+ * and signal end of file such that the user can browse
+ * to the end. Then wait for the user to close the pager.
+ */
+
+ if (pager_pid != 0 && pager_pid != 1) {
+ fclose(stdout);
+ waitpid(pager_pid, NULL, 0);
+ }
+
return((int)rc);
}
@@ -927,7 +940,7 @@ mmsg(enum mandocerr t, enum mandoclevel lvl,
fputc('\n', stderr);
}
-static void
+static pid_t
spawn_pager(void)
{
#define MAX_PAGER_ARGS 16
@@ -936,31 +949,33 @@ spawn_pager(void)
char *cp;
int fildes[2];
int argc;
+ pid_t pager_pid;
if (pipe(fildes) == -1) {
fprintf(stderr, "%s: pipe: %s\n",
progname, strerror(errno));
- return;
+ return(0);
}
- switch (fork()) {
+ switch (pager_pid = fork()) {
case -1:
fprintf(stderr, "%s: fork: %s\n",
progname, strerror(errno));
exit((int)MANDOCLEVEL_SYSERR);
case 0:
+ break;
+ default:
close(fildes[0]);
if (dup2(fildes[1], STDOUT_FILENO) == -1) {
fprintf(stderr, "%s: dup output: %s\n",
progname, strerror(errno));
exit((int)MANDOCLEVEL_SYSERR);
}
- return;
- default:
- break;
+ close(fildes[1]);
+ return(pager_pid);
}
- /* The original process becomes the pager. */
+ /* The child process becomes the pager. */
close(fildes[1]);
if (dup2(fildes[0], STDIN_FILENO) == -1) {
@@ -968,6 +983,7 @@ spawn_pager(void)
progname, strerror(errno));
exit((int)MANDOCLEVEL_SYSERR);
}
+ close(fildes[0]);
pager = getenv("MANPAGER");
if (pager == NULL || *pager == '\0')