aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/main.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2019-07-26 18:01:43 +0000
committerIngo Schwarze <schwarze@openbsd.org>2019-07-26 18:01:43 +0000
commit9f22e06212d3b35e53f50fe1288a658829de721e (patch)
tree6b78807eb8978e3d43edd40b74b70818df2231b9 /main.c
parentf297e8ee9d6c64721ec4be733153ad885f3fe569 (diff)
downloadmandoc-9f22e06212d3b35e53f50fe1288a658829de721e.tar.gz
mandoc-9f22e06212d3b35e53f50fe1288a658829de721e.tar.zst
mandoc-9f22e06212d3b35e53f50fe1288a658829de721e.zip
Structural cleanup, no functional change:
Move process group management out of main() into its own function because it has its own, self-contained logic and its own local variables.
Diffstat (limited to 'main.c')
-rw-r--r--main.c116
1 files changed, 61 insertions, 55 deletions
diff --git a/main.c b/main.c
index b11f7b51..cf219176 100644
--- a/main.c
+++ b/main.c
@@ -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 <kristaps@bsd.lv>
* Copyright (c) 2010-2012, 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
@@ -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))
@@ -1151,6 +1099,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
spawn_pager(struct tag_files *tag_files)
{