diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 2998506b5..e2f5b087f 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -927,7 +927,7 @@ string runProgram(Path program, bool searchPath, const Strings & args, /* Wait for the child to finish. */ int status = pid.wait(true); if (!statusOk(status)) - throw ExecError(format("program ‘%1%’ %2%") + throw ExecError(status, format("program ‘%1%’ %2%") % program % statusToString(status)); return result; diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 1a43bf400..259c73260 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -247,7 +247,16 @@ pid_t startProcess(std::function fun, const ProcessOptions & options = P string runProgram(Path program, bool searchPath = false, const Strings & args = Strings(), const string & input = ""); -MakeError(ExecError, Error) +class ExecError : public Error +{ +public: + int status; + + template + ExecError(int status, Args... args) + : Error(args...), status(status) + { } +}; /* Convert a list of strings to a null-terminated vector of char *'s. The result must not be accessed beyond the lifetime of the diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index eb5719e47..b209464b8 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -60,6 +60,14 @@ std::vector shellwords(const string & s) return res; } +static void maybePrintExecError(ExecError & e) +{ + if (WIFEXITED(e.status)) + throw Exit(WEXITSTATUS(e.status)); + else + throw e; +} + int main(int argc, char ** argv) { return handleExceptions(argv[0], [&]() { @@ -346,8 +354,12 @@ int main(int argc, char ** argv) for (const auto & arg : instArgs) instantiateArgs.push_back(arg); instantiateArgs.push_back(expr); - auto instOutput = runProgram(settings.nixBinDir + "/nix-instantiate", false, instantiateArgs); - drvPaths = tokenizeString>(instOutput); + try { + auto instOutput = runProgram(settings.nixBinDir + "/nix-instantiate", false, instantiateArgs); + drvPaths = tokenizeString>(instOutput); + } catch (ExecError & e) { + maybePrintExecError(e); + } } else { drvPaths.push_back(expr); } @@ -370,7 +382,12 @@ int main(int argc, char ** argv) nixStoreArgs.push_back(input.first); for (const auto & src : drv.inputSrcs) nixStoreArgs.push_back(src); - runProgram(settings.nixBinDir + "/nix-store", false, nixStoreArgs); + + try { + runProgram(settings.nixBinDir + "/nix-store", false, nixStoreArgs); + } catch (ExecError & e) { + maybePrintExecError(e); + } // Set the environment. auto env = getEnv(); @@ -471,7 +488,14 @@ int main(int argc, char ** argv) nixStoreArgs.push_back(arg); for (const auto & path : drvPaths2) nixStoreArgs.push_back(path); - auto nixStoreRes = runProgram(settings.nixBinDir + "/nix-store", false, nixStoreArgs); + + std::string nixStoreRes; + try { + nixStoreRes = runProgram(settings.nixBinDir + "/nix-store", false, nixStoreArgs); + } catch (ExecError & e) { + maybePrintExecError(e); + } + for (const auto & outpath : tokenizeString>(nixStoreRes)) outPaths.push_back(chomp(outpath));