aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bantyev <balsoft@balsoft.ru>2021-11-26 17:38:46 +0300
committerAlexander Bantyev <balsoft@balsoft.ru>2021-12-06 16:51:55 +0300
commit0a2fa2d68460eca946c91b72cd264725e5cda7db (patch)
tree75b89d7f5d549a501be198e3829e48d5fce7d067
parentd1aaa7ef71713b6693ad3ddf8704ce62bab82095 (diff)
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.
-rw-r--r--src/libmain/shared.cc4
-rw-r--r--src/libmain/shared.hh1
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;