summaryrefslogtreecommitdiffstats
path: root/lib/pager.c
diff options
context:
space:
mode:
authorKarel Zak2016-08-26 12:07:25 +0200
committerKarel Zak2016-08-26 12:07:25 +0200
commite215d467ca828498109d178eb0e7cbe4a835cd99 (patch)
treeaed8bd796b076a8eace7af4170c326e00531f261 /lib/pager.c
parentsu, runuser, setpriv: create links between man pages (diff)
downloadkernel-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.c55
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;