diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libexpr/eval.cc | 24 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 8 | ||||
-rw-r--r-- | src/libstore/download.cc | 3 | ||||
-rw-r--r-- | src/libstore/download.hh | 3 | ||||
-rw-r--r-- | src/libutil/serialise.cc | 2 | ||||
-rw-r--r-- | src/libutil/serialise.hh | 9 | ||||
-rwxr-xr-x | src/nix-channel/nix-channel.cc | 2 | ||||
-rw-r--r-- | src/nix-daemon/nix-daemon.cc | 3 |
8 files changed, 36 insertions, 18 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 353097f89713..2473157b3f63 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -307,6 +307,8 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store) assert(gcInitialised); + static_assert(sizeof(Env) == 16); + /* Initialise the Nix expression search path. */ if (!settings.pureEval) { Strings paths = parseNixPath(getEnv("NIX_PATH", "")); @@ -352,6 +354,10 @@ Path EvalState::checkSourcePath(const Path & path_) { if (!allowedPaths) return path_; + auto i = resolvedPaths.find(path_); + if (i != resolvedPaths.end()) + return i->second; + bool found = false; for (auto & i : *allowedPaths) { @@ -369,8 +375,10 @@ Path EvalState::checkSourcePath(const Path & path_) Path path = canonPath(path_, true); for (auto & i : *allowedPaths) { - if (isDirOrInDir(path, i)) + if (isDirOrInDir(path, i)) { + resolvedPaths[path_] = path; return path; + } } throw RestrictedPathError("access to path '%1%' is forbidden in restricted mode", path); @@ -562,12 +570,12 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) if (!var.fromWith) return env->values[var.displ]; while (1) { - if (!env->haveWithAttrs) { + if (env->type == Env::HasWithExpr) { if (noEval) return 0; Value * v = allocValue(); evalAttrs(*env->up, (Expr *) env->values[0], *v); env->values[0] = v; - env->haveWithAttrs = true; + env->type = Env::HasWithAttrs; } Bindings::iterator j = env->values[0]->attrs->find(var.name); if (j != env->values[0]->attrs->end()) { @@ -597,6 +605,7 @@ Env & EvalState::allocEnv(size_t size) nrValuesInEnvs += size; Env * env = (Env *) allocBytes(sizeof(Env) + size * sizeof(Value *)); env->size = (decltype(Env::size)) size; + env->type = Env::Plain; /* We assume that env->values has been cleared by the allocator; maybeThunk() and lookupVar fromWith expect this. */ @@ -1199,7 +1208,7 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v) Env & env2(state.allocEnv(1)); env2.up = &env; env2.prevWith = prevWith; - env2.haveWithAttrs = false; + env2.type = Env::HasWithExpr; env2.values[0] = (Value *) attrs; body->eval(state, env2, v); @@ -1857,9 +1866,10 @@ size_t valueSize(Value & v) size_t sz = sizeof(Env) + sizeof(Value *) * env.size; - for (size_t i = 0; i < env.size; ++i) - if (env.values[i]) - sz += doValue(*env.values[i]); + if (env.type != Env::HasWithExpr) + for (size_t i = 0; i < env.size; ++i) + if (env.values[i]) + sz += doValue(*env.values[i]); if (env.up) sz += doEnv(*env.up); diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 86e93a5ac9ce..3725e45dad9b 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -7,6 +7,7 @@ #include "hash.hh" #include <map> +#include <unordered_map> namespace nix { @@ -34,8 +35,8 @@ struct Env { Env * up; unsigned short size; // used by ‘valueSize’ - unsigned short prevWith:15; // nr of levels up to next `with' environment - unsigned short haveWithAttrs:1; + unsigned short prevWith:14; // nr of levels up to next `with' environment + enum { Plain = 0, HasWithExpr, HasWithAttrs } type:2; Value * values[0]; }; @@ -100,6 +101,9 @@ private: std::map<std::string, std::pair<bool, std::string>> searchPathResolved; + /* Cache used by checkSourcePath(). */ + std::unordered_map<Path, Path> resolvedPaths; + public: EvalState(const Strings & _searchPath, ref<Store> store); diff --git a/src/libstore/download.cc b/src/libstore/download.cc index 18f9094f82e0..54f4dd218007 100644 --- a/src/libstore/download.cc +++ b/src/libstore/download.cc @@ -623,7 +623,7 @@ DownloadResult Downloader::download(const DownloadRequest & request) return enqueueDownload(request).get(); } -Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpack, string name, const Hash & expectedHash, string * effectiveUrl) +Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpack, string name, const Hash & expectedHash, string * effectiveUrl, int ttl) { auto url = resolveUri(url_); @@ -653,7 +653,6 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa string expectedETag; - int ttl = settings.tarballTtl; bool skip = false; if (pathExists(fileLink) && pathExists(dataFile)) { diff --git a/src/libstore/download.hh b/src/libstore/download.hh index 0b8d29b21dfe..7ade756fc356 100644 --- a/src/libstore/download.hh +++ b/src/libstore/download.hh @@ -2,6 +2,7 @@ #include "types.hh" #include "hash.hh" +#include "globals.hh" #include <string> #include <future> @@ -54,7 +55,7 @@ struct Downloader use the recorded ETag to verify if the server has a more recent version, and if so, download it to the Nix store. */ Path downloadCached(ref<Store> store, const string & uri, bool unpack, string name = "", - const Hash & expectedHash = Hash(), string * effectiveUri = nullptr); + const Hash & expectedHash = Hash(), string * effectiveUri = nullptr, int ttl = settings.tarballTtl); enum Error { NotFound, Forbidden, Misc, Transient, Interrupted }; }; diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc index 33ae1ea389d7..21803edd056a 100644 --- a/src/libutil/serialise.cc +++ b/src/libutil/serialise.cc @@ -133,7 +133,7 @@ size_t FdSource::readUnbuffered(unsigned char * data, size_t len) ssize_t n; do { checkInterrupt(); - n = ::read(fd, (char *) data, bufSize); + n = ::read(fd, (char *) data, len); } while (n == -1 && errno == EINTR); if (n == -1) { _good = false; throw SysError("reading from file"); } if (n == 0) { _good = false; throw EndOfFile("unexpected end-of-file"); } diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh index 6e703c52a1e3..14b62fdb6774 100644 --- a/src/libutil/serialise.hh +++ b/src/libutil/serialise.hh @@ -77,10 +77,12 @@ struct BufferedSource : Source size_t read(unsigned char * data, size_t len) override; - /* Underlying read call, to be overridden. */ - virtual size_t readUnbuffered(unsigned char * data, size_t len) = 0; bool hasData(); + +protected: + /* Underlying read call, to be overridden. */ + virtual size_t readUnbuffered(unsigned char * data, size_t len) = 0; }; @@ -134,8 +136,9 @@ struct FdSource : BufferedSource return *this; } - size_t readUnbuffered(unsigned char * data, size_t len) override; bool good() override; +protected: + size_t readUnbuffered(unsigned char * data, size_t len) override; private: bool _good = true; }; diff --git a/src/nix-channel/nix-channel.cc b/src/nix-channel/nix-channel.cc index d1b47ede803f..55ebda438965 100755 --- a/src/nix-channel/nix-channel.cc +++ b/src/nix-channel/nix-channel.cc @@ -86,7 +86,7 @@ static void update(const StringSet & channelNames) // definition from a consistent location if the redirect changes mid-download. std::string effectiveUrl; auto dl = getDownloader(); - auto filename = dl->downloadCached(store, url, false, "", Hash(), &effectiveUrl); + auto filename = dl->downloadCached(store, url, false, "", Hash(), &effectiveUrl, 0); url = chomp(std::move(effectiveUrl)); // If the URL contains a version number, append it to the name diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index 35603af7082a..3dd8cec290cb 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -197,7 +197,8 @@ struct TunnelSource : BufferedSource { Source & from; TunnelSource(Source & from) : from(from) { } - size_t readUnbuffered(unsigned char * data, size_t len) +protected: + size_t readUnbuffered(unsigned char * data, size_t len) override { to << STDERR_READ << len; to.flush(); |