From 3b8cd0ea54e2027fd7c972e3edcbbc8bb43afa52 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 15 Aug 2018 05:10:12 +0200 Subject: 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. --- lib/dpkg/libdpkg.map | 2 ++ lib/dpkg/pager.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/dpkg/pager.h | 6 +++++ 3 files changed, 72 insertions(+) (limited to 'lib') 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 #include +#include + +#include #include #include #include #include #include +#include +#include #include /** @@ -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 -- cgit v1.2.3