diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-08-20T13·12+0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-08-20T13·12+0200 |
commit | 392430b2c4ceb2e476abe2b3acc928581b2a1445 (patch) | |
tree | 30db8572f28c8def55f3b4dcce988a6ed4c778e9 /src/libmain/shared.cc | |
parent | 894fa5e42dd952caa702794964a13845ccf6f29a (diff) |
nix-store -l: Automatically pipe output into $PAGER
Diffstat (limited to 'src/libmain/shared.cc')
-rw-r--r-- | src/libmain/shared.cc | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 9ac9d2773852..ba75847fdb63 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -285,4 +285,44 @@ int handleExceptions(const string & programName, std::function<void()> fun) } +RunPager::RunPager() +{ + string pager = getEnv("PAGER"); + if (!isatty(STDOUT_FILENO) || pager.empty()) return; + + /* Ignore SIGINT. The pager will handle it (and we'll get + SIGPIPE). */ + struct sigaction act; + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + sigemptyset(&act.sa_mask); + if (sigaction(SIGINT, &act, 0)) throw SysError("ignoring SIGINT"); + + restoreSIGPIPE(); + + Pipe toPager; + toPager.create(); + + pid = startProcess([&]() { + if (dup2(toPager.readSide, STDIN_FILENO) == -1) + throw SysError("dupping stdin"); + execl("/bin/sh", "sh", "-c", pager.c_str(), NULL); + throw SysError(format("executing `%1%'") % pager); + }); + + if (dup2(toPager.writeSide, STDOUT_FILENO) == -1) + throw SysError("dupping stdout"); + +} + + +RunPager::~RunPager() +{ + if (pid != -1) { + close(STDOUT_FILENO); + pid.wait(true); + } +} + + } |