restoreSignals() + restoreAffinity() -> restoreProcessContext()
This commit is contained in:
parent
8a29052cb2
commit
9b9e703df4
9 changed files with 32 additions and 42 deletions
|
@ -310,7 +310,7 @@ void printVersion(const string & programName)
|
||||||
|
|
||||||
void showManPage(const string & name)
|
void showManPage(const string & name)
|
||||||
{
|
{
|
||||||
restoreSignals();
|
restoreProcessContext();
|
||||||
setenv("MANPATH", settings.nixManDir.c_str(), 1);
|
setenv("MANPATH", settings.nixManDir.c_str(), 1);
|
||||||
execlp("man", "man", name.c_str(), nullptr);
|
execlp("man", "man", name.c_str(), nullptr);
|
||||||
throw SysError("command 'man %1%' failed", name.c_str());
|
throw SysError("command 'man %1%' failed", name.c_str());
|
||||||
|
@ -373,7 +373,7 @@ RunPager::RunPager()
|
||||||
throw SysError("dupping stdin");
|
throw SysError("dupping stdin");
|
||||||
if (!getenv("LESS"))
|
if (!getenv("LESS"))
|
||||||
setenv("LESS", "FRSXMK", 1);
|
setenv("LESS", "FRSXMK", 1);
|
||||||
restoreSignals();
|
restoreProcessContext();
|
||||||
if (pager)
|
if (pager)
|
||||||
execl("/bin/sh", "sh", "-c", pager, nullptr);
|
execl("/bin/sh", "sh", "-c", pager, nullptr);
|
||||||
execlp("pager", "pager", nullptr);
|
execlp("pager", "pager", nullptr);
|
||||||
|
|
|
@ -50,7 +50,7 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string
|
||||||
options.dieWithParent = false;
|
options.dieWithParent = false;
|
||||||
|
|
||||||
conn->sshPid = startProcess([&]() {
|
conn->sshPid = startProcess([&]() {
|
||||||
restoreSignals();
|
restoreProcessContext();
|
||||||
|
|
||||||
close(in.writeSide.get());
|
close(in.writeSide.get());
|
||||||
close(out.readSide.get());
|
close(out.readSide.get());
|
||||||
|
@ -110,7 +110,7 @@ Path SSHMaster::startMaster()
|
||||||
options.dieWithParent = false;
|
options.dieWithParent = false;
|
||||||
|
|
||||||
state->sshMaster = startProcess([&]() {
|
state->sshMaster = startProcess([&]() {
|
||||||
restoreSignals();
|
restoreProcessContext();
|
||||||
|
|
||||||
close(out.readSide.get());
|
close(out.readSide.get());
|
||||||
|
|
||||||
|
|
|
@ -1116,7 +1116,7 @@ void runProgram2(const RunOptions & options)
|
||||||
Strings args_(options.args);
|
Strings args_(options.args);
|
||||||
args_.push_front(options.program);
|
args_.push_front(options.program);
|
||||||
|
|
||||||
restoreSignals();
|
restoreProcessContext();
|
||||||
|
|
||||||
if (options.searchPath)
|
if (options.searchPath)
|
||||||
execvp(options.program.c_str(), stringsToCharPtrs(args_).data());
|
execvp(options.program.c_str(), stringsToCharPtrs(args_).data());
|
||||||
|
@ -1612,12 +1612,19 @@ void startSignalHandlerThread()
|
||||||
std::thread(signalHandlerThread, set).detach();
|
std::thread(signalHandlerThread, set).detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
void restoreSignals()
|
static void restoreSignals()
|
||||||
{
|
{
|
||||||
if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr))
|
if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr))
|
||||||
throw SysError("restoring signals");
|
throw SysError("restoring signals");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void restoreProcessContext()
|
||||||
|
{
|
||||||
|
restoreSignals();
|
||||||
|
|
||||||
|
restoreAffinity();
|
||||||
|
}
|
||||||
|
|
||||||
/* RAII helper to automatically deregister a callback. */
|
/* RAII helper to automatically deregister a callback. */
|
||||||
struct InterruptCallbackImpl : InterruptCallback
|
struct InterruptCallbackImpl : InterruptCallback
|
||||||
{
|
{
|
||||||
|
@ -1680,10 +1687,11 @@ string showBytes(uint64_t bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: move to libstore/build
|
||||||
void commonChildInit(Pipe & logPipe)
|
void commonChildInit(Pipe & logPipe)
|
||||||
{
|
{
|
||||||
const static string pathNullDevice = "/dev/null";
|
const static string pathNullDevice = "/dev/null";
|
||||||
restoreSignals();
|
restoreProcessContext();
|
||||||
|
|
||||||
/* Put the child in a separate session (and thus a separate
|
/* Put the child in a separate session (and thus a separate
|
||||||
process group) so that it has no controlling terminal (meaning
|
process group) so that it has no controlling terminal (meaning
|
||||||
|
|
|
@ -300,6 +300,11 @@ std::pair<int, std::string> runProgram(const RunOptions & options);
|
||||||
void runProgram2(const RunOptions & options);
|
void runProgram2(const RunOptions & options);
|
||||||
|
|
||||||
|
|
||||||
|
/* Restore the original inherited Unix process context (such as signal
|
||||||
|
masks, stack size, CPU affinity). */
|
||||||
|
void restoreProcessContext();
|
||||||
|
|
||||||
|
|
||||||
class ExecError : public Error
|
class ExecError : public Error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -513,9 +518,6 @@ class Callback;
|
||||||
on the current thread (and thus any threads created by it). */
|
on the current thread (and thus any threads created by it). */
|
||||||
void startSignalHandlerThread();
|
void startSignalHandlerThread();
|
||||||
|
|
||||||
/* Restore default signal handling. */
|
|
||||||
void restoreSignals();
|
|
||||||
|
|
||||||
struct InterruptCallback
|
struct InterruptCallback
|
||||||
{
|
{
|
||||||
virtual ~InterruptCallback() { };
|
virtual ~InterruptCallback() { };
|
||||||
|
|
|
@ -422,8 +422,6 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
} else
|
} else
|
||||||
env[var.first] = var.second;
|
env[var.first] = var.second;
|
||||||
|
|
||||||
restoreAffinity();
|
|
||||||
|
|
||||||
/* Run a shell using the derivation's environment. For
|
/* Run a shell using the derivation's environment. For
|
||||||
convenience, source $stdenv/setup to setup additional
|
convenience, source $stdenv/setup to setup additional
|
||||||
environment variables and shell functions. Also don't
|
environment variables and shell functions. Also don't
|
||||||
|
@ -473,7 +471,7 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
|
|
||||||
auto argPtrs = stringsToCharPtrs(args);
|
auto argPtrs = stringsToCharPtrs(args);
|
||||||
|
|
||||||
restoreSignals();
|
restoreProcessContext();
|
||||||
|
|
||||||
logger->stop();
|
logger->stop();
|
||||||
|
|
||||||
|
|
|
@ -462,8 +462,7 @@ struct CmdDevelop : Common, MixEnvironment
|
||||||
auto args = phase || !command.empty() ? Strings{std::string(baseNameOf(shell)), rcFilePath}
|
auto args = phase || !command.empty() ? Strings{std::string(baseNameOf(shell)), rcFilePath}
|
||||||
: Strings{std::string(baseNameOf(shell)), "--rcfile", rcFilePath};
|
: Strings{std::string(baseNameOf(shell)), "--rcfile", rcFilePath};
|
||||||
|
|
||||||
restoreAffinity();
|
restoreProcessContext();
|
||||||
restoreSignals();
|
|
||||||
|
|
||||||
execvp(shell.c_str(), stringsToCharPtrs(args).data());
|
execvp(shell.c_str(), stringsToCharPtrs(args).data());
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,8 @@ struct CmdEdit : InstallableCommand
|
||||||
|
|
||||||
auto args = editorFor(pos);
|
auto args = editorFor(pos);
|
||||||
|
|
||||||
restoreSignals();
|
restoreProcessContext();
|
||||||
|
|
||||||
execvp(args.front().c_str(), stringsToCharPtrs(args).data());
|
execvp(args.front().c_str(), stringsToCharPtrs(args).data());
|
||||||
|
|
||||||
std::string command;
|
std::string command;
|
||||||
|
|
|
@ -343,24 +343,6 @@ StringSet NixRepl::completePrefix(string prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int runProgram(const string & program, const Strings & args)
|
|
||||||
{
|
|
||||||
Strings args2(args);
|
|
||||||
args2.push_front(program);
|
|
||||||
|
|
||||||
Pid pid;
|
|
||||||
pid = fork();
|
|
||||||
if (pid == -1) throw SysError("forking");
|
|
||||||
if (pid == 0) {
|
|
||||||
restoreAffinity();
|
|
||||||
execvp(program.c_str(), stringsToCharPtrs(args2).data());
|
|
||||||
_exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pid.wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool isVarName(const string & s)
|
bool isVarName(const string & s)
|
||||||
{
|
{
|
||||||
if (s.size() == 0) return false;
|
if (s.size() == 0) return false;
|
||||||
|
@ -462,7 +444,7 @@ bool NixRepl::processLine(string line)
|
||||||
auto args = editorFor(pos);
|
auto args = editorFor(pos);
|
||||||
auto editor = args.front();
|
auto editor = args.front();
|
||||||
args.pop_front();
|
args.pop_front();
|
||||||
runProgram(editor, args);
|
runProgram(editor, true, args);
|
||||||
|
|
||||||
// Reload right after exiting the editor
|
// Reload right after exiting the editor
|
||||||
state->resetFileCache();
|
state->resetFileCache();
|
||||||
|
@ -481,7 +463,7 @@ bool NixRepl::processLine(string line)
|
||||||
state->callFunction(f, v, result, Pos());
|
state->callFunction(f, v, result, Pos());
|
||||||
|
|
||||||
StorePath drvPath = getDerivationPath(result);
|
StorePath drvPath = getDerivationPath(result);
|
||||||
runProgram(settings.nixBinDir + "/nix-shell", Strings{state->store->printStorePath(drvPath)});
|
runProgram(settings.nixBinDir + "/nix-shell", true, {state->store->printStorePath(drvPath)});
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (command == ":b" || command == ":i" || command == ":s") {
|
else if (command == ":b" || command == ":i" || command == ":s") {
|
||||||
|
@ -494,16 +476,18 @@ bool NixRepl::processLine(string line)
|
||||||
/* We could do the build in this process using buildPaths(),
|
/* We could do the build in this process using buildPaths(),
|
||||||
but doing it in a child makes it easier to recover from
|
but doing it in a child makes it easier to recover from
|
||||||
problems / SIGINT. */
|
problems / SIGINT. */
|
||||||
if (runProgram(settings.nixBinDir + "/nix", Strings{"build", "--no-link", drvPathRaw}) == 0) {
|
try {
|
||||||
|
runProgram(settings.nixBinDir + "/nix", true, {"build", "--no-link", drvPathRaw});
|
||||||
auto drv = state->store->readDerivation(drvPath);
|
auto drv = state->store->readDerivation(drvPath);
|
||||||
std::cout << std::endl << "this derivation produced the following outputs:" << std::endl;
|
std::cout << std::endl << "this derivation produced the following outputs:" << std::endl;
|
||||||
for (auto & i : drv.outputsAndOptPaths(*state->store))
|
for (auto & i : drv.outputsAndOptPaths(*state->store))
|
||||||
std::cout << fmt(" %s -> %s\n", i.first, state->store->printStorePath(*i.second.second));
|
std::cout << fmt(" %s -> %s\n", i.first, state->store->printStorePath(*i.second.second));
|
||||||
|
} catch (ExecError &) {
|
||||||
}
|
}
|
||||||
} else if (command == ":i") {
|
} else if (command == ":i") {
|
||||||
runProgram(settings.nixBinDir + "/nix-env", Strings{"-i", drvPathRaw});
|
runProgram(settings.nixBinDir + "/nix-env", true, {"-i", drvPathRaw});
|
||||||
} else {
|
} else {
|
||||||
runProgram(settings.nixBinDir + "/nix-shell", Strings{drvPathRaw});
|
runProgram(settings.nixBinDir + "/nix-shell", true, {drvPathRaw});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,7 @@ struct RunCommon : virtual Command
|
||||||
{
|
{
|
||||||
stopProgressBar();
|
stopProgressBar();
|
||||||
|
|
||||||
restoreSignals();
|
restoreProcessContext();
|
||||||
|
|
||||||
restoreAffinity();
|
|
||||||
|
|
||||||
/* If this is a diverted store (i.e. its "logical" location
|
/* If this is a diverted store (i.e. its "logical" location
|
||||||
(typically /nix/store) differs from its "physical" location
|
(typically /nix/store) differs from its "physical" location
|
||||||
|
|
Loading…
Reference in a new issue