diff options
author | Karel Zak | 2016-08-26 12:07:25 +0200 |
---|---|---|
committer | Karel Zak | 2016-08-26 12:07:25 +0200 |
commit | e215d467ca828498109d178eb0e7cbe4a835cd99 (patch) | |
tree | aed8bd796b076a8eace7af4170c326e00531f261 /lib/pager.c | |
parent | su, runuser, setpriv: create links between man pages (diff) | |
download | kernel-qcow2-util-linux-e215d467ca828498109d178eb0e7cbe4a835cd99.tar.gz kernel-qcow2-util-linux-e215d467ca828498109d178eb0e7cbe4a835cd99.tar.xz kernel-qcow2-util-linux-e215d467ca828498109d178eb0e7cbe4a835cd99.zip |
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 <kzak@redhat.com>
Diffstat (limited to 'lib/pager.c')
-rw-r--r-- | lib/pager.c | 55 |
1 files changed, 51 insertions, 4 deletions
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; |