This is an automated email from the git hooks/post-receive script.

guillem pushed a commit to branch master
in repository dpkg.

View the commit online:
https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=3b8cd0ea54e2027fd7c972e3edcbbc8bb43afa52

commit 3b8cd0ea54e2027fd7c972e3edcbbc8bb43afa52
Author: Guillem Jover <[email protected]>
AuthorDate: Wed Aug 15 05:10:12 2018 +0200

    libdpkg: Add pager spawning and reaping support
    
    This will make using a pager way easier, and make it possible to remove
    some redundant and unsafe system() usage.
---
 debian/changelog     |  1 +
 lib/dpkg/libdpkg.map |  2 ++
 lib/dpkg/pager.c     | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/dpkg/pager.h     |  6 +++++
 4 files changed, 73 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 7bcfc04ae..06462517a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -206,6 +206,7 @@ dpkg (1.19.1) UNRELEASED; urgency=medium
     - libdpkg: Add new m_dup() function.
     - libdpkg: Factor out package stanza printing into its own function.
     - libdpkg: Split pager specific code into its own module.
+    - libdpkg: Add pager spawning and reaping support.
   * Build system:
     - Set distribution tarball format to ustar, instead of default v7 format.
     - Mark PO4A and POD2MAN as precious variables.
diff --git a/lib/dpkg/libdpkg.map b/lib/dpkg/libdpkg.map
index b562d7aad..cb3062845 100644
--- a/lib/dpkg/libdpkg.map
+++ b/lib/dpkg/libdpkg.map
@@ -185,6 +185,8 @@ LIBDPKG_PRIVATE {
        command_destroy;
 
        pager_get_exec;
+       pager_spawn;
+       pager_reap;
 
        setcloexec;
 
diff --git a/lib/dpkg/pager.c b/lib/dpkg/pager.c
index 4922b537a..c9adf5bce 100644
--- a/lib/dpkg/pager.c
+++ b/lib/dpkg/pager.c
@@ -21,12 +21,17 @@
 #include <config.h>
 #include <compat.h>
 
+#include <sys/types.h>
+
+#include <stdbool.h>
 #include <stdlib.h>
 #include <unistd.h>
 
 #include <dpkg/dpkg.h>
 #include <dpkg/i18n.h>
 #include <dpkg/string.h>
+#include <dpkg/subproc.h>
+#include <dpkg/command.h>
 #include <dpkg/pager.h>
 
 /**
@@ -48,3 +53,62 @@ pager_get_exec(void)
 
        return pager;
 }
+
+struct pager {
+       bool used;
+       const char *desc;
+       pid_t pid;
+       int stdout_old;
+       int pipe[2];
+};
+
+struct pager *
+pager_spawn(const char *desc, const char *filename)
+{
+       struct pager *pager;
+
+       pager = m_calloc(1, sizeof(*pager));
+       pager->used = filename || (isatty(0) && isatty(1));
+       pager->desc = desc;
+
+       if (!pager->used)
+               return pager;
+
+       m_pipe(pager->pipe);
+
+       pager->pid = subproc_fork();
+       if (pager->pid == 0) {
+               struct command cmd;
+               const char *exec;
+
+               exec = pager_get_exec();
+
+               m_dup2(pager->pipe[0], 0);
+               close(pager->pipe[0]);
+               close(pager->pipe[1]);
+
+               command_init(&cmd, exec, desc);
+               command_add_arg(&cmd, exec);
+               command_add_arg(&cmd, filename);
+               command_exec(&cmd);
+       }
+
+       pager->stdout_old = m_dup(1);
+       m_dup2(pager->pipe[1], 1);
+       close(pager->pipe[0]);
+       close(pager->pipe[1]);
+
+       return pager;
+}
+
+void
+pager_reap(struct pager *pager)
+{
+       if (!pager->used)
+               return;
+
+       m_dup2(pager->stdout_old, 1);
+       subproc_reap(pager->pid, pager->desc, SUBPROC_NOPIPE);
+
+       free(pager);
+}
diff --git a/lib/dpkg/pager.h b/lib/dpkg/pager.h
index 8ecc93b97..7d7ea0dff 100644
--- a/lib/dpkg/pager.h
+++ b/lib/dpkg/pager.h
@@ -36,6 +36,12 @@ struct pager;
 const char *
 pager_get_exec(void);
 
+struct pager *
+pager_spawn(const char *desc, const char *filename);
+
+void
+pager_reap(struct pager *pager);
+
 /** @} */
 
 DPKG_END_DECLS

-- 
Dpkg.Org's dpkg

Reply via email to