From c9da7277be6433d888dc42e3e44c10f4546433e8 Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Tue, 10 Mar 2015 03:02:28 +0000 Subject: Fix a regression caused in rev. 1.212, reported by kristaps@: When using a pager and the first manual shown is gzip'ed, the gunzip(1) process ended up as a child of the pager process such that the man(1) process couldn't wait for it, preventing proper display of the manual. Solve this by making the pager a child of the man(1) process (instead of the other way round), which requires being a bit more careful about properly closing file descriptors after use and waiting for the pager before exiting man(1). --- main.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index c5569f61..80be725e 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.223 2015/03/06 09:24:59 kristaps Exp $ */ +/* $Id: main.c,v 1.224 2015/03/10 03:02:28 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2012, 2014, 2015 Ingo Schwarze @@ -20,6 +20,7 @@ #include #include /* MACHINE */ +#include #include #include @@ -481,6 +482,21 @@ out: free(defos); + /* + * Flush the output and signal end of file. + * If a pager is attached, it allows browsing to the end. + * Otherwise, it does no harm, we are about to exit anyway. + */ + + fclose(stdout); + + /* + * If we spawned a pager, wait for the user to close it. + * Otherwise, this call fails with no adverse effect. + */ + + wait(NULL); + return((int)rc); } @@ -951,18 +967,19 @@ spawn_pager(void) 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); } + close(fildes[1]); return; - default: - break; } - /* The original process becomes the pager. */ + /* The child process becomes the pager. */ close(fildes[1]); if (dup2(fildes[0], STDIN_FILENO) == -1) { @@ -970,6 +987,7 @@ spawn_pager(void) progname, strerror(errno)); exit((int)MANDOCLEVEL_SYSERR); } + close(fildes[0]); pager = getenv("MANPAGER"); if (pager == NULL || *pager == '\0') -- cgit v1.2.3-56-ge451