summaryrefslogtreecommitdiffstats
path: root/libblkid/pager.c
diff options
context:
space:
mode:
Diffstat (limited to 'libblkid/pager.c')
-rw-r--r--libblkid/pager.c220
1 files changed, 0 insertions, 220 deletions
diff --git a/libblkid/pager.c b/libblkid/pager.c
deleted file mode 100644
index 5cf8c03b5..000000000
--- a/libblkid/pager.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Based on linux-perf/git scm
- *
- * Some modifications and simplifications for util-linux
- * by Davidlohr Bueso <dave@xxxxxxx> - March 2012.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <err.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#include "c.h"
-#include "xalloc.h"
-#include "nls.h"
-
-#define NULL_DEVICE "/dev/null"
-
-void setup_pager(void);
-
-static const char *pager_argv[] = { "sh", "-c", NULL, NULL };
-
-struct child_process {
- const char **argv;
- pid_t pid;
- int in;
- int out;
- int err;
- unsigned no_stdin:1;
- void (*preexec_cb)(void);
-};
-static struct child_process pager_process;
-
-static inline void close_pair(int fd[2])
-{
- close(fd[0]);
- close(fd[1]);
-}
-
-static inline void dup_devnull(int to)
-{
- int fd = open(NULL_DEVICE, O_RDWR);
-
- if (fd < 0)
- err(EXIT_FAILURE, _("cannot open %s"), NULL_DEVICE);
- dup2(fd, to);
- close(fd);
-}
-
-static int start_command(struct child_process *cmd)
-{
- int need_in;
- int fdin[2];
-
- /*
- * In case of errors we must keep the promise to close FDs
- * that have been passed in via ->in and ->out.
- */
- need_in = !cmd->no_stdin && cmd->in < 0;
- if (need_in) {
- if (pipe(fdin) < 0) {
- if (cmd->out > 0)
- close(cmd->out);
- return -1;
- }
- cmd->in = fdin[1];
- }
-
- fflush(NULL);
- cmd->pid = fork();
- if (!cmd->pid) {
- if (need_in) {
- dup2(fdin[0], 0);
- close_pair(fdin);
- } else if (cmd->in > 0) {
- dup2(cmd->in, 0);
- close(cmd->in);
- }
-
- cmd->preexec_cb();
- execvp(cmd->argv[0], (char *const*) cmd->argv);
- exit(127); /* cmd not found */
- }
-
- if (cmd->pid < 0) {
- if (need_in)
- close_pair(fdin);
- else if (cmd->in)
- close(cmd->in);
- return -1;
- }
-
- if (need_in)
- close(fdin[0]);
- else if (cmd->in)
- close(cmd->in);
- return 0;
-}
-
-static int wait_or_whine(pid_t pid)
-{
- for (;;) {
- int status, code;
- pid_t waiting = waitpid(pid, &status, 0);
-
- if (waiting < 0) {
- if (errno == EINTR)
- continue;
- err(EXIT_FAILURE, _("waitpid failed (%s)"), strerror(errno));
- }
- if (waiting != pid)
- return -1;
- if (WIFSIGNALED(status))
- return -1;
-
- if (!WIFEXITED(status))
- return -1;
- code = WEXITSTATUS(status);
- switch (code) {
- case 127:
- return -1;
- case 0:
- return 0;
- default:
- return -1;
- }
- }
-}
-
-static int finish_command(struct child_process *cmd)
-{
- return wait_or_whine(cmd->pid);
-}
-
-static void pager_preexec(void)
-{
- /*
- * Work around bug in "less" by not starting it until we
- * have real input
- */
- fd_set in;
-
- FD_ZERO(&in);
- FD_SET(0, &in);
- select(1, &in, NULL, &in, NULL);
-
- setenv("LESS", "FRSX", 0);
-}
-
-static void wait_for_pager(void)
-{
- fflush(stdout);
- fflush(stderr);
- /* signal EOF to pager */
- close(1);
- close(2);
- finish_command(&pager_process);
-}
-
-static void wait_for_pager_signal(int signo)
-{
- wait_for_pager();
- raise(signo);
-}
-
-void setup_pager(void)
-{
- const char *pager = getenv("PAGER");
-
- if (!isatty(1))
- return;
-
- if (!pager)
- pager = "less";
- else if (!*pager || !strcmp(pager, "cat"))
- return;
-
- /* spawn the pager */
- pager_argv[2] = pager;
- pager_process.argv = pager_argv;
- pager_process.in = -1;
- pager_process.preexec_cb = pager_preexec;
-
- if (start_command(&pager_process))
- return;
-
- /* original process continues, but writes to the pipe */
- dup2(pager_process.in, 1);
- if (isatty(2))
- dup2(pager_process.in, 2);
- close(pager_process.in);
-
- /* this makes sure that the parent terminates after the pager */
- signal(SIGINT, wait_for_pager_signal);
- signal(SIGHUP, wait_for_pager_signal);
- signal(SIGTERM, wait_for_pager_signal);
- signal(SIGQUIT, wait_for_pager_signal);
- signal(SIGPIPE, wait_for_pager_signal);
-
- atexit(wait_for_pager);
-}
-
-#ifdef TEST_PROGRAM
-
-#define MAX 255
-
-int main(int argc __attribute__ ((__unused__)),
- char *argv[] __attribute__ ((__unused__)))
-{
- int i;
-
- setup_pager();
- for (i = 0; i < MAX; i++)
- printf("%d\n", i);
- return EXIT_SUCCESS;
-}
-#endif /* TEST_PROGRAM */