From 74f75c855837bce7f48491e9ce8ac03794e5b40d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 12 Jan 2018 17:31:08 +0100 Subject: import, builtins.readFile: Handle diverted stores Fixes #1791 --- src/libexpr/eval.cc | 10 ++++++++++ src/libexpr/eval.hh | 9 +++++++++ src/libexpr/primops.cc | 12 ++++++------ 3 files changed, 25 insertions(+), 6 deletions(-) (limited to 'src/libexpr') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 63de2d60a..087a95dde 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -375,6 +375,16 @@ void EvalState::checkURI(const std::string & uri) } +Path EvalState::toRealPath(const Path & path, const PathSet & context) +{ + // FIXME: check whether 'path' is in 'context'. + return + !context.empty() && store->isInStore(path) + ? store->toRealPath(path) + : path; +}; + + void EvalState::addConstant(const string & name, Value & v) { Value * v2 = allocValue(); diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index f0ab1435b..cc971ae80 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -112,6 +112,15 @@ public: void checkURI(const std::string & uri); + /* When using a diverted store and 'path' is in the Nix store, map + 'path' to the diverted location (e.g. /nix/store/foo is mapped + to /home/alice/my-nix/nix/store/foo). However, this is only + done if the context is not empty, since otherwise we're + probably trying to read from the actual /nix/store. This is + intended to distinguish between import-from-derivation and + sources stored in the actual /nix/store. */ + Path toRealPath(const Path & path, const PathSet & context); + /* Parse a Nix expression from the specified file. */ Expr * parseExprFromFile(const Path & path); Expr * parseExprFromFile(const Path & path, StaticEnv & staticEnv); diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 602971427..98fe2199e 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -84,10 +84,10 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args % path % e.path % pos); } - path = state.checkSourcePath(path); + Path realPath = state.checkSourcePath(state.toRealPath(path, context)); if (state.store->isStorePath(path) && state.store->isValidPath(path) && isDerivation(path)) { - Derivation drv = readDerivation(path); + Derivation drv = readDerivation(realPath); Value & w = *state.allocValue(); state.mkAttrs(w, 3 + drv.outputs.size()); Value * v2 = state.allocAttr(w, state.sDrvPath); @@ -114,7 +114,7 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args } else { state.forceAttrs(*args[0]); if (args[0]->attrs->empty()) - state.evalFile(path, v); + state.evalFile(realPath, v); else { Env * env = &state.allocEnv(args[0]->attrs->size()); env->up = &state.baseEnv; @@ -127,8 +127,8 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args env->values[displ++] = attr.value; } - printTalkative("evaluating file '%1%'", path); - Expr * e = state.parseExprFromFile(resolveExprPath(path), staticEnv); + printTalkative("evaluating file '%1%'", realPath); + Expr * e = state.parseExprFromFile(resolveExprPath(realPath), staticEnv); e->eval(state, *env, v); } @@ -863,7 +863,7 @@ static void prim_readFile(EvalState & state, const Pos & pos, Value * * args, Va throw EvalError(format("cannot read '%1%', since path '%2%' is not valid, at %3%") % path % e.path % pos); } - string s = readFile(state.checkSourcePath(path)); + string s = readFile(state.checkSourcePath(state.toRealPath(path, context))); if (s.find((char) 0) != string::npos) throw Error(format("the contents of the file '%1%' cannot be represented as a Nix string") % path); mkString(v, s.c_str()); -- cgit v1.2.3