From 0a2fa2d68460eca946c91b72cd264725e5cda7db Mon Sep 17 00:00:00 2001 From: Alexander Bantyev Date: Fri, 26 Nov 2021 17:38:46 +0300 Subject: [PATCH] RunPager: restore stdout upon pager exit Before this change, stdout was closed after the pager exits. This is fine for non-interactive commands where we want to exit right after the pager exits anyways, but for interactive things (e.g. nix repl) this breaks the output after we quit the pager. Keep the initial stdout fd as part of RunPager, and restore it in RunPager::~RunPager using dup2. --- src/libmain/shared.cc | 4 ++-- src/libmain/shared.hh | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index b6bfea8cb..4404e0195 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -427,7 +427,7 @@ RunPager::RunPager() }); pid.setKillSignal(SIGINT); - + stdout = fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 0); if (dup2(toPager.writeSide.get(), STDOUT_FILENO) == -1) throw SysError("dupping stdout"); } @@ -438,7 +438,7 @@ RunPager::~RunPager() try { if (pid != -1) { std::cout.flush(); - close(STDOUT_FILENO); + dup2(stdout, STDOUT_FILENO); pid.wait(); } } catch (...) { diff --git a/src/libmain/shared.hh b/src/libmain/shared.hh index 05277d90a..ed012959b 100644 --- a/src/libmain/shared.hh +++ b/src/libmain/shared.hh @@ -88,6 +88,7 @@ public: private: Pid pid; + int stdout; }; extern volatile ::sig_atomic_t blockInt;