diff options
author | Lennart Poettering <lennart@poettering.net> | 2011-01-04 00:47:40 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2011-01-04 00:47:40 +0100 |
commit | 611efaac7a76904ffc3d03592a8fe57da5f42c02 (patch) | |
tree | e18b09d2af0dffadabdf83bc76258b32a77a9363 | |
parent | 0736af98c6fae9c7d31e3dd17589421b7e883ef5 (diff) |
systemctl: try harder to find a suitable pager
-rw-r--r-- | src/systemctl.c | 99 |
1 files changed, 55 insertions, 44 deletions
diff --git a/src/systemctl.c b/src/systemctl.c index 585f1dc5fe..8a6277e75c 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -4251,7 +4251,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { ARG_SYSTEM, ARG_GLOBAL, ARG_NO_BLOCK, - ARG_NO_PAGER, + ARG_NO_PAGER, ARG_NO_WALL, ARG_ORDER, ARG_REQUIRE, @@ -4352,9 +4352,9 @@ static int systemctl_parse_argv(int argc, char *argv[]) { arg_no_block = true; break; - case ARG_NO_PAGER: - arg_no_pager = true; - break; + case ARG_NO_PAGER: + arg_no_pager = true; + break; case ARG_NO_WALL: arg_no_wall = true; @@ -5283,45 +5283,56 @@ static int runlevel_main(void) { } static void pager_open(void) { - pid_t pid; - int fd[2]; - const char *pager = getenv("PAGER"); - - if (!on_tty() || arg_no_pager) - return; - if (!pager) - pager = "less"; - else if (!*pager || !strcmp(pager, "cat")) - return; - - if (pipe(fd) < 0) - return; - pid = fork(); - if (pid < 0) { - close(fd[0]); - close(fd[1]); - return; - } - - /* Return in the child */ - if (!pid) { - dup2(fd[1], 1); - close(fd[0]); - close(fd[1]); - return; - } - - /* The original process turns into the PAGER */ - dup2(fd[0], 0); - close(fd[0]); - close(fd[1]); - - setenv("LESS", "FRSX", 0); - execlp(pager, pager, NULL); - execl("/bin/sh", "sh", "-c", pager, NULL); - - log_error("unable to execute pager '%s'", pager); - _exit(EXIT_FAILURE); + pid_t pid; + int fd[2]; + const char *pager; + + if (!on_tty() || arg_no_pager) + return; + + if ((pager = getenv("PAGER"))) + if (!*pager || streq(pager, "cat")) + return; + + if (pipe(fd) < 0) { + log_error("Failed to create pager pipe: %m"); + return; + } + + pid = fork(); + if (pid < 0) { + log_error("Failed to fork pager: %m"); + close_pipe(fd); + return; + } + + /* The original process turns into the PAGER */ + if (pid != 0) { + + dup2(fd[0], STDIN_FILENO); + close_pipe(fd); + + if (!getenv("LESS")) + setenv("LESS", "FRSX", 0); + + if (pager) { + execlp(pager, pager, NULL); + execl("/bin/sh", "sh", "-c", pager, NULL); + } else { + execlp("sensible-pager", "sensible-pager", NULL); + execlp("less", "less", NULL); + execlp("more", "more", NULL); + } + + log_error("Unable to execute pager: %m"); + _exit(EXIT_FAILURE); + } + + /* Return in the child */ + if (dup2(fd[1], STDOUT_FILENO) < 0) + log_error("Failed to duplicate pager pipe: %m"); + + close_pipe(fd); } int main(int argc, char*argv[]) { @@ -5341,7 +5352,7 @@ int main(int argc, char*argv[]) { goto finish; } - pager_open(); + pager_open(); /* /sbin/runlevel doesn't need to communicate via D-Bus, so * let's shortcut this */ |