=================================================================== RCS file: /cvs/mandoc/main.c,v retrieving revision 1.332 retrieving revision 1.333 diff -u -p -r1.332 -r1.333 --- mandoc/main.c 2019/07/19 20:27:25 1.332 +++ mandoc/main.c 2019/07/26 18:01:43 1.333 @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.332 2019/07/19 20:27:25 schwarze Exp $ */ +/* $Id: main.c,v 1.333 2019/07/26 18:01:43 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2012, 2014-2019 Ingo Schwarze @@ -101,6 +101,7 @@ static int fs_search(const struct mansearch *, static void outdata_alloc(struct curparse *); static void parse(struct curparse *, int, const char *); static void passthrough(int, int); +static void run_pager(struct tag_files *); static pid_t spawn_pager(struct tag_files *); static void usage(enum argmode) __attribute__((__noreturn__)); static int woptions(struct curparse *, char *); @@ -130,9 +131,7 @@ main(int argc, char *argv[]) int show_usage; int options; int use_pager; - int status, signum; int c; - pid_t pager_pid, tc_pgid, man_pgid, pid; #if HAVE_PROGNAME progname = getprogname(); @@ -669,63 +668,12 @@ out: manconf_free(&conf); mansearch_free(res, sz); } - free(curp.os_s); - /* - * When using a pager, finish writing both temporary files, - * fork it, wait for the user to close it, and clean up. - */ - if (tag_files != NULL) { fclose(stdout); tag_write(); - man_pgid = getpgid(0); - tag_files->tcpgid = man_pgid == getpid() ? - getpgid(getppid()) : man_pgid; - pager_pid = 0; - signum = SIGSTOP; - for (;;) { - - /* Stop here until moved to the foreground. */ - - tc_pgid = tcgetpgrp(tag_files->ofd); - if (tc_pgid != man_pgid) { - if (tc_pgid == pager_pid) { - (void)tcsetpgrp(tag_files->ofd, - man_pgid); - if (signum == SIGTTIN) - continue; - } else - tag_files->tcpgid = tc_pgid; - kill(0, signum); - continue; - } - - /* Once in the foreground, activate the pager. */ - - if (pager_pid) { - (void)tcsetpgrp(tag_files->ofd, pager_pid); - kill(pager_pid, SIGCONT); - } else - pager_pid = spawn_pager(tag_files); - - /* Wait for the pager to stop or exit. */ - - while ((pid = waitpid(pager_pid, &status, - WUNTRACED)) == -1 && errno == EINTR) - continue; - - if (pid == -1) { - mandoc_msg(MANDOCERR_WAIT, 0, 0, - "%s", strerror(errno)); - break; - } - if (!WIFSTOPPED(status)) - break; - - signum = WSTOPSIG(status); - } + run_pager(tag_files); tag_unlink(); } else if (curp.outtype != OUTT_LINT && (search.argmode == ARG_FILE || sz > 0)) @@ -1149,6 +1097,64 @@ woptions(struct curparse *curp, char *arg) } } return 0; +} + +/* + * Wait until moved to the foreground, + * then fork the pager and wait for the user to close it. + */ +static void +run_pager(struct tag_files *tag_files) +{ + int signum, status; + pid_t man_pgid, tc_pgid; + pid_t pager_pid, wait_pid; + + man_pgid = getpgid(0); + tag_files->tcpgid = man_pgid == getpid() ? getpgid(getppid()) : + man_pgid; + pager_pid = 0; + signum = SIGSTOP; + + for (;;) { + /* Stop here until moved to the foreground. */ + + tc_pgid = tcgetpgrp(tag_files->ofd); + if (tc_pgid != man_pgid) { + if (tc_pgid == pager_pid) { + (void)tcsetpgrp(tag_files->ofd, man_pgid); + if (signum == SIGTTIN) + continue; + } else + tag_files->tcpgid = tc_pgid; + kill(0, signum); + continue; + } + + /* Once in the foreground, activate the pager. */ + + if (pager_pid) { + (void)tcsetpgrp(tag_files->ofd, pager_pid); + kill(pager_pid, SIGCONT); + } else + pager_pid = spawn_pager(tag_files); + + /* Wait for the pager to stop or exit. */ + + while ((wait_pid = waitpid(pager_pid, &status, + WUNTRACED)) == -1 && errno == EINTR) + continue; + + if (wait_pid == -1) { + mandoc_msg(MANDOCERR_WAIT, 0, 0, + "%s", strerror(errno)); + break; + } + if (!WIFSTOPPED(status)) + break; + + signum = WSTOPSIG(status); + } } static pid_t