diff options
author | Guillem Jover <guillem@debian.org> | 2018-08-15 05:10:12 +0200 |
---|---|---|
committer | Guillem Jover <guillem@debian.org> | 2018-08-30 03:14:08 +0200 |
commit | 3b8cd0ea54e2027fd7c972e3edcbbc8bb43afa52 (patch) | |
tree | a30930573825bae899d046e3ddbe6c2e37de7b1f /lib | |
parent | 7a6cdb430bd85bd38601730fef816e7c89e5e1b8 (diff) | |
download | dpkg-3b8cd0ea54e2027fd7c972e3edcbbc8bb43afa52.tar.gz |
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.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/dpkg/libdpkg.map | 2 | ||||
-rw-r--r-- | lib/dpkg/pager.c | 64 | ||||
-rw-r--r-- | lib/dpkg/pager.h | 6 |
3 files changed, 72 insertions, 0 deletions
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 |