diff options
author | Matija Skala <mskala@gmx.com> | 2017-04-24 18:30:50 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2017-04-24 18:30:50 +0200 |
commit | a45e7bb4084bade974ef2c8b40172e548478aafd (patch) | |
tree | e5ac2726b5a5c61693c9367199bd04b44aecd7d0 /src/shared/pager.c | |
parent | load-fragment: resolve specifiers in BindPaths/BindReadOnlyPaths (#5687) (diff) | |
download | systemd-a45e7bb4084bade974ef2c8b40172e548478aafd.tar.xz systemd-a45e7bb4084bade974ef2c8b40172e548478aafd.zip |
redirect stdout/stderr back when closing the pager (#5661)
Diffstat (limited to 'src/shared/pager.c')
-rw-r--r-- | src/shared/pager.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/src/shared/pager.c b/src/shared/pager.c index c1480a718b..2501a53c19 100644 --- a/src/shared/pager.c +++ b/src/shared/pager.c @@ -53,6 +53,11 @@ 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; @@ -147,10 +152,19 @@ int pager_open(bool no_pager, bool jump_to_end) { } /* Return in the parent */ - if (dup2(fd[1], STDOUT_FILENO) < 0) + stored_stdout = fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 3); + if (dup2(fd[1], STDOUT_FILENO) < 0) { + stored_stdout = safe_close(stored_stdout); return log_error_errno(errno, "Failed to duplicate pager pipe: %m"); - if (dup2(fd[1], STDERR_FILENO) < 0) + } + stdout_redirected = true; + + stored_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3); + if (dup2(fd[1], STDERR_FILENO) < 0) { + stored_stderr = safe_close(stored_stderr); return log_error_errno(errno, "Failed to duplicate pager pipe: %m"); + } + stderr_redirected = true; return 1; } @@ -161,8 +175,15 @@ void pager_close(void) { return; /* Inform pager that we are done */ - safe_fclose(stdout); - safe_fclose(stderr); + (void) fflush(stdout); + if (stdout_redirected && (stored_stdout < 0 || dup2(stored_stdout, STDOUT_FILENO)) < 0) + (void) close(STDOUT_FILENO); + stored_stdout = safe_close(stored_stdout); + (void) fflush(stderr); + if (stderr_redirected && (stored_stderr < 0 || dup2(stored_stderr, STDERR_FILENO)) < 0) + (void) close(STDERR_FILENO); + stored_stderr = safe_close(stored_stderr); + stdout_redirected = stderr_redirected = false; (void) kill(pager_pid, SIGCONT); (void) wait_for_terminate(pager_pid, NULL); |