diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libexpr/eval.cc | 21 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 8 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 35 | ||||
-rw-r--r-- | src/libmain/shared.cc | 59 | ||||
-rw-r--r-- | src/libmain/stack.cc | 2 | ||||
-rw-r--r-- | src/libstore/build.cc | 64 | ||||
-rw-r--r-- | src/libstore/gc.cc | 4 | ||||
-rw-r--r-- | src/libstore/local-store.cc | 5 | ||||
-rw-r--r-- | src/libstore/pathlocks.cc | 2 | ||||
-rw-r--r-- | src/libstore/remote-store.cc | 2 | ||||
-rw-r--r-- | src/libutil/types.hh | 1 | ||||
-rw-r--r-- | src/libutil/util.cc | 92 | ||||
-rw-r--r-- | src/libutil/util.hh | 18 | ||||
-rw-r--r-- | src/nix-daemon/nix-daemon.cc | 37 | ||||
-rw-r--r-- | src/nix-instantiate/nix-instantiate.cc | 2 | ||||
-rw-r--r-- | src/nix-store/nix-store.cc | 2 |
16 files changed, 152 insertions, 202 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 2ff9756108ad..298f6a3a60e3 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -247,7 +247,6 @@ EvalState::EvalState(const Strings & _searchPath) EvalState::~EvalState() { fileEvalCache.clear(); - printCanaries(); } @@ -1514,26 +1513,6 @@ void EvalState::printStats() } -void EvalState::printCanaries() -{ -#if HAVE_BOEHMGC - if (!settings.get("debug-gc", false)) return; - - GC_gcollect(); - - if (gcCanaries.empty()) { - printMsg(lvlError, "all canaries have been garbage-collected"); - return; - } - - printMsg(lvlError, "the following canaries have not been garbage-collected:"); - - for (auto i : gcCanaries) - printMsg(lvlError, format(" %1%") % i->string.s); -#endif -} - - size_t valueSize(Value & v) { std::set<const void *> seen; diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 8bf65c2c55de..78942927fd24 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -287,8 +287,6 @@ public: /* Print statistics. */ void printStats(); - void printCanaries(); - private: unsigned long nrEnvs; @@ -320,12 +318,6 @@ private: friend struct ExprOpConcatLists; friend struct ExprSelect; friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v); - -#if HAVE_BOEHMGC - std::set<Value *> gcCanaries; - friend void canaryFinalizer(GC_PTR obj, GC_PTR client_data); - friend void prim_gcCanary(EvalState & state, const Pos & pos, Value * * args, Value & v); -#endif }; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index e7b79604699b..cd7b287e29c3 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -417,32 +417,6 @@ static void prim_trace(EvalState & state, const Pos & pos, Value * * args, Value } -#if HAVE_BOEHMGC -void canaryFinalizer(GC_PTR obj, GC_PTR client_data) -{ - Value * v = (Value *) obj; - EvalState & state(* (EvalState *) client_data); - printMsg(lvlError, format("canary ‘%1%’ garbage-collected") % v->string.s); - auto i = state.gcCanaries.find(v); - assert(i != state.gcCanaries.end()); - state.gcCanaries.erase(i); -} -#endif - - -void prim_gcCanary(EvalState & state, const Pos & pos, Value * * args, Value & v) -{ - string s = state.forceStringNoCtx(*args[0], pos); - state.mkList(v, 1); - Value * canary = v.list.elems[0] = state.allocValue(); -#if HAVE_BOEHMGC - state.gcCanaries.insert(canary); - GC_register_finalizer(canary, canaryFinalizer, &state, 0, 0); -#endif - mkString(*canary, s); -} - - void prim_valueSize(EvalState & state, const Pos & pos, Value * * args, Value & v) { /* We're not forcing the argument on purpose. */ @@ -756,8 +730,12 @@ static void prim_readFile(EvalState & state, const Pos & pos, Value * * args, Va { PathSet context; Path path = state.coerceToPath(pos, *args[0], context); - if (!context.empty()) - throw EvalError(format("string ‘%1%’ cannot refer to other paths, at %2%") % path % pos); + try { + realiseContext(context); + } catch (InvalidPathError & e) { + throw EvalError(format("cannot read ‘%1%’, since path ‘%2%’ is not valid, at %3%") + % path % e.path % pos); + } mkString(v, readFile(path).c_str()); } @@ -1556,7 +1534,6 @@ void EvalState::createBaseEnv() // Debugging addPrimOp("__trace", 2, prim_trace); - addPrimOp("__gcCanary", 1, prim_gcCanary); addPrimOp("__valueSize", 1, prim_valueSize); // Paths diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index bf5688a1e606..9c74a614e2e4 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -16,7 +16,6 @@ #include <sys/stat.h> #include <unistd.h> #include <signal.h> -#include <spawn.h> extern char * * environ; @@ -293,8 +292,9 @@ int handleExceptions(const string & programName, std::function<void()> fun) RunPager::RunPager() { - string pager = getEnv("PAGER"); - if (!isatty(STDOUT_FILENO) || pager.empty()) return; + if (!isatty(STDOUT_FILENO)) return; + string pager = getEnv("PAGER", "default"); + if (pager == "" || pager == "cat") return; /* Ignore SIGINT. The pager will handle it (and we'll get SIGPIPE). */ @@ -309,35 +309,18 @@ RunPager::RunPager() Pipe toPager; toPager.create(); - // FIXME: should do this in the child environment. - if (!getenv("LESS")) - setenv("LESS", "FRSXMK", 1); - - /* Start the pager using posix_spawn. */ - pid_t pid_; - const char * argv[] = { "sh", "-c", pager.c_str(), 0 }; - - posix_spawn_file_actions_t fileActions; - int err = posix_spawn_file_actions_init(&fileActions); - if (err) throw SysError(err, "creating POSIX file actions"); - err = posix_spawn_file_actions_adddup2(&fileActions, toPager.readSide, STDIN_FILENO); - if (err) throw SysError(err, "adding to POSIX file actions"); - - posix_spawnattr_t spawnAttrs; - err = posix_spawnattr_init(&spawnAttrs); - if (err) throw SysError(err, "creating POSIX spawn attrs"); -#ifdef POSIX_SPAWN_USEVFORK - err = posix_spawnattr_setflags(&spawnAttrs, POSIX_SPAWN_USEVFORK); - if (err) throw SysError(err, "setting POSIX spawn attr flag"); -#endif - - err = posix_spawn(&pid_, "/bin/sh", &fileActions, &spawnAttrs, (char * const *) argv, environ); - - posix_spawn_file_actions_destroy(&fileActions); - posix_spawnattr_destroy(&spawnAttrs); - - if (err) throw SysError(err, format("running ‘%1%’") % pager); - pid = pid_; + pid = startProcess([&]() { + if (dup2(toPager.readSide, STDIN_FILENO) == -1) + throw SysError("dupping stdin"); + if (!getenv("LESS")) + setenv("LESS", "FRSXMK", 1); + if (pager != "default") + execl("/bin/sh", "sh", "-c", pager.c_str(), NULL); + execlp("pager", "pager", NULL); + execlp("less", "less", NULL); + execlp("more", "more", NULL); + throw SysError(format("executing ‘%1%’") % pager); + }); if (dup2(toPager.writeSide, STDOUT_FILENO) == -1) throw SysError("dupping stdout"); @@ -346,10 +329,14 @@ RunPager::RunPager() RunPager::~RunPager() { - if (pid != -1) { - std::cout.flush(); - close(STDOUT_FILENO); - pid.wait(true); + try { + if (pid != -1) { + std::cout.flush(); + close(STDOUT_FILENO); + pid.wait(true); + } + } catch (...) { + ignoreException(); } } diff --git a/src/libmain/stack.cc b/src/libmain/stack.cc index b670e695d140..41b617d98be2 100644 --- a/src/libmain/stack.cc +++ b/src/libmain/stack.cc @@ -32,7 +32,7 @@ static void sigsegvHandler(int signo, siginfo_t * info, void * ctx) if (diff < 0) diff = -diff; if (diff < 4096) { char msg[] = "error: stack overflow (possible infinite recursion)\n"; - write(2, msg, strlen(msg)); + (void) write(2, msg, strlen(msg)); _exit(1); // maybe abort instead? } } diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 539d0b21b278..08f44b392b00 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -415,18 +415,6 @@ static void commonChildInit(Pipe & logPipe) } -/* Convert a string list to an array of char pointers. Careful: the - string list should outlive the array. */ -const char * * strings2CharPtrs(const Strings & ss) -{ - const char * * arr = new const char * [ss.size() + 1]; - const char * * p = arr; - foreach (Strings::const_iterator, i, ss) *p++ = i->c_str(); - *p = 0; - return arr; -} - - ////////////////////////////////////////////////////////////////////// @@ -816,8 +804,8 @@ private: /* Start building a derivation. */ void startBuilder(); - /* Initialise the builder's process. */ - void initChild(); + /* Run the builder's process. */ + void runChild(); friend int childEntry(void *); @@ -1914,9 +1902,11 @@ void DerivationGoal::startBuilder() builderOut.create(); /* Fork a child to build the package. */ + ProcessOptions options; + options.allowVfork = !buildUser.enabled(); pid = startProcess([&]() { - initChild(); - }); + runChild(); + }, options); /* parent */ pid.setSeparatePG(true); @@ -1936,7 +1926,7 @@ void DerivationGoal::startBuilder() } -void DerivationGoal::initChild() +void DerivationGoal::runChild() { /* Warning: in the child we should absolutely not make any SQLite calls! */ @@ -1986,9 +1976,11 @@ void DerivationGoal::initChild() /* Set the hostname etc. to fixed values. */ char hostname[] = "localhost"; - sethostname(hostname, sizeof(hostname)); + if (sethostname(hostname, sizeof(hostname)) == -1) + throw SysError("cannot set host name"); char domainname[] = "(none)"; // kernel default - setdomainname(domainname, sizeof(domainname)); + if (setdomainname(domainname, sizeof(domainname)) == -1) + throw SysError("cannot set domain name"); /* Make all filesystems private. This is necessary because subtrees may have been mounted as "shared" @@ -2122,11 +2114,7 @@ void DerivationGoal::initChild() Strings envStrs; foreach (Environment::const_iterator, i, env) envStrs.push_back(rewriteHashes(i->first + "=" + i->second, rewritesToTmp)); - const char * * envArr = strings2CharPtrs(envStrs); - - Path program = drv.builder.c_str(); - std::vector<const char *> args; /* careful with c_str()! */ - string user; /* must be here for its c_str()! */ + auto envArr = stringsToCharPtrs(envStrs); /* If we are running in `build-users' mode, then switch to the user we allocated above. Make sure that we drop all root @@ -2135,8 +2123,6 @@ void DerivationGoal::initChild() setuid() when run as root sets the real, effective and saved UIDs. */ if (buildUser.enabled()) { - printMsg(lvlChatty, format("switching to user ‘%1%’") % buildUser.getUser()); - if (setgroups(0, 0) == -1) throw SysError("cannot clear the set of supplementary groups"); @@ -2152,29 +2138,25 @@ void DerivationGoal::initChild() } /* Fill in the arguments. */ + Strings args; string builderBasename = baseNameOf(drv.builder); - args.push_back(builderBasename.c_str()); - foreach (Strings::iterator, i, drv.args) { - auto re = rewriteHashes(*i, rewritesToTmp); - auto cstr = new char[re.length()+1]; - std::strcpy(cstr, re.c_str()); - - args.push_back(cstr); - } - args.push_back(0); + args.push_back(builderBasename); + foreach (Strings::iterator, i, drv.args) + args.push_back(rewriteHashes(*i, rewritesToTmp)); + auto argArr = stringsToCharPtrs(args); restoreSIGPIPE(); /* Indicate that we managed to set up the build environment. */ - writeToStderr("\n"); + writeFull(STDERR_FILENO, "\n"); /* Execute the program. This should not return. */ - execve(program.c_str(), (char * *) &args[0], (char * *) envArr); + execve(drv.builder.c_str(), (char * *) &argArr[0], (char * *) &envArr[0]); throw SysError(format("executing ‘%1%’") % drv.builder); } catch (std::exception & e) { - writeToStderr("while setting up the build environment: " + string(e.what()) + "\n"); + writeFull(STDERR_FILENO, "while setting up the build environment: " + string(e.what()) + "\n"); _exit(1); } } @@ -2487,7 +2469,7 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) BZ2_bzWrite(&err, bzLogFile, (unsigned char *) data.data(), data.size()); if (err != BZ_OK) throw Error(format("cannot write to compressed log file (BZip2 error = %1%)") % err); } else if (fdLogFile != -1) - writeFull(fdLogFile, (unsigned char *) data.data(), data.size()); + writeFull(fdLogFile, data); } if (hook && fd == hook->fromHook.readSide) @@ -2797,7 +2779,7 @@ void SubstitutionGoal::tryToRun() args.push_back("--substitute"); args.push_back(storePath); args.push_back(destPath); - const char * * argArr = strings2CharPtrs(args); + auto argArr = stringsToCharPtrs(args); /* Fork the substitute program. */ pid = startProcess([&]() { @@ -2807,7 +2789,7 @@ void SubstitutionGoal::tryToRun() if (dup2(outPipe.writeSide, STDOUT_FILENO) == -1) throw SysError("cannot dup output pipe into stdout"); - execv(sub.c_str(), (char * *) argArr); + execv(sub.c_str(), (char * *) &argArr[0]); throw SysError(format("executing ‘%1%’") % sub); }); diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 49cb11d23290..7959a592d987 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -191,7 +191,7 @@ void LocalStore::addTempRoot(const Path & path) lockFile(fdTempRoots, ltWrite, true); string s = path + '\0'; - writeFull(fdTempRoots, (const unsigned char *) s.data(), s.size()); + writeFull(fdTempRoots, s); /* Downgrade to a read lock. */ debug(format("downgrading to read lock on ‘%1%’") % fnTempRoots); @@ -231,7 +231,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds) if (lockFile(*fd, ltWrite, false)) { printMsg(lvlError, format("removing stale temporary roots file ‘%1%’") % path); unlink(path.c_str()); - writeFull(*fd, (const unsigned char *) "d", 1); + writeFull(*fd, "d"); continue; } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index fc48c0405650..3ad80bc4e6f4 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -358,7 +358,8 @@ LocalStore::~LocalStore() i->second.to.close(); i->second.from.close(); i->second.error.close(); - i->second.pid.wait(true); + if (i->second.pid != -1) + i->second.pid.wait(true); } } catch (...) { ignoreException(); @@ -498,7 +499,7 @@ void LocalStore::makeStoreWritable() if (unshare(CLONE_NEWNS) == -1) throw SysError("setting up a private mount namespace"); - if (mount(0, settings.nixStore.c_str(), 0, MS_REMOUNT | MS_BIND, 0) == -1) + if (mount(0, settings.nixStore.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1) throw SysError(format("remounting %1% writable") % settings.nixStore); } #endif diff --git a/src/libstore/pathlocks.cc b/src/libstore/pathlocks.cc index f26684afacb9..9db37e8f9aaa 100644 --- a/src/libstore/pathlocks.cc +++ b/src/libstore/pathlocks.cc @@ -33,7 +33,7 @@ void deleteLockFile(const Path & path, int fd) other processes waiting on this lock that the lock is stale (deleted). */ unlink(path.c_str()); - writeFull(fd, (const unsigned char *) "d", 1); + writeFull(fd, "d"); /* Note that the result of unlink() is ignored; removing the lock file is an optimisation, not a necessity. */ } diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index cabde051bd02..d08913246321 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -110,7 +110,7 @@ void RemoteStore::connectToDaemon() applications... */ AutoCloseFD fdPrevDir = open(".", O_RDONLY); if (fdPrevDir == -1) throw SysError("couldn't open current directory"); - chdir(dirOf(socketPath).c_str()); + if (chdir(dirOf(socketPath).c_str()) == -1) throw SysError(format("couldn't change to directory of ‘%1%’") % socketPath); Path socketPathRel = "./" + baseNameOf(socketPath); struct sockaddr_un addr; diff --git a/src/libutil/types.hh b/src/libutil/types.hh index 030996a060e2..160884ee1ad7 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -73,7 +73,6 @@ class SysError : public Error public: int errNo; SysError(const FormatOrString & fs); - SysError(int errNo, const FormatOrString & fs); }; diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 60be02cd4647..dcdb438e03b2 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -45,14 +45,8 @@ BaseError & BaseError::addPrefix(const FormatOrString & fs) SysError::SysError(const FormatOrString & fs) - : SysError(errno, fs) -{ -} - - -SysError::SysError(int errNo, const FormatOrString & fs) - : Error(format("%1%: %2%") % fs.s % strerror(errNo)) - , errNo(errNo) + : Error(format("%1%: %2%") % fs.s % strerror(errno)) + , errNo(errno) { } @@ -271,7 +265,7 @@ void writeFile(const Path & path, const string & s) AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0666); if (fd == -1) throw SysError(format("opening file ‘%1%’") % path); - writeFull(fd, (unsigned char *) s.data(), s.size()); + writeFull(fd, s); } @@ -298,7 +292,7 @@ string readLine(int fd) void writeLine(int fd, string s) { s += '\n'; - writeFull(fd, (const unsigned char *) s.data(), s.size()); + writeFull(fd, s); } @@ -489,18 +483,13 @@ void warnOnce(bool & haveWarned, const FormatOrString & fs) } -static void defaultWriteToStderr(const unsigned char * buf, size_t count) -{ - writeFull(STDERR_FILENO, buf, count); -} - - void writeToStderr(const string & s) { try { - auto p = _writeToStderr; - if (!p) p = defaultWriteToStderr; - p((const unsigned char *) s.data(), s.size()); + if (_writeToStderr) + _writeToStderr((const unsigned char *) s.data(), s.size()); + else + writeFull(STDERR_FILENO, s); } catch (SysError & e) { /* Ignore failing writes to stderr if we're in an exception handler, otherwise throw an exception. We need to ignore @@ -512,7 +501,7 @@ void writeToStderr(const string & s) } -void (*_writeToStderr) (const unsigned char * buf, size_t count) = defaultWriteToStderr; +void (*_writeToStderr) (const unsigned char * buf, size_t count) = 0; void readFull(int fd, unsigned char * buf, size_t count) @@ -546,6 +535,12 @@ void writeFull(int fd, const unsigned char * buf, size_t count) } +void writeFull(int fd, const string & s) +{ + writeFull(fd, (const unsigned char *) s.data(), s.size()); +} + + string drainFD(int fd) { string result; @@ -831,6 +826,9 @@ void killUser(uid_t uid) users to which the current process can send signals. So we fork a process, switch to uid, and send a mass kill. */ + ProcessOptions options; + options.allowVfork = false; + Pid pid = startProcess([&]() { if (setuid(uid) == -1) @@ -853,7 +851,7 @@ void killUser(uid_t uid) } _exit(0); - }); + }, options); int status = pid.wait(true); if (status != 0) @@ -869,46 +867,64 @@ void killUser(uid_t uid) ////////////////////////////////////////////////////////////////////// -pid_t startProcess(std::function<void()> fun, - bool dieWithParent, const string & errorPrefix, bool runExitHandlers) +/* Wrapper around vfork to prevent the child process from clobbering + the caller's stack frame in the parent. */ +static pid_t doFork(bool allowVfork, std::function<void()> fun) __attribute__((noinline)); +static pid_t doFork(bool allowVfork, std::function<void()> fun) { +#ifdef __linux__ + pid_t pid = allowVfork ? vfork() : fork(); +#else pid_t pid = fork(); - if (pid == -1) throw SysError("unable to fork"); +#endif + if (pid != 0) return pid; + fun(); + abort(); +} - if (pid == 0) { - _writeToStderr = 0; + +pid_t startProcess(std::function<void()> fun, const ProcessOptions & options) +{ + auto wrapper = [&]() { + if (!options.allowVfork) _writeToStderr = 0; try { #if __linux__ - if (dieWithParent && prctl(PR_SET_PDEATHSIG, SIGKILL) == -1) + if (options.dieWithParent && prctl(PR_SET_PDEATHSIG, SIGKILL) == -1) throw SysError("setting death signal"); #endif restoreAffinity(); fun(); } catch (std::exception & e) { try { - std::cerr << errorPrefix << e.what() << "\n"; + std::cerr << options.errorPrefix << e.what() << "\n"; } catch (...) { } } catch (...) { } - if (runExitHandlers) + if (options.runExitHandlers) exit(1); else _exit(1); - } + }; + + pid_t pid = doFork(options.allowVfork, wrapper); + if (pid == -1) throw SysError("unable to fork"); return pid; } +std::vector<const char *> stringsToCharPtrs(const Strings & ss) +{ + std::vector<const char *> res; + for (auto & s : ss) res.push_back(s.c_str()); + res.push_back(0); + return res; +} + + string runProgram(Path program, bool searchPath, const Strings & args) { checkInterrupt(); - std::vector<const char *> cargs; /* careful with c_str()! */ - cargs.push_back(program.c_str()); - for (Strings::const_iterator i = args.begin(); i != args.end(); ++i) - cargs.push_back(i->c_str()); - cargs.push_back(0); - /* Create a pipe. */ Pipe pipe; pipe.create(); @@ -918,6 +934,10 @@ string runProgram(Path program, bool searchPath, const Strings & args) if (dup2(pipe.writeSide, STDOUT_FILENO) == -1) throw SysError("dupping stdout"); + Strings args_(args); + args_.push_front(program); + auto cargs = stringsToCharPtrs(args_); + if (searchPath) execvp(program.c_str(), (char * *) &cargs[0]); else diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 628b8a0e1f09..186ee71f45d0 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -171,6 +171,7 @@ extern void (*_writeToStderr) (const unsigned char * buf, size_t count); requested number of bytes. */ void readFull(int fd, unsigned char * buf, size_t count); void writeFull(int fd, const unsigned char * buf, size_t count); +void writeFull(int fd, const string & s); MakeError(EndOfFile, Error) @@ -269,8 +270,16 @@ void killUser(uid_t uid); /* Fork a process that runs the given function, and return the child pid to the caller. */ -pid_t startProcess(std::function<void()> fun, bool dieWithParent = true, - const string & errorPrefix = "error: ", bool runExitHandlers = false); +struct ProcessOptions +{ + string errorPrefix; + bool dieWithParent; + bool runExitHandlers; + bool allowVfork; + ProcessOptions() : errorPrefix("error: "), dieWithParent(true), runExitHandlers(false), allowVfork(true) { }; +}; + +pid_t startProcess(std::function<void()> fun, const ProcessOptions & options = ProcessOptions()); /* Run a program and return its stdout in a string (i.e., like the @@ -280,6 +289,11 @@ string runProgram(Path program, bool searchPath = false, MakeError(ExecError, Error) +/* Convert a list of strings to a null-terminated vector of char + *'s. The result must not be accessed beyond the lifetime of the + list of strings. */ +std::vector<const char *> stringsToCharPtrs(const Strings & ss); + /* Close all file descriptors except stdin, stdout, stderr, and those listed in the given set. Good practice in child processes. */ void closeMostFDs(const set<int> & exceptions); diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index 3864ab935de0..bed7de0859a3 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -513,11 +513,11 @@ static void performOp(bool trusted, unsigned int clientVersion, } case wopOptimiseStore: - startWork(); - store->optimiseStore(); - stopWork(); - writeInt(1, to); - break; + startWork(); + store->optimiseStore(); + stopWork(); + writeInt(1, to); + break; default: throw Error(format("invalid operation %1%") % op); @@ -610,6 +610,8 @@ static void processConnection(bool trusted) assert(!canSendStderr); }; + canSendStderr = false; + _isInterrupted = false; printMsg(lvlDebug, format("%1% operations") % opCount); } @@ -696,7 +698,8 @@ static PeerInfo getPeerInfo(int remote) static void daemonLoop(char * * argv) { - chdir("/"); + if (chdir("/") == -1) + throw SysError("cannot change current directory"); /* Get rid of children automatically; don't let them become zombies. */ @@ -726,7 +729,8 @@ static void daemonLoop(char * * argv) /* Urgh, sockaddr_un allows path names of only 108 characters. So chdir to the socket directory so that we can pass a relative path name. */ - chdir(dirOf(socketPath).c_str()); + if (chdir(dirOf(socketPath).c_str()) == -1) + throw SysError("cannot change current directory"); Path socketPathRel = "./" + baseNameOf(socketPath); struct sockaddr_un addr; @@ -746,7 +750,8 @@ static void daemonLoop(char * * argv) if (res == -1) throw SysError(format("cannot bind to socket ‘%1%’") % socketPath); - chdir("/"); /* back to the root */ + if (chdir("/") == -1) /* back to the root */ + throw SysError("cannot change current directory"); if (listen(fdSocket, 5) == -1) throw SysError(format("cannot listen on socket ‘%1%’") % socketPath); @@ -799,6 +804,11 @@ static void daemonLoop(char * * argv) % (peer.uidKnown ? user : "<unknown>")); /* Fork a child to handle the connection. */ + ProcessOptions options; + options.errorPrefix = "unexpected Nix daemon error: "; + options.dieWithParent = false; + options.runExitHandlers = true; + options.allowVfork = false; startProcess([&]() { fdSocket.close(); @@ -821,7 +831,7 @@ static void daemonLoop(char * * argv) processConnection(trusted); exit(0); - }, false, "unexpected Nix daemon error: ", true); + }, options); } catch (Interrupted & e) { throw; @@ -832,15 +842,6 @@ static void daemonLoop(char * * argv) } -void run(Strings args) -{ - for (Strings::iterator i = args.begin(); i != args.end(); ) { - string arg = *i++; - } - -} - - int main(int argc, char * * argv) { return handleExceptions(argv[0], [&]() { diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc index 9a6e178f514e..e7214e657bd5 100644 --- a/src/nix-instantiate/nix-instantiate.cc +++ b/src/nix-instantiate/nix-instantiate.cc @@ -86,8 +86,6 @@ void processExpr(EvalState & state, const Strings & attrPaths, } } } - - state.printCanaries(); } diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index c91bca97d534..87bc8c379de5 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -488,7 +488,7 @@ static void opReadLog(Strings opFlags, Strings opArgs) if (pathExists(logPath)) { /* !!! Make this run in O(1) memory. */ string log = readFile(logPath); - writeFull(STDOUT_FILENO, (const unsigned char *) log.data(), log.size()); + writeFull(STDOUT_FILENO, log); found = true; break; } |