From e215d467ca828498109d178eb0e7cbe4a835cd99 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 26 Aug 2016 12:07:25 +0200 Subject: lib/pager: cleanup and extend API * clean up function names * add functions to temporary redirect to the pager and then restore original terminal output Signed-off-by: Karel Zak --- lib/pager.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) (limited to 'lib/pager.c') diff --git a/lib/pager.c b/lib/pager.c index e8cf10913..fb2c2d9d8 100644 --- a/lib/pager.c +++ b/lib/pager.c @@ -17,11 +17,11 @@ #include "c.h" #include "xalloc.h" #include "nls.h" +#include "ttyutils.h" +#include "pager.h" #define NULL_DEVICE "/dev/null" -void setup_pager(void); - static const char *pager_argv[] = { "sh", "-c", NULL, NULL }; struct child_process { @@ -30,6 +30,10 @@ struct child_process { int in; int out; int err; + + int org_err; + int org_out; + unsigned no_stdin:1; void (*preexec_cb)(void); }; @@ -144,6 +148,9 @@ static void pager_preexec(void) static void wait_for_pager(void) { + if (pager_process.pid == 0) + return; + fflush(stdout); fflush(stderr); /* signal EOF to pager */ @@ -158,7 +165,7 @@ static void wait_for_pager_signal(int signo) raise(signo); } -void setup_pager(void) +static void __setup_pager(void) { const char *pager = getenv("PAGER"); @@ -191,10 +198,50 @@ void setup_pager(void) signal(SIGTERM, wait_for_pager_signal); signal(SIGQUIT, wait_for_pager_signal); signal(SIGPIPE, wait_for_pager_signal); +} + +/* Setup pager and redirects output to the $PAGER. The pager is closed at exit. + */ +void pager_redirect(void) +{ + if (pager_process.pid) + return; /* already running */ + + __setup_pager(); atexit(wait_for_pager); } +/* Setup pager and redirect output, the pager may be closed by pager_close(). + */ +void pager_open(void) +{ + if (pager_process.pid) + return; /* already running */ + + pager_process.org_out = dup(STDOUT_FILENO); + pager_process.org_err = dup(STDERR_FILENO); + + __setup_pager(); +} + +/* Close pager and restore original std{out,err}. + */ +void pager_close(void) +{ + if (pager_process.pid == 0) + return; + + wait_for_pager(); + dup2(pager_process.org_out, STDOUT_FILENO); + dup2(pager_process.org_err, STDERR_FILENO); + + close(pager_process.org_out); + close(pager_process.org_err); + + memset(&pager_process, 0, sizeof(pager_process)); +} + #ifdef TEST_PROGRAM #define MAX 255 @@ -204,7 +251,7 @@ int main(int argc __attribute__ ((__unused__)), { int i; - setup_pager(); + pager_setup(); for (i = 0; i < MAX; i++) printf("%d\n", i); return EXIT_SUCCESS; -- cgit v1.2.3-55-g7522