forked from lix-project/lix
nix-store -l: Automatically pipe output into $PAGER
This commit is contained in:
parent
894fa5e42d
commit
392430b2c4
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,18 @@ template<class N> N getIntArg(const string & opt,
|
||||||
/* Show the manual page for the specified program. */
|
/* Show the manual page for the specified program. */
|
||||||
void showManPage(const string & name);
|
void showManPage(const string & name);
|
||||||
|
|
||||||
|
/* The constructor of this class starts a pager if stdout is a
|
||||||
|
terminal and $PAGER is set. Stdout is redirected to the pager. */
|
||||||
|
class RunPager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RunPager();
|
||||||
|
~RunPager();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Pid pid;
|
||||||
|
};
|
||||||
|
|
||||||
extern volatile ::sig_atomic_t blockInt;
|
extern volatile ::sig_atomic_t blockInt;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -931,11 +931,11 @@ void closeOnExec(int fd)
|
||||||
|
|
||||||
void restoreSIGPIPE()
|
void restoreSIGPIPE()
|
||||||
{
|
{
|
||||||
struct sigaction act, oact;
|
struct sigaction act;
|
||||||
act.sa_handler = SIG_DFL;
|
act.sa_handler = SIG_DFL;
|
||||||
act.sa_flags = 0;
|
act.sa_flags = 0;
|
||||||
sigemptyset(&act.sa_mask);
|
sigemptyset(&act.sa_mask);
|
||||||
if (sigaction(SIGPIPE, &act, &oact)) throw SysError("resetting SIGPIPE");
|
if (sigaction(SIGPIPE, &act, 0)) throw SysError("resetting SIGPIPE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -459,6 +459,8 @@ static void opReadLog(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (!opFlags.empty()) throw UsageError("unknown flag");
|
if (!opFlags.empty()) throw UsageError("unknown flag");
|
||||||
|
|
||||||
|
RunPager pager;
|
||||||
|
|
||||||
foreach (Strings::iterator, i, opArgs) {
|
foreach (Strings::iterator, i, opArgs) {
|
||||||
Path path = useDeriver(followLinksToStorePath(*i));
|
Path path = useDeriver(followLinksToStorePath(*i));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue