diff options
Diffstat (limited to 'src/shared/pager.c')
-rw-r--r-- | src/shared/pager.c | 68 |
1 files changed, 19 insertions, 49 deletions
diff --git a/src/shared/pager.c b/src/shared/pager.c index 39997278f1..75db3c985b 100644 --- a/src/shared/pager.c +++ b/src/shared/pager.c @@ -42,6 +42,11 @@ static pid_t pager_pid = 0; +static int stored_stdout = -1; +static int stored_stderr = -1; +static bool stdout_redirected = false; +static bool stderr_redirected = false; + noreturn static void pager_fallback(void) { int r; @@ -54,15 +59,10 @@ noreturn static void pager_fallback(void) { _exit(EXIT_SUCCESS); } -static int stored_stdout = -1; -static int stored_stderr = -1; -static bool stdout_redirected = false; -static bool stderr_redirected = false; - int pager_open(bool no_pager, bool jump_to_end) { _cleanup_close_pair_ int fd[2] = { -1, -1 }; const char *pager; - pid_t parent_pid; + int r; if (no_pager) return 0; @@ -73,6 +73,9 @@ int pager_open(bool no_pager, bool jump_to_end) { if (terminal_is_dumb()) return 0; + if (!is_main_thread()) + return -EPERM; + pager = getenv("SYSTEMD_PAGER"); if (!pager) pager = getenv("PAGER"); @@ -89,18 +92,13 @@ int pager_open(bool no_pager, bool jump_to_end) { if (pipe2(fd, O_CLOEXEC) < 0) return log_error_errno(errno, "Failed to create pager pipe: %m"); - parent_pid = getpid_cached(); - - pager_pid = fork(); - if (pager_pid < 0) - return log_error_errno(errno, "Failed to fork pager: %m"); - - /* In the child start the pager */ - if (pager_pid == 0) { + r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pager_pid); + if (r < 0) + return r; + if (r == 0) { const char* less_opts, *less_charset; - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); + /* In the child start the pager */ (void) dup2(fd[0], STDIN_FILENO); safe_close_pair(fd); @@ -124,15 +122,6 @@ int pager_open(bool no_pager, bool jump_to_end) { setenv("LESSCHARSET", less_charset, 1) < 0) _exit(EXIT_FAILURE); - /* Make sure the pager goes away when the parent dies */ - if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) - _exit(EXIT_FAILURE); - - /* Check whether our parent died before we were able - * to set the death signal */ - if (getppid() != parent_pid) - _exit(EXIT_SUCCESS); - if (pager) { execlp(pager, pager, NULL); execl("/bin/sh", "sh", "-c", pager, NULL); @@ -204,7 +193,6 @@ int show_man_page(const char *desc, bool null_stdio) { pid_t pid; size_t k; int r; - siginfo_t status; k = strlen(desc); @@ -222,33 +210,15 @@ int show_man_page(const char *desc, bool null_stdio) { } else args[1] = desc; - pid = fork(); - if (pid < 0) - return log_error_errno(errno, "Failed to fork: %m"); - - if (pid == 0) { + r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_NULL_STDIO : 0)|FORK_LOG, &pid); + if (r < 0) + return r; + if (r == 0) { /* Child */ - - (void) reset_all_signal_handlers(); - (void) reset_signal_mask(); - - if (null_stdio) { - r = make_null_stdio(); - if (r < 0) { - log_error_errno(r, "Failed to kill stdio: %m"); - _exit(EXIT_FAILURE); - } - } - execvp(args[0], (char**) args); log_error_errno(errno, "Failed to execute man: %m"); _exit(EXIT_FAILURE); } - r = wait_for_terminate(pid, &status); - if (r < 0) - return r; - - log_debug("Exit code %i status %i", status.si_code, status.si_status); - return status.si_status; + return wait_for_terminate_and_check(NULL, pid, 0); } |