diff options
Diffstat (limited to 'src/nix/repl.cc')
-rw-r--r-- | src/nix/repl.cc | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/src/nix/repl.cc b/src/nix/repl.cc index d4806d74adb8..d8f812149069 100644 --- a/src/nix/repl.cc +++ b/src/nix/repl.cc @@ -192,6 +192,14 @@ static int listPossibleCallback(char *s, char ***avp) { return ac; } +namespace { + // Used to communicate to NixRepl::getLine whether a signal occurred in ::readline. + volatile sig_atomic_t g_signal_received = 0; + + void sigintHandler(int signo) { + g_signal_received = signo; + } +} void NixRepl::mainLoop(const std::vector<std::string> & files) { @@ -251,8 +259,40 @@ void NixRepl::mainLoop(const std::vector<std::string> & files) bool NixRepl::getLine(string & input, const std::string &prompt) { + struct sigaction act, old; + sigset_t savedSignalMask, set; + + auto setupSignals = [&]() { + act.sa_handler = sigintHandler; + sigfillset(&act.sa_mask); + act.sa_flags = 0; + if (sigaction(SIGINT, &act, &old)) + throw SysError("installing handler for SIGINT"); + + sigemptyset(&set); + sigaddset(&set, SIGINT); + if (sigprocmask(SIG_UNBLOCK, &set, &savedSignalMask)) + throw SysError("unblocking SIGINT"); + }; + auto restoreSignals = [&]() { + if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr)) + throw SysError("restoring signals"); + + if (sigaction(SIGINT, &old, 0)) + throw SysError("restoring handler for SIGINT"); + }; + + setupSignals(); char * s = readline(prompt.c_str()); Finally doFree([&]() { free(s); }); + restoreSignals(); + + if (g_signal_received) { + g_signal_received = 0; + input.clear(); + return true; + } + if (!s) return false; input += s; @@ -337,8 +377,6 @@ static int runProgram(const string & program, const Strings & args) if (pid == -1) throw SysError("forking"); if (pid == 0) { restoreAffinity(); - restoreSignals(); - restoreMountNamespace(); execvp(program.c_str(), stringsToCharPtrs(args2).data()); _exit(1); } @@ -643,30 +681,13 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m for (auto & i : *v.attrs) sorted[i.name] = i.value; - /* If this is a derivation, then don't show the - self-references ("all", "out", etc.). */ - StringSet hidden; - if (isDrv) { - hidden.insert("all"); - Bindings::iterator i = v.attrs->find(state.sOutputs); - if (i == v.attrs->end()) - hidden.insert("out"); - else { - state.forceList(*i->value); - for (unsigned int j = 0; j < i->value->listSize(); ++j) - hidden.insert(state.forceStringNoCtx(*i->value->listElems()[j])); - } - } - for (auto & i : sorted) { if (isVarName(i.first)) str << i.first; else printStringValue(str, i.first.c_str()); str << " = "; - if (hidden.find(i.first) != hidden.end()) - str << "«...»"; - else if (seen.find(i.second) != seen.end()) + if (seen.find(i.second) != seen.end()) str << "«repeated»"; else try { |