]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/pager: cleanup and extend API
authorKarel Zak <kzak@redhat.com>
Fri, 26 Aug 2016 10:07:25 +0000 (12:07 +0200)
committerKarel Zak <kzak@redhat.com>
Fri, 26 Aug 2016 10:07:25 +0000 (12:07 +0200)
* 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>
include/pager.h
lib/pager.c
sys-utils/dmesg.c

index 9ca42eb35f582cbb2353911d900760099d6eaf12..0a7140d70e9288c7747d4fe90e693fe72e41c8c3 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef UTIL_LINUX_PAGER
 #define UTIL_LINUX_PAGER
 
-void setup_pager(void);
+void pager_redirect(void);
+
+void pager_open(void);
+void pager_close(void);
 
 #endif
index e8cf10913fc96e599507e6aa68b36da2020e4b51..fb2c2d9d84b7f165c8bfd3aae244a100d815380b 100644 (file)
 #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;
index a2ab3a2e3220b73c5799cc7c828768ac86cfc92a..0056b2520a8d30c4fc5d6fe0d34e9c06386daa2c 100644 (file)
@@ -1418,7 +1418,7 @@ int main(int argc, char *argv[])
                nopager = 1;
        ctl.pager = nopager ? 0 : ctl.pager;
        if (ctl.pager)
-               setup_pager();
+               pager_redirect();
 
        switch (ctl.action) {
        case SYSLOG_ACTION_READ_ALL:
@@ -1432,7 +1432,7 @@ int main(int argc, char *argv[])
                            errx(EXIT_FAILURE, _("--raw can be used together with --level or "
                                 "--facility only when reading messages from /dev/kmsg"));
                if (ctl.pager)
-                       setup_pager();
+                       pager_redirect();
                n = read_buffer(&ctl, &buf);
                if (n > 0)
                        print_buffer(&ctl, buf, n);