style(3p/nix): Final act in the brace-wrapping saga

This last change set was generated by a full clang-tidy run (including
compilation):

    clang-tidy -p ~/projects/nix-build/ \
      -checks=-*,readability-braces-around-statements -fix src/*/*.cc

Actually running clang-tidy requires some massaging to make it play
nice with Nix + meson, I'll be adding a wrapper or something for that soon.
This commit is contained in:
Vincent Ambo 2020-05-19 20:47:23 +01:00
parent cf40d08908
commit 3908732181
84 changed files with 2601 additions and 1554 deletions

View file

@ -33,6 +33,7 @@ let
cairo
cargo
cgit
clang-tools
clangStdenv
clang_9
cmake

View file

@ -20,6 +20,7 @@ in stdenv.mkDerivation {
nativeBuildInputs = with pkgs; [
bison
clang-tools
meson
ninja
pkgconfig

View file

@ -39,10 +39,11 @@ static AutoCloseFD openSlotLock(const Machine& m, unsigned long long slot) {
}
static bool allSupportedLocally(const std::set<std::string>& requiredFeatures) {
for (auto& feature : requiredFeatures)
for (auto& feature : requiredFeatures) {
if (!settings.systemFeatures.get().count(feature)) {
return false;
}
}
return true;
}
@ -172,10 +173,11 @@ static int _main(int argc, char** argv) {
}
if (!bestSlotLock) {
if (rightType && !canBuildLocally)
if (rightType && !canBuildLocally) {
std::cerr << "# postpone\n";
else
} else {
std::cerr << "# decline\n";
}
break;
}
@ -194,8 +196,9 @@ static int _main(int argc, char** argv) {
if (hasPrefix(bestMachine->storeUri, "ssh://")) {
storeParams["max-connections"] = "1";
storeParams["log-fd"] = "4";
if (bestMachine->sshKey != "")
if (bestMachine->sshKey != "") {
storeParams["ssh-key"] = bestMachine->sshKey;
}
}
sshStore = openStore(bestMachine->storeUri, storeParams);
@ -254,15 +257,17 @@ static int _main(int argc, char** argv) {
auto result = sshStore->buildDerivation(drvPath, drv);
if (!result.success())
if (!result.success()) {
throw Error("build of '%s' on '%s' failed: %s", drvPath, storeUri,
result.errorMsg);
}
PathSet missing;
for (auto& path : outputs)
for (auto& path : outputs) {
if (!store->isValidPath(path)) {
missing.insert(path);
}
}
if (!missing.empty()) {
DLOG(INFO) << "copying outputs from '" << storeUri << "'";

View file

@ -16,16 +16,18 @@ static Strings parseAttrPath(const string& s) {
} else if (*i == '"') {
++i;
while (1) {
if (i == s.end())
if (i == s.end()) {
throw Error(format("missing closing quote in selection path '%1%'") %
s);
}
if (*i == '"') {
break;
}
cur.push_back(*i++);
}
} else
} else {
cur.push_back(*i);
}
++i;
}
if (!cur.empty()) {
@ -62,33 +64,38 @@ Value* findAlongAttrPath(EvalState& state, const string& attrPath,
according to what is specified in the attrPath. */
if (apType == apAttr) {
if (v->type != tAttrs)
if (v->type != tAttrs) {
throw TypeError(format("the expression selected by the selection path "
"'%1%' should be a set but is %2%") %
attrPath % showType(*v));
}
if (attr.empty())
if (attr.empty()) {
throw Error(format("empty attribute name in selection path '%1%'") %
attrPath);
}
Bindings::iterator a = v->attrs->find(state.symbols.create(attr));
if (a == v->attrs->end())
if (a == v->attrs->end()) {
throw Error(
format("attribute '%1%' in selection path '%2%' not found") % attr %
attrPath);
}
v = &*a->value;
}
else if (apType == apIndex) {
if (!v->isList())
if (!v->isList()) {
throw TypeError(format("the expression selected by the selection path "
"'%1%' should be a list but is %2%") %
attrPath % showType(*v));
}
if (attrIndex >= v->listSize())
if (attrIndex >= v->listSize()) {
throw Error(
format("list index %1% in selection path '%2%' is out of range") %
attrIndex % attrPath);
}
v = v->listElems()[attrIndex];
}

View file

@ -10,8 +10,9 @@ namespace nix {
capacity. The space is implicitly reserved after the Bindings
structure. */
Bindings* EvalState::allocBindings(size_t capacity) {
if (capacity > std::numeric_limits<Bindings::size_t>::max())
if (capacity > std::numeric_limits<Bindings::size_t>::max()) {
throw Error("attribute set of size %d is too big", capacity);
}
return new (allocBytes(sizeof(Bindings) + sizeof(Attr) * capacity))
Bindings((Bindings::size_t)capacity);
}

View file

@ -36,11 +36,12 @@ Bindings* MixEvalArgs::getAutoArgs(EvalState& state) {
Bindings* res = state.allocBindings(autoArgs.size());
for (auto& i : autoArgs) {
Value* v = state.allocValue();
if (i.second[0] == 'E')
if (i.second[0] == 'E') {
state.mkThunk_(
*v, state.parseExprFromString(string(i.second, 1), absPath(".")));
else
} else {
mkString(*v, string(i.second, 1));
}
res->push_back(Attr(state.symbols.create(i.first), v));
}
res->sort();
@ -55,8 +56,9 @@ Path lookupFileArg(EvalState& state, string s) {
} else if (s.size() > 2 && s.at(0) == '<' && s.at(s.size() - 1) == '>') {
Path p = s.substr(1, s.size() - 2);
return state.findFile(p);
} else
} else {
return absPath(s);
}
}
} // namespace nix

View file

@ -62,17 +62,19 @@ static void printValue(std::ostream& str, std::set<const Value*>& active,
break;
case tString:
str << "\"";
for (const char* i = v.string.s; *i; i++)
if (*i == '\"' || *i == '\\')
for (const char* i = v.string.s; *i; i++) {
if (*i == '\"' || *i == '\\') {
str << "\\" << *i;
else if (*i == '\n')
} else if (*i == '\n') {
str << "\\n";
else if (*i == '\r')
} else if (*i == '\r') {
str << "\\r";
else if (*i == '\t')
} else if (*i == '\t') {
str << "\\t";
else
} else {
str << *i;
}
}
str << "\"";
break;
case tPath:
@ -281,7 +283,9 @@ static Strings parseNixPath(const string& s) {
if (*p == ':') {
if (isUri(std::string(start2, s.end()))) {
++p;
while (p != s.end() && *p != ':') ++p;
while (p != s.end() && *p != ':') {
++p;
}
}
res.push_back(std::string(start, p));
if (p == s.end()) {
@ -361,8 +365,9 @@ EvalState::EvalState(const Strings& _searchPath, ref<Store> store)
for (auto& path : closure) {
allowedPaths->insert(path);
}
} else
} else {
allowedPaths->insert(r.second);
}
}
}
@ -400,9 +405,10 @@ Path EvalState::checkSourcePath(const Path& path_) {
}
}
if (!found)
if (!found) {
throw RestrictedPathError(
"access to path '%1%' is forbidden in restricted mode", abspath);
}
/* Resolve symlinks. */
DLOG(INFO) << "checking access to '" << abspath << "'";
@ -428,12 +434,14 @@ void EvalState::checkURI(const std::string& uri) {
prefix. Thus, the prefix https://github.co does not permit
access to https://github.com. Note: this allows 'http://' and
'https://' as prefixes for any http/https URI. */
for (auto& prefix : evalSettings.allowedUris.get())
for (auto& prefix : evalSettings.allowedUris.get()) {
if (uri == prefix ||
(uri.size() > prefix.size() && prefix.size() > 0 &&
hasPrefix(uri, prefix) &&
(prefix[prefix.size() - 1] == '/' || uri[prefix.size()] == '/')))
(prefix[prefix.size() - 1] == '/' || uri[prefix.size()] == '/'))) {
return;
}
}
/* If the URI is a path, then check it against allowedPaths as
well. */
@ -600,9 +608,10 @@ inline Value* EvalState::lookupVar(Env* env, const ExprVar& var, bool noEval) {
}
return j->value;
}
if (!env->prevWith)
if (!env->prevWith) {
throwUndefinedVarError("undefined variable '%1%' at %2%", var.name,
var.pos);
}
for (size_t l = env->prevWith; l; --l, env = env->up) {
;
}
@ -622,8 +631,9 @@ Value* EvalState::allocValue() {
}
Env& EvalState::allocEnv(size_t size) {
if (size > std::numeric_limits<decltype(Env::size)>::max())
if (size > std::numeric_limits<decltype(Env::size)>::max()) {
throw Error("environment size %d is too big", size);
}
nrEnvs++;
nrValuesInEnvs += size;
@ -669,8 +679,9 @@ void EvalState::mkPos(Value& v, Pos* pos) {
mkInt(*allocAttr(v, sLine), pos->line);
mkInt(*allocAttr(v, sColumn), pos->column);
v.attrs->sort();
} else
} else {
mkNull(v);
}
}
/* Create a thunk for the delayed computation of the given expression
@ -823,8 +834,9 @@ void ExprAttrs::eval(EvalState& state, Env& env, Value& v) {
if (hasOverrides && !i.second.inherited) {
vAttr = state.allocValue();
mkThunk(*vAttr, env2, i.second.e);
} else
} else {
vAttr = i.second.e->maybeThunk(state, i.second.inherited ? env : env2);
}
env2.values[displ++] = vAttr;
v.attrs->push_back(Attr(i.first, vAttr, &i.second.pos));
}
@ -850,16 +862,18 @@ void ExprAttrs::eval(EvalState& state, Env& env, Value& v) {
if (j != attrs.end()) {
(*newBnds)[j->second.displ] = i;
env2.values[j->second.displ] = i.value;
} else
} else {
newBnds->push_back(i);
}
}
newBnds->sort();
v.attrs = newBnds;
}
} else {
for (auto& i : attrs)
for (auto& i : attrs) {
v.attrs->push_back(
Attr(i.first, i.second.e->maybeThunk(state, env), &i.second.pos));
}
}
/* Dynamic attrs apply *after* rec and __overrides. */
@ -873,9 +887,10 @@ void ExprAttrs::eval(EvalState& state, Env& env, Value& v) {
state.forceStringNoCtx(nameVal);
Symbol nameSym = state.symbols.create(nameVal.string.s);
Bindings::iterator j = v.attrs->find(nameSym);
if (j != v.attrs->end())
if (j != v.attrs->end()) {
throwEvalError("dynamic attribute '%1%' at %2% already defined at %3%",
nameSym, i.pos, *j->pos);
}
i.valueExpr->setName(nameSym);
/* Keep sorted order so find can catch duplicates */
@ -895,17 +910,19 @@ void ExprLet::eval(EvalState& state, Env& env, Value& v) {
while the inherited attributes are evaluated in the original
environment. */
size_t displ = 0;
for (auto& i : attrs->attrs)
for (auto& i : attrs->attrs) {
env2.values[displ++] =
i.second.e->maybeThunk(state, i.second.inherited ? env : env2);
}
body->eval(state, env2, v);
}
void ExprList::eval(EvalState& state, Env& env, Value& v) {
state.mkList(v, elems.size());
for (size_t n = 0; n < elems.size(); ++n)
for (size_t n = 0; n < elems.size(); ++n) {
v.listElems()[n] = elems[n]->maybeThunk(state, env);
}
}
void ExprVar::eval(EvalState& state, Env& env, Value& v) {
@ -919,10 +936,11 @@ static string showAttrPath(EvalState& state, Env& env,
std::ostringstream out;
bool first = true;
for (auto& i : attrPath) {
if (!first)
if (!first) {
out << '.';
else
} else {
first = false;
}
try {
out << getName(i, state, env);
} catch (Error& e) {
@ -956,8 +974,9 @@ void ExprSelect::eval(EvalState& state, Env& env, Value& v) {
}
} else {
state.forceAttrs(*vAttrs, pos);
if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) {
throwEvalError("attribute '%1%' missing, at %2%", name, pos);
}
}
vAttrs = j->value;
pos2 = j->pos;
@ -969,9 +988,10 @@ void ExprSelect::eval(EvalState& state, Env& env, Value& v) {
state.forceValue(*vAttrs, (pos2 != NULL ? *pos2 : this->pos));
} catch (Error& e) {
if (pos2 && pos2->file != state.sDerivationNix)
if (pos2 && pos2->file != state.sDerivationNix) {
addErrorPrefix(e, "while evaluating the attribute '%1%' at %2%:\n",
showAttrPath(state, env, attrPath), *pos2);
}
throw;
}
@ -1112,9 +1132,10 @@ void EvalState::callFunction(Value& fun, Value& arg, Value& v, const Pos& pos) {
for (auto& i : lambda.formals->formals) {
Bindings::iterator j = arg.attrs->find(i.name);
if (j == arg.attrs->end()) {
if (!i.def)
if (!i.def) {
throwTypeError("%1% called without required argument '%2%', at %3%",
lambda, i.name, pos);
}
env2.values[displ++] = i.def->maybeThunk(*this, env2);
} else {
attrsUsed++;
@ -1127,11 +1148,13 @@ void EvalState::callFunction(Value& fun, Value& arg, Value& v, const Pos& pos) {
if (!lambda.formals->ellipsis && attrsUsed != arg.attrs->size()) {
/* Nope, so show the first unexpected argument to the
user. */
for (auto& i : *arg.attrs)
for (auto& i : *arg.attrs) {
if (lambda.formals->argNames.find(i.name) ==
lambda.formals->argNames.end())
lambda.formals->argNames.end()) {
throwTypeError("%1% called with unexpected argument '%2%', at %3%",
lambda, i.name, pos);
}
}
abort(); // can't happen
}
}
@ -1143,15 +1166,17 @@ void EvalState::callFunction(Value& fun, Value& arg, Value& v, const Pos& pos) {
/* Evaluate the body. This is conditional on showTrace, because
catching exceptions makes this function not tail-recursive. */
if (settings.showTrace) try {
if (settings.showTrace) {
try {
lambda.body->eval(*this, env2, v);
} catch (Error& e) {
addErrorPrefix(e, "while evaluating %1%, called from %2%:\n", lambda,
pos);
throw;
}
else
} else {
fun.lambda.fun->body->eval(*this, env2, v);
}
}
// Lifted out of callFunction() because it creates a temporary that
@ -1181,13 +1206,14 @@ void EvalState::autoCallFunction(Bindings& args, Value& fun, Value& res) {
for (auto& i : fun.lambda.fun->formals->formals) {
Bindings::iterator j = args.find(i.name);
if (j != args.end())
if (j != args.end()) {
actualArgs->attrs->push_back(*j);
else if (!i.def)
} else if (!i.def) {
throwTypeError(
"cannot auto-call a function that has an argument without a default "
"value ('%1%')",
i.name);
}
}
actualArgs->attrs->sort();
@ -1278,10 +1304,11 @@ void ExprOpUpdate::eval(EvalState& state, Env& env, Value& v) {
v.attrs->push_back(*j);
++i;
++j;
} else if (i->name < j->name)
} else if (i->name < j->name) {
v.attrs->push_back(*i++);
else
} else {
v.attrs->push_back(*j++);
}
}
while (i != v1.attrs->end()) {
@ -1364,20 +1391,23 @@ void ExprConcatStrings::eval(EvalState& state, Env& env, Value& v) {
firstType = tFloat;
nf = n;
nf += vTmp.fpoint;
} else
} else {
throwEvalError("cannot add %1% to an integer, at %2%", showType(vTmp),
pos);
}
} else if (firstType == tFloat) {
if (vTmp.type == tInt) {
nf += vTmp.integer;
} else if (vTmp.type == tFloat) {
nf += vTmp.fpoint;
} else
} else {
throwEvalError("cannot add %1% to a float, at %2%", showType(vTmp),
pos);
} else
}
} else {
s << state.coerceToString(pos, vTmp, context, false,
firstType == tString);
}
}
if (firstType == tInt) {
@ -1385,11 +1415,12 @@ void ExprConcatStrings::eval(EvalState& state, Env& env, Value& v) {
} else if (firstType == tFloat) {
mkFloat(v, nf);
} else if (firstType == tPath) {
if (!context.empty())
if (!context.empty()) {
throwEvalError(
"a string that refers to a store path cannot be appended to a path, "
"at %1%",
pos);
}
auto path = canonPath(s.str());
mkPath(v, path.c_str());
} else {
@ -1415,13 +1446,15 @@ void EvalState::forceValueDeep(Value& v) {
forceValue(v);
if (v.type == tAttrs) {
for (auto& i : *v.attrs) try {
for (auto& i : *v.attrs) {
try {
recurse(*i.value);
} catch (Error& e) {
addErrorPrefix(e, "while evaluating the attribute '%1%' at %2%:\n",
i.name, *i.pos);
throw;
}
}
} else if (v.isList()) {
for (size_t n = 0; n < v.listSize(); ++n) {
recurse(*v.listElems()[n]);
@ -1486,10 +1519,11 @@ string EvalState::forceString(Value& v, const Pos& pos) {
}
void copyContext(const Value& v, PathSet& context) {
if (v.string.context)
if (v.string.context) {
for (const char** p = v.string.context; *p; ++p) {
context.insert(*p);
}
}
}
string EvalState::forceString(Value& v, PathSet& context, const Pos& pos) {
@ -1501,16 +1535,17 @@ string EvalState::forceString(Value& v, PathSet& context, const Pos& pos) {
string EvalState::forceStringNoCtx(Value& v, const Pos& pos) {
string s = forceString(v, pos);
if (v.string.context) {
if (pos)
if (pos) {
throwEvalError(
"the string '%1%' is not allowed to refer to a store path (such as "
"'%2%'), at %3%",
v.string.s, v.string.context[0], pos);
else
} else {
throwEvalError(
"the string '%1%' is not allowed to refer to a store path (such as "
"'%2%')",
v.string.s, v.string.context[0]);
}
}
return s;
}
@ -1567,13 +1602,15 @@ string EvalState::coerceToString(const Pos& pos, Value& v, PathSet& context,
return *maybeString;
}
auto i = v.attrs->find(sOutPath);
if (i == v.attrs->end())
if (i == v.attrs->end()) {
throwTypeError("cannot coerce a set to a string, at %1%", pos);
}
return coerceToString(pos, *i->value, context, coerceMore, copyToStore);
}
if (v.type == tExternal)
if (v.type == tExternal) {
return v.external->coerceToString(pos, context, coerceMore, copyToStore);
}
if (coerceMore) {
/* Note that `false' is represented as an empty string for
@ -1601,9 +1638,10 @@ string EvalState::coerceToString(const Pos& pos, Value& v, PathSet& context,
copyToStore);
if (n < v.listSize() - 1
/* !!! not quite correct */
&&
(!v.listElems()[n]->isList() || v.listElems()[n]->listSize() != 0))
&& (!v.listElems()[n]->isList() ||
v.listElems()[n]->listSize() != 0)) {
result += " ";
}
}
return result;
}
@ -1613,13 +1651,14 @@ string EvalState::coerceToString(const Pos& pos, Value& v, PathSet& context,
}
string EvalState::copyPathToStore(PathSet& context, const Path& path) {
if (nix::isDerivation(path))
if (nix::isDerivation(path)) {
throwEvalError("file names are not allowed to end in '%1%'", drvExtension);
}
Path dstPath;
if (srcToStore[path] != "")
if (srcToStore[path] != "") {
dstPath = srcToStore[path];
else {
} else {
dstPath =
settings.readOnlyMode
? store
@ -1638,9 +1677,10 @@ string EvalState::copyPathToStore(PathSet& context, const Path& path) {
Path EvalState::coerceToPath(const Pos& pos, Value& v, PathSet& context) {
string path = coerceToString(pos, v, context, false, false);
if (path == "" || path[0] != '/')
if (path == "" || path[0] != '/') {
throwEvalError("string '%1%' doesn't represent an absolute path, at %2%",
path, pos);
}
return path;
}
@ -1827,10 +1867,11 @@ void EvalState::printStats() {
auto list = topObj.list("functions");
for (auto& i : functionCalls) {
auto obj = list.object();
if (i.first->name.set())
if (i.first->name.set()) {
obj.attr("name", (const string&)i.first->name);
else
} else {
obj.attr("name", nullptr);
}
if (i.first->pos) {
obj.attr("file", (const string&)i.first->pos.file);
obj.attr("line", i.first->pos.line);
@ -1885,10 +1926,11 @@ size_t valueSize(Value& v) {
switch (v.type) {
case tString:
sz += doString(v.string.s);
if (v.string.context)
if (v.string.context) {
for (const char** p = v.string.context; *p; ++p) {
sz += doString(*p);
}
}
break;
case tPath:
sz += doString(v.path);
@ -1908,8 +1950,9 @@ size_t valueSize(Value& v) {
if (seen.find(v.listElems()) == seen.end()) {
seen.insert(v.listElems());
sz += v.listSize() * sizeof(Value*);
for (size_t n = 0; n < v.listSize(); ++n)
for (size_t n = 0; n < v.listSize(); ++n) {
sz += doValue(*v.listElems()[n]);
}
}
break;
case tThunk:
@ -1947,11 +1990,13 @@ size_t valueSize(Value& v) {
size_t sz = sizeof(Env) + sizeof(Value*) * env.size;
if (env.type != Env::HasWithExpr)
for (size_t i = 0; i < env.size; ++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);

View file

@ -25,18 +25,20 @@ DrvInfo::DrvInfo(EvalState& state, ref<Store> store,
name = storePathToName(drvPath);
if (spec.second.size() > 1)
if (spec.second.size() > 1) {
throw Error(
"building more than one derivation output is not supported, in '%s'",
drvPathWithOutputs);
}
outputName = spec.second.empty() ? get(drv.env, "outputName", "out")
: *spec.second.begin();
auto i = drv.outputs.find(outputName);
if (i == drv.outputs.end())
if (i == drv.outputs.end()) {
throw Error("derivation '%s' does not have output '%s'", drvPath,
outputName);
}
outPath = i->second.path;
}
@ -110,8 +112,9 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall) {
outputs[name] =
state->coerceToPath(*outPath->pos, *outPath->value, context);
}
} else
} else {
outputs["out"] = queryOutPath();
}
}
if (!onlyOutputsToInstall || !attrs) {
return outputs;
@ -363,10 +366,11 @@ static void getDerivations(EvalState& state, Value& vIn,
state.autoCallFunction(autoArgs, vIn, v);
/* Process the expression. */
if (!getDerivation(state, v, pathPrefix, drvs, done, ignoreAssertionFailures))
if (!getDerivation(state, v, pathPrefix, drvs, done,
ignoreAssertionFailures)) {
;
else if (v.type == tAttrs) {
} else if (v.type == tAttrs) {
/* !!! undocumented hackery to support combining channels in
nix-env.cc. */
bool combineChannels =
@ -384,11 +388,11 @@ static void getDerivations(EvalState& state, Value& vIn,
continue;
}
string pathPrefix2 = addToPath(pathPrefix, i->name);
if (combineChannels)
if (combineChannels) {
getDerivations(state, *i->value, pathPrefix2, autoArgs, drvs, done,
ignoreAssertionFailures);
else if (getDerivation(state, *i->value, pathPrefix2, drvs, done,
ignoreAssertionFailures)) {
} else if (getDerivation(state, *i->value, pathPrefix2, drvs, done,
ignoreAssertionFailures)) {
/* If the value of this attribute is itself a set,
should we recurse into it? => Only if it has a
`recurseForDerivations = true' attribute. */
@ -396,9 +400,10 @@ static void getDerivations(EvalState& state, Value& vIn,
Bindings::iterator j = i->value->attrs->find(
state.symbols.create("recurseForDerivations"));
if (j != i->value->attrs->end() &&
state.forceBool(*j->value, *j->pos))
state.forceBool(*j->value, *j->pos)) {
getDerivations(state, *i->value, pathPrefix2, autoArgs, drvs, done,
ignoreAssertionFailures);
}
}
}
}
@ -408,9 +413,10 @@ static void getDerivations(EvalState& state, Value& vIn,
for (unsigned int n = 0; n < v.listSize(); ++n) {
string pathPrefix2 = addToPath(pathPrefix, (format("%1%") % n).str());
if (getDerivation(state, *v.listElems()[n], pathPrefix2, drvs, done,
ignoreAssertionFailures))
ignoreAssertionFailures)) {
getDerivations(state, *v.listElems()[n], pathPrefix2, autoArgs, drvs,
done, ignoreAssertionFailures);
}
}
}

View file

@ -21,29 +21,30 @@ static string parseJSONString(const char*& s) {
}
if (*s == '\\') {
s++;
if (*s == '"')
if (*s == '"') {
res += '"';
else if (*s == '\\')
} else if (*s == '\\') {
res += '\\';
else if (*s == '/')
} else if (*s == '/') {
res += '/';
else if (*s == '/')
} else if (*s == '/') {
res += '/';
else if (*s == 'b')
} else if (*s == 'b') {
res += '\b';
else if (*s == 'f')
} else if (*s == 'f') {
res += '\f';
else if (*s == 'n')
} else if (*s == 'n') {
res += '\n';
else if (*s == 'r')
} else if (*s == 'r') {
res += '\r';
else if (*s == 't')
} else if (*s == 't') {
res += '\t';
else if (*s == 'u')
} else if (*s == 'u') {
throw JSONParseError(
"\\u characters in JSON strings are currently not supported");
else
} else {
throw JSONParseError("invalid escaped character in JSON string");
}
s++;
} else {
res += *s++;
@ -76,8 +77,9 @@ static void parseJSON(EvalState& state, const char*& s, Value& v) {
if (*s == ']') {
break;
}
if (*s != ',')
if (*s != ',') {
throw JSONParseError("expected ',' or ']' after JSON array element");
}
s++;
}
s++;
@ -108,8 +110,9 @@ static void parseJSON(EvalState& state, const char*& s, Value& v) {
if (*s == '}') {
break;
}
if (*s != ',')
if (*s != ',') {
throw JSONParseError("expected ',' or '}' after JSON member");
}
s++;
}
state.mkAttrs(v, attrs.size());
@ -137,10 +140,11 @@ static void parseJSON(EvalState& state, const char*& s, Value& v) {
}
try {
if (number_type == tFloat)
if (number_type == tFloat) {
mkFloat(v, stod(tmp_number));
else
} else {
mkInt(v, stol(tmp_number));
}
} catch (std::invalid_argument& e) {
throw JSONParseError("invalid JSON number");
} catch (std::out_of_range& e) {
@ -163,17 +167,19 @@ static void parseJSON(EvalState& state, const char*& s, Value& v) {
mkNull(v);
}
else
else {
throw JSONParseError("unrecognised JSON value");
}
}
void parseJSON(EvalState& state, const string& s_, Value& v) {
const char* s = s_.c_str();
parseJSON(state, s, v);
skipWhitespace(s);
if (*s)
if (*s) {
throw JSONParseError(
format("expected end-of-string while parsing JSON value: %1%") % s);
}
}
} // namespace nix

View file

@ -25,9 +25,10 @@ DrvName::DrvName(const string& s) : hits(0) {
bool DrvName::matches(DrvName& n) {
if (name != "*") {
if (!regex)
if (!regex) {
regex = std::unique_ptr<std::regex>(
new std::regex(name, std::regex::extended));
}
if (!std::regex_match(n.name, *regex)) {
return false;
}
@ -41,7 +42,9 @@ bool DrvName::matches(DrvName& n) {
string nextComponent(string::const_iterator& p,
const string::const_iterator end) {
/* Skip any dots and dashes (component separators). */
while (p != end && (*p == '.' || *p == '-')) ++p;
while (p != end && (*p == '.' || *p == '-')) {
++p;
}
if (p == end) {
return "";
@ -51,10 +54,15 @@ string nextComponent(string::const_iterator& p,
of digits. Otherwise, consume the longest sequence of
non-digit, non-separator characters. */
string s;
if (isdigit(*p))
while (p != end && isdigit(*p)) s += *p++;
else
while (p != end && (!isdigit(*p) && *p != '.' && *p != '-')) s += *p++;
if (isdigit(*p)) {
while (p != end && isdigit(*p)) {
s += *p++;
}
} else {
while (p != end && (!isdigit(*p) && *p != '.' && *p != '-')) {
s += *p++;
}
}
return s;
}
@ -65,14 +73,14 @@ static bool componentsLT(const string& c1, const string& c2) {
if (c1Num && c2Num) {
return n1 < n2;
} else if (c1 == "" && c2Num)
} else if (c1 == "" && c2Num) {
return true;
else if (c1 == "pre" && c2 != "pre")
} else if (c1 == "pre" && c2 != "pre") {
return true;
else if (c2 == "pre")
} else if (c2 == "pre") {
return false;
/* Assume that `2.3a' < `2.3.1'. */
else if (c2Num) {
/* Assume that `2.3a' < `2.3.1'. */
} else if (c2Num) {
return true;
} else if (c1Num) {
return false;
@ -88,10 +96,11 @@ int compareVersions(const string& v1, const string& v2) {
while (p1 != v1.end() || p2 != v2.end()) {
string c1 = nextComponent(p1, v1.end());
string c2 = nextComponent(p2, v2.end());
if (componentsLT(c1, c2))
if (componentsLT(c1, c2)) {
return -1;
else if (componentsLT(c2, c1))
} else if (componentsLT(c2, c1)) {
return 1;
}
}
return 0;

View file

@ -16,37 +16,40 @@ std::ostream& operator<<(std::ostream& str, const Expr& e) {
static void showString(std::ostream& str, const string& s) {
str << '"';
for (auto c : (string)s)
if (c == '"' || c == '\\' || c == '$')
for (auto c : (string)s) {
if (c == '"' || c == '\\' || c == '$') {
str << "\\" << c;
else if (c == '\n')
} else if (c == '\n') {
str << "\\n";
else if (c == '\r')
} else if (c == '\r') {
str << "\\r";
else if (c == '\t')
} else if (c == '\t') {
str << "\\t";
else
} else {
str << c;
}
}
str << '"';
}
static void showId(std::ostream& str, const string& s) {
if (s.empty())
if (s.empty()) {
str << "\"\"";
else if (s == "if") // FIXME: handle other keywords
} else if (s == "if") { // FIXME: handle other keywords
str << '"' << s << '"';
else {
} else {
char c = s[0];
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')) {
showString(str, s);
return;
}
for (auto c : s)
for (auto c : s) {
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') || c == '_' || c == '\'' || c == '-')) {
showString(str, s);
return;
}
}
str << s;
}
}
@ -84,14 +87,17 @@ void ExprAttrs::show(std::ostream& str) const {
str << "rec ";
}
str << "{ ";
for (auto& i : attrs)
if (i.second.inherited)
for (auto& i : attrs) {
if (i.second.inherited) {
str << "inherit " << i.first << " "
<< "; ";
else
} else {
str << i.first << " = " << *i.second.e << "; ";
for (auto& i : dynamicAttrs)
}
}
for (auto& i : dynamicAttrs) {
str << "\"${" << *i.nameExpr << "}\" = " << *i.valueExpr << "; ";
}
str << "}";
}
@ -109,10 +115,11 @@ void ExprLambda::show(std::ostream& str) const {
str << "{ ";
bool first = true;
for (auto& i : formals->formals) {
if (first)
if (first) {
first = false;
else
} else {
str << ", ";
}
str << i.name;
if (i.def) {
str << " ? " << *i.def;
@ -137,11 +144,13 @@ void ExprLambda::show(std::ostream& str) const {
void ExprLet::show(std::ostream& str) const {
str << "(let ";
for (auto& i : attrs->attrs)
for (auto& i : attrs->attrs) {
if (i.second.inherited) {
str << "inherit " << i.first << "; ";
} else
} else {
str << i.first << " = " << *i.second.e << "; ";
}
}
str << "in " << *body << ")";
}
@ -163,10 +172,11 @@ void ExprConcatStrings::show(std::ostream& str) const {
bool first = true;
str << "(";
for (auto& i : *es) {
if (first)
if (first) {
first = false;
else
} else {
str << " + ";
}
str << *i;
}
str << ")";
@ -175,12 +185,13 @@ void ExprConcatStrings::show(std::ostream& str) const {
void ExprPos::show(std::ostream& str) const { str << "__curPos"; }
std::ostream& operator<<(std::ostream& str, const Pos& pos) {
if (!pos)
if (!pos) {
str << "undefined position";
else
} else {
str << (format(ANSI_BOLD "%1%" ANSI_NORMAL ":%2%:%3%") % (string)pos.file %
pos.line % pos.column)
.str();
}
return str;
}
@ -188,14 +199,16 @@ string showAttrPath(const AttrPath& attrPath) {
std::ostringstream out;
bool first = true;
for (auto& i : attrPath) {
if (!first)
if (!first) {
out << '.';
else
} else {
first = false;
if (i.symbol.set())
}
if (i.symbol.set()) {
out << i.symbol;
else
} else {
out << "\"${" << *i.expr << "}\"";
}
}
return out.str();
}
@ -239,9 +252,10 @@ void ExprVar::bindVars(const StaticEnv& env) {
/* Otherwise, the variable must be obtained from the nearest
enclosing `with'. If there is no `with', then we can issue an
"undefined variable" error now. */
if (withLevel == -1)
if (withLevel == -1) {
throw UndefinedVarError(format("undefined variable '%1%' at %2%") % name %
pos);
}
fromWith = true;
this->level = withLevel;
@ -252,18 +266,20 @@ void ExprSelect::bindVars(const StaticEnv& env) {
if (def) {
def->bindVars(env);
}
for (auto& i : attrPath)
for (auto& i : attrPath) {
if (!i.symbol.set()) {
i.expr->bindVars(env);
}
}
}
void ExprOpHasAttr::bindVars(const StaticEnv& env) {
e->bindVars(env);
for (auto& i : attrPath)
for (auto& i : attrPath) {
if (!i.symbol.set()) {
i.expr->bindVars(env);
}
}
}
void ExprAttrs::bindVars(const StaticEnv& env) {
@ -315,10 +331,11 @@ void ExprLambda::bindVars(const StaticEnv& env) {
newEnv.vars[i.name] = displ++;
}
for (auto& i : formals->formals)
for (auto& i : formals->formals) {
if (i.def) {
i.def->bindVars(newEnv);
}
}
}
body->bindVars(newEnv);
@ -332,8 +349,9 @@ void ExprLet::bindVars(const StaticEnv& env) {
newEnv.vars[i.first] = i.second.displ = displ++;
}
for (auto& i : attrs->attrs)
for (auto& i : attrs->attrs) {
i.second.e->bindVars(i.second.inherited ? env : newEnv);
}
body->bindVars(newEnv);
}

View file

@ -37,8 +37,9 @@ std::pair<string, string> decodeContext(const string& s) {
size_t index = s.find("!", 1);
return std::pair<string, string>(string(s, index + 1),
string(s, 1, index - 1));
} else
} else {
return std::pair<string, string>(s.at(0) == '/' ? s : string(s, 1), "");
}
}
InvalidPathError::InvalidPathError(const Path& path)
@ -62,9 +63,10 @@ void EvalState::realiseContext(const PathSet& context) {
if (allowedPaths) {
auto drv = store->derivationFromPath(decoded.first);
DerivationOutputs::iterator i = drv.outputs.find(decoded.second);
if (i == drv.outputs.end())
if (i == drv.outputs.end()) {
throw Error("derivation '%s' does not have an output named '%s'",
decoded.first, decoded.second);
}
allowedPaths->insert(i->second.path);
}
}
@ -74,10 +76,11 @@ void EvalState::realiseContext(const PathSet& context) {
return;
}
if (!evalSettings.enableImportFromDerivation)
if (!evalSettings.enableImportFromDerivation) {
throw EvalError(format("attempted to realize '%1%' during evaluation but "
"'allow-import-from-derivation' is false") %
*(drvs.begin()));
}
/* For performance, prefetch all substitute info. */
PathSet willBuild, willSubstitute, unknown;
@ -178,20 +181,22 @@ void prim_importNative(EvalState& state, const Pos& pos, Value** args,
string sym = state.forceStringNoCtx(*args[1], pos);
void* handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
if (!handle)
if (!handle) {
throw EvalError(format("could not open '%1%': %2%") % path % dlerror());
}
dlerror();
ValueInitializer func = (ValueInitializer)dlsym(handle, sym.c_str());
if (!func) {
char* message = dlerror();
if (message)
if (message) {
throw EvalError(format("could not load symbol '%1%' from '%2%': %3%") %
sym % path % message);
else
} else {
throw EvalError(format("symbol '%1%' from '%2%' resolved to NULL when a "
"function pointer was expected") %
sym % path);
}
}
(func)(state, v);
@ -356,9 +361,10 @@ struct CompareValues {
if (v1->type == tInt && v2->type == tFloat) {
return v1->integer < v2->fpoint;
}
if (v1->type != v2->type)
if (v1->type != v2->type) {
throw EvalError(format("cannot compare %1% with %2%") % showType(*v1) %
showType(*v2));
}
switch (v1->type) {
case tInt:
return v1->integer < v2->integer;
@ -388,19 +394,22 @@ static void prim_genericClosure(EvalState& state, const Pos& pos, Value** args,
/* Get the start set. */
Bindings::iterator startSet =
args[0]->attrs->find(state.symbols.create("startSet"));
if (startSet == args[0]->attrs->end())
if (startSet == args[0]->attrs->end()) {
throw EvalError(format("attribute 'startSet' required, at %1%") % pos);
}
state.forceList(*startSet->value, pos);
ValueList workSet;
for (unsigned int n = 0; n < startSet->value->listSize(); ++n)
for (unsigned int n = 0; n < startSet->value->listSize(); ++n) {
workSet.push_back(startSet->value->listElems()[n]);
}
/* Get the operator. */
Bindings::iterator op =
args[0]->attrs->find(state.symbols.create("operator"));
if (op == args[0]->attrs->end())
if (op == args[0]->attrs->end()) {
throw EvalError(format("attribute 'operator' required, at %1%") % pos);
}
state.forceValue(*op->value);
/* Construct the closure by applying the operator to element of
@ -417,8 +426,9 @@ static void prim_genericClosure(EvalState& state, const Pos& pos, Value** args,
state.forceAttrs(*e, pos);
Bindings::iterator key = e->attrs->find(state.symbols.create("key"));
if (key == e->attrs->end())
if (key == e->attrs->end()) {
throw EvalError(format("attribute 'key' required, at %1%") % pos);
}
state.forceValue(*key->value);
if (doneKeys.find(key->value) != doneKeys.end()) {
@ -551,8 +561,9 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
/* Figure out the name first (for stack backtraces). */
Bindings::iterator attr = args[0]->attrs->find(state.sName);
if (attr == args[0]->attrs->end())
if (attr == args[0]->attrs->end()) {
throw EvalError(format("required attribute 'name' missing, at %1%") % pos);
}
string drvName;
Pos& posDrvName(*attr->pos);
try {
@ -568,8 +579,9 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
std::ostringstream jsonBuf;
std::unique_ptr<JSONObject> jsonObject;
attr = args[0]->attrs->find(state.sStructuredAttrs);
if (attr != args[0]->attrs->end() && state.forceBool(*attr->value, pos))
if (attr != args[0]->attrs->end() && state.forceBool(*attr->value, pos)) {
jsonObject = std::make_unique<JSONObject>(jsonBuf);
}
/* Check whether null attributes should be ignored. */
bool ignoreNulls = false;
@ -597,37 +609,41 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
const string& key = i->name;
auto handleHashMode = [&](const std::string& s) {
if (s == "recursive")
if (s == "recursive") {
outputHashRecursive = true;
else if (s == "flat")
} else if (s == "flat") {
outputHashRecursive = false;
else
} else {
throw EvalError(
"invalid value '%s' for 'outputHashMode' attribute, at %s", s,
posDrvName);
}
};
auto handleOutputs = [&](const Strings& ss) {
outputs.clear();
for (auto& j : ss) {
if (outputs.find(j) != outputs.end())
if (outputs.find(j) != outputs.end()) {
throw EvalError(format("duplicate derivation output '%1%', at %2%") %
j % posDrvName);
}
/* !!! Check whether j is a valid attribute
name. */
/* Derivations cannot be named drv, because
then we'd have an attribute drvPath in
the resulting set. */
if (j == "drv")
if (j == "drv") {
throw EvalError(
format("invalid derivation output name 'drv', at %1%") %
posDrvName);
}
outputs.insert(j);
}
if (outputs.empty())
if (outputs.empty()) {
throw EvalError(
format("derivation cannot have an empty set of outputs, at %1%") %
posDrvName);
}
};
try {
@ -660,41 +676,43 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
auto placeholder(jsonObject->placeholder(key));
printValueAsJSON(state, true, *i->value, placeholder, context);
if (i->name == state.sBuilder)
if (i->name == state.sBuilder) {
drv.builder = state.forceString(*i->value, context, posDrvName);
else if (i->name == state.sSystem)
} else if (i->name == state.sSystem) {
drv.platform = state.forceStringNoCtx(*i->value, posDrvName);
else if (i->name == state.sOutputHash)
} else if (i->name == state.sOutputHash) {
outputHash = state.forceStringNoCtx(*i->value, posDrvName);
else if (i->name == state.sOutputHashAlgo)
} else if (i->name == state.sOutputHashAlgo) {
outputHashAlgo = state.forceStringNoCtx(*i->value, posDrvName);
else if (i->name == state.sOutputHashMode)
} else if (i->name == state.sOutputHashMode) {
handleHashMode(state.forceStringNoCtx(*i->value, posDrvName));
else if (i->name == state.sOutputs) {
} else if (i->name == state.sOutputs) {
/* Require outputs to be a list of strings. */
state.forceList(*i->value, posDrvName);
Strings ss;
for (unsigned int n = 0; n < i->value->listSize(); ++n)
for (unsigned int n = 0; n < i->value->listSize(); ++n) {
ss.emplace_back(state.forceStringNoCtx(*i->value->listElems()[n],
posDrvName));
}
handleOutputs(ss);
}
} else {
auto s = state.coerceToString(posDrvName, *i->value, context, true);
drv.env.emplace(key, s);
if (i->name == state.sBuilder)
if (i->name == state.sBuilder) {
drv.builder = s;
else if (i->name == state.sSystem)
} else if (i->name == state.sSystem) {
drv.platform = s;
else if (i->name == state.sOutputHash)
} else if (i->name == state.sOutputHash) {
outputHash = s;
else if (i->name == state.sOutputHashAlgo)
} else if (i->name == state.sOutputHashAlgo) {
outputHashAlgo = s;
else if (i->name == state.sOutputHashMode)
} else if (i->name == state.sOutputHashMode) {
handleHashMode(s);
else if (i->name == state.sOutputs)
} else if (i->name == state.sOutputs) {
handleOutputs(tokenizeString<Strings>(s));
}
}
}
@ -728,8 +746,9 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
state.store->computeFSClosure(string(path, 1), refs);
for (auto& j : refs) {
drv.inputSrcs.insert(j);
if (isDerivation(j))
if (isDerivation(j)) {
drv.inputDrvs[j] = state.store->queryDerivationOutputNames(j);
}
}
}
@ -740,31 +759,36 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
}
/* Otherwise it's a source file. */
else
else {
drv.inputSrcs.insert(path);
}
}
/* Do we have all required attributes? */
if (drv.builder == "")
if (drv.builder == "") {
throw EvalError(format("required attribute 'builder' missing, at %1%") %
posDrvName);
if (drv.platform == "")
}
if (drv.platform == "") {
throw EvalError(format("required attribute 'system' missing, at %1%") %
posDrvName);
}
/* Check whether the derivation name is valid. */
checkStoreName(drvName);
if (isDerivation(drvName))
if (isDerivation(drvName)) {
throw EvalError(
format("derivation names are not allowed to end in '%1%', at %2%") %
drvExtension % posDrvName);
}
if (outputHash) {
/* Handle fixed-output derivations. */
if (outputs.size() != 1 || *(outputs.begin()) != "out")
if (outputs.size() != 1 || *(outputs.begin()) != "out") {
throw Error(format("multiple outputs are not supported in fixed-output "
"derivations, at %1%") %
posDrvName);
}
HashType ht =
outputHashAlgo.empty() ? htUnknown : parseHashType(outputHashAlgo);
@ -797,7 +821,7 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
path. */
Hash h = hashDerivationModulo(*state.store, drv);
for (auto& i : drv.outputs)
for (auto& i : drv.outputs) {
if (i.second.path == "") {
Path outPath = state.store->makeOutputPath(i.first, h, drvName);
if (!jsonObject) {
@ -805,6 +829,7 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
}
i.second.path = outPath;
}
}
}
/* Write the resulting term into the Nix store directory. */
@ -868,9 +893,10 @@ static void prim_storePath(EvalState& state, const Pos& pos, Value** args,
if (!state.store->isStorePath(path)) {
path = canonPath(path, true);
}
if (!state.store->isInStore(path))
if (!state.store->isInStore(path)) {
throw EvalError(format("path '%1%' is not in the Nix store, at %2%") %
path % pos);
}
Path path2 = state.store->toStorePath(path);
if (!settings.readOnlyMode) {
state.store->ensurePath(path2);
@ -939,10 +965,11 @@ static void prim_readFile(EvalState& state, const Pos& pos, Value** args,
path % e.path % pos);
}
string s = readFile(state.checkSourcePath(state.toRealPath(path, context)));
if (s.find((char)0) != string::npos)
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());
}
@ -965,8 +992,9 @@ static void prim_findFile(EvalState& state, const Pos& pos, Value** args,
}
i = v2.attrs->find(state.symbols.create("path"));
if (i == v2.attrs->end())
if (i == v2.attrs->end()) {
throw EvalError(format("attribute 'path' missing, at %1%") % pos);
}
PathSet context;
string path = state.coerceToString(pos, *i->value, context, false, false);
@ -993,8 +1021,9 @@ static void prim_hashFile(EvalState& state, const Pos& pos, Value** args,
Value& v) {
string type = state.forceStringNoCtx(*args[0], pos);
HashType ht = parseHashType(type);
if (ht == htUnknown)
if (ht == htUnknown) {
throw Error(format("unknown hash type '%1%', at %2%") % type % pos);
}
PathSet context; // discarded
Path p = state.coerceToPath(pos, *args[1], context);
@ -1079,10 +1108,11 @@ static void prim_toFile(EvalState& state, const Pos& pos, Value** args,
PathSet refs;
for (auto path : context) {
if (path.at(0) != '/')
if (path.at(0) != '/') {
throw EvalError(format("in 'toFile': the file '%1%' cannot refer to "
"derivation outputs, at %2%") %
name % pos);
}
refs.insert(path);
}
@ -1150,8 +1180,9 @@ static void addPath(EvalState& state, const Pos& pos, const string& name,
"added from '%1%'") %
path);
}
} else
} else {
dstPath = expectedStorePath;
}
mkString(v, dstPath, {dstPath});
}
@ -1160,15 +1191,17 @@ static void prim_filterSource(EvalState& state, const Pos& pos, Value** args,
Value& v) {
PathSet context;
Path path = state.coerceToPath(pos, *args[1], context);
if (!context.empty())
if (!context.empty()) {
throw EvalError(format("string '%1%' cannot refer to other paths, at %2%") %
path % pos);
}
state.forceValue(*args[0]);
if (args[0]->type != tLambda)
if (args[0]->type != tLambda) {
throw TypeError(format("first argument in call to 'filterSource' is not a "
"function but %1%, at %2%") %
showType(*args[0]) % pos);
}
addPath(state, pos, baseNameOf(path), path, args[0], true, Hash(), v);
}
@ -1187,24 +1220,26 @@ static void prim_path(EvalState& state, const Pos& pos, Value** args,
if (n == "path") {
PathSet context;
path = state.coerceToPath(*attr.pos, *attr.value, context);
if (!context.empty())
if (!context.empty()) {
throw EvalError(
format("string '%1%' cannot refer to other paths, at %2%") % path %
*attr.pos);
} else if (attr.name == state.sName)
}
} else if (attr.name == state.sName) {
name = state.forceStringNoCtx(*attr.value, *attr.pos);
else if (n == "filter") {
} else if (n == "filter") {
state.forceValue(*attr.value);
filterFun = attr.value;
} else if (n == "recursive")
} else if (n == "recursive") {
recursive = state.forceBool(*attr.value, *attr.pos);
else if (n == "sha256")
} else if (n == "sha256") {
expectedHash =
Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256);
else
} else {
throw EvalError(
format("unsupported argument '%1%' to 'addPath', at %2%") %
attr.name % *attr.pos);
}
}
if (path.empty()) {
throw EvalError(format("'path' required, at %1%") % pos);
@ -1229,8 +1264,9 @@ static void prim_attrNames(EvalState& state, const Pos& pos, Value** args,
state.mkList(v, args[0]->attrs->size());
size_t n = 0;
for (auto& i : *args[0]->attrs)
for (auto& i : *args[0]->attrs) {
mkString(*(v.listElems()[n++] = state.allocValue()), i.name);
}
std::sort(v.listElems(), v.listElems() + n, [](Value* v1, Value* v2) {
return strcmp(v1->string.s, v2->string.s) < 0;
@ -1265,8 +1301,9 @@ void prim_getAttr(EvalState& state, const Pos& pos, Value** args, Value& v) {
state.forceAttrs(*args[1], pos);
// !!! Should we create a symbol here or just do a lookup?
Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
if (i == args[1]->attrs->end())
if (i == args[1]->attrs->end()) {
throw EvalError(format("attribute '%1%' missing, at %2%") % attr % pos);
}
// !!! add to stack trace?
if (state.countCalls && i->pos) {
state.attrSelects[*i->pos]++;
@ -1345,21 +1382,23 @@ static void prim_listToAttrs(EvalState& state, const Pos& pos, Value** args,
state.forceAttrs(v2, pos);
Bindings::iterator j = v2.attrs->find(state.sName);
if (j == v2.attrs->end())
if (j == v2.attrs->end()) {
throw TypeError(
format(
"'name' attribute missing in a call to 'listToAttrs', at %1%") %
pos);
}
string name = state.forceStringNoCtx(*j->value, pos);
Symbol sym = state.symbols.create(name);
if (seen.find(sym) == seen.end()) {
Bindings::iterator j2 =
v2.attrs->find(state.symbols.create(state.sValue));
if (j2 == v2.attrs->end())
if (j2 == v2.attrs->end()) {
throw TypeError(format("'value' attribute missing in a call to "
"'listToAttrs', at %1%") %
pos);
}
v.attrs->push_back(Attr(sym, j2->value, j2->pos));
seen.insert(sym);
@ -1434,8 +1473,9 @@ static void prim_catAttrs(EvalState& state, const Pos& pos, Value** args,
static void prim_functionArgs(EvalState& state, const Pos& pos, Value** args,
Value& v) {
state.forceValue(*args[0]);
if (args[0]->type != tLambda)
if (args[0]->type != tLambda) {
throw TypeError(format("'functionArgs' requires a function, at %1%") % pos);
}
if (!args[0]->lambda.fun->matchAttrs) {
state.mkAttrs(v, 0);
@ -1443,9 +1483,10 @@ static void prim_functionArgs(EvalState& state, const Pos& pos, Value** args,
}
state.mkAttrs(v, args[0]->lambda.fun->formals->formals.size());
for (auto& i : args[0]->lambda.fun->formals->formals)
for (auto& i : args[0]->lambda.fun->formals->formals) {
// !!! should optimise booleans (allocate only once)
mkBool(*state.allocAttr(v, i.name), i.def);
}
v.attrs->sort();
}
@ -1479,8 +1520,9 @@ static void prim_isList(EvalState& state, const Pos& pos, Value** args,
static void elemAt(EvalState& state, const Pos& pos, Value& list, int n,
Value& v) {
state.forceList(list, pos);
if (n < 0 || (unsigned int)n >= list.listSize())
if (n < 0 || (unsigned int)n >= list.listSize()) {
throw Error(format("list index %1% is out of bounds, at %2%") % n % pos);
}
state.forceValue(*list.listElems()[n]);
v = *list.listElems()[n];
}
@ -1503,8 +1545,9 @@ static void prim_head(EvalState& state, const Pos& pos, Value** args,
static void prim_tail(EvalState& state, const Pos& pos, Value** args,
Value& v) {
state.forceList(*args[0], pos);
if (args[0]->listSize() == 0)
if (args[0]->listSize() == 0) {
throw Error(format("'tail' called on an empty list, at %1%") % pos);
}
state.mkList(v, args[0]->listSize() - 1);
for (unsigned int n = 0; n < v.listSize(); ++n) {
v.listElems()[n] = args[0]->listElems()[n + 1];
@ -1637,9 +1680,10 @@ static void prim_genList(EvalState& state, const Pos& pos, Value** args,
Value& v) {
auto len = state.forceInt(*args[1], pos);
if (len < 0)
if (len < 0) {
throw EvalError(format("cannot create list of size %1%, at %2%") % len %
pos);
}
state.mkList(v, len);
@ -1698,10 +1742,11 @@ static void prim_partition(EvalState& state, const Pos& pos, Value** args,
state.forceValue(*vElem);
Value res;
state.callFunction(*args[0], *vElem, res, pos);
if (state.forceBool(res, pos))
if (state.forceBool(res, pos)) {
right.push_back(vElem);
else
} else {
wrong.push_back(vElem);
}
}
state.mkAttrs(v, 2);
@ -1805,8 +1850,9 @@ static void prim_div(EvalState& state, const Pos& pos, Value** args, Value& v) {
NixInt i1 = state.forceInt(*args[0], pos);
NixInt i2 = state.forceInt(*args[1], pos);
/* Avoid division overflow as it might raise SIGFPE. */
if (i1 == std::numeric_limits<NixInt>::min() && i2 == -1)
if (i1 == std::numeric_limits<NixInt>::min() && i2 == -1) {
throw EvalError(format("overflow in integer division, at %1%") % pos);
}
mkInt(v, i1 / i2);
}
}
@ -1859,9 +1905,10 @@ static void prim_substring(EvalState& state, const Pos& pos, Value** args,
PathSet context;
string s = state.coerceToString(pos, *args[2], context);
if (start < 0)
if (start < 0) {
throw EvalError(format("negative start position in 'substring', at %1%") %
pos);
}
mkString(v, (unsigned int)start >= s.size() ? "" : string(s, start, len),
context);
@ -1879,8 +1926,9 @@ static void prim_hashString(EvalState& state, const Pos& pos, Value** args,
Value& v) {
string type = state.forceStringNoCtx(*args[0], pos);
HashType ht = parseHashType(type);
if (ht == htUnknown)
if (ht == htUnknown) {
throw Error(format("unknown hash type '%1%', at %2%") % type % pos);
}
PathSet context; // discarded
string s = state.forceString(*args[1], context, pos);
@ -1910,11 +1958,12 @@ static void prim_match(EvalState& state, const Pos& pos, Value** args,
const size_t len = match.size() - 1;
state.mkList(v, len);
for (size_t i = 0; i < len; ++i) {
if (!match[i + 1].matched)
if (!match[i + 1].matched) {
mkNull(*(v.listElems()[i] = state.allocValue()));
else
} else {
mkString(*(v.listElems()[i] = state.allocValue()),
match[i + 1].str().c_str());
}
}
} catch (std::regex_error& e) {
@ -1969,11 +2018,12 @@ static void prim_split(EvalState& state, const Pos& pos, Value** args,
// Start at 1, beacause the first match is the whole string.
state.mkList(*elem, slen);
for (size_t si = 0; si < slen; ++si) {
if (!match[si + 1].matched)
if (!match[si + 1].matched) {
mkNull(*(elem->listElems()[si] = state.allocValue()));
else
} else {
mkString(*(elem->listElems()[si] = state.allocValue()),
match[si + 1].str().c_str());
}
}
// Add a string for non-matched suffix characters.
@ -2023,15 +2073,17 @@ static void prim_replaceStrings(EvalState& state, const Pos& pos, Value** args,
Value& v) {
state.forceList(*args[0], pos);
state.forceList(*args[1], pos);
if (args[0]->listSize() != args[1]->listSize())
if (args[0]->listSize() != args[1]->listSize()) {
throw EvalError(format("'from' and 'to' arguments to 'replaceStrings' have "
"different lengths, at %1%") %
pos);
}
vector<string> from;
from.reserve(args[0]->listSize());
for (unsigned int n = 0; n < args[0]->listSize(); ++n)
for (unsigned int n = 0; n < args[0]->listSize(); ++n) {
from.push_back(state.forceString(*args[0]->listElems()[n], pos));
}
vector<std::pair<string, PathSet>> to;
to.reserve(args[1]->listSize());
@ -2051,7 +2103,7 @@ static void prim_replaceStrings(EvalState& state, const Pos& pos, Value** args,
bool found = false;
auto i = from.begin();
auto j = to.begin();
for (; i != from.end(); ++i, ++j)
for (; i != from.end(); ++i, ++j) {
if (s.compare(p, i->size(), *i) == 0) {
found = true;
res += j->first;
@ -2069,6 +2121,7 @@ static void prim_replaceStrings(EvalState& state, const Pos& pos, Value** args,
j->second.clear();
break;
}
}
if (!found) {
if (p < s.size()) {
res += s[p];
@ -2139,20 +2192,22 @@ void fetch(EvalState& state, const Pos& pos, Value** args, Value& v,
for (auto& attr : *args[0]->attrs) {
string n(attr.name);
if (n == "url")
if (n == "url") {
request.uri = state.forceStringNoCtx(*attr.value, *attr.pos);
else if (n == "sha256")
} else if (n == "sha256") {
request.expectedHash =
Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256);
else if (n == "name")
} else if (n == "name") {
request.name = state.forceStringNoCtx(*attr.value, *attr.pos);
else
} else {
throw EvalError(format("unsupported argument '%1%' to '%2%', at %3%") %
attr.name % who % attr.pos);
}
}
if (request.uri.empty())
if (request.uri.empty()) {
throw EvalError(format("'url' argument required, at %1%") % pos);
}
} else {
request.uri = state.forceStringNoCtx(*args[0], pos);
@ -2160,9 +2215,10 @@ void fetch(EvalState& state, const Pos& pos, Value** args, Value& v,
state.checkURI(request.uri);
if (evalSettings.pureEval && !request.expectedHash)
if (evalSettings.pureEval && !request.expectedHash) {
throw Error("in pure evaluation mode, '%s' requires a 'sha256' argument",
who);
}
auto res = getDownloader()->downloadCached(state.store, request);
@ -2282,10 +2338,11 @@ void EvalState::createBaseEnv() {
// Paths
addPrimOp("__toPath", 1, prim_toPath);
if (evalSettings.pureEval)
if (evalSettings.pureEval) {
addPurityError("__storePath");
else
} else {
addPrimOp("__storePath", 1, prim_storePath);
}
addPrimOp("__pathExists", 1, prim_pathExists);
addPrimOp("baseNameOf", 1, prim_baseNameOf);
addPrimOp("dirOf", 1, prim_dirOf);
@ -2387,9 +2444,11 @@ void EvalState::createBaseEnv() {
}
addConstant("__nixPath", v);
if (RegisterPrimOp::primOps)
for (auto& primOp : *RegisterPrimOp::primOps)
if (RegisterPrimOp::primOps) {
for (auto& primOp : *RegisterPrimOp::primOps) {
addPrimOp(std::get<0>(primOp), std::get<1>(primOp), std::get<2>(primOp));
}
}
/* Now that we've added all primops, sort the `builtins' set,
because attribute lookups expect it to be sorted. */

View file

@ -58,8 +58,9 @@ void printValueAsJSON(EvalState& state, bool strict, Value& v,
auto placeholder(obj.placeholder(j));
printValueAsJSON(state, strict, *a.value, placeholder, context);
}
} else
} else {
printValueAsJSON(state, strict, *i->value, out, context);
}
break;
}

View file

@ -94,8 +94,9 @@ static void printValueAsXML(EvalState& state, bool strict, bool location,
if (strict) {
state.forceValue(*a->value);
}
if (a->value->type == tString)
if (a->value->type == tString) {
xmlAttrs["drvPath"] = drvPath = a->value->string.s;
}
}
a = v.attrs->find(state.sOutPath);
@ -103,8 +104,9 @@ static void printValueAsXML(EvalState& state, bool strict, bool location,
if (strict) {
state.forceValue(*a->value);
}
if (a->value->type == tString)
if (a->value->type == tString) {
xmlAttrs["outPath"] = a->value->string.s;
}
}
XMLOpenElement _(doc, "derivation", xmlAttrs);
@ -112,8 +114,9 @@ static void printValueAsXML(EvalState& state, bool strict, bool location,
if (drvPath != "" && drvsSeen.find(drvPath) == drvsSeen.end()) {
drvsSeen.insert(drvPath);
showAttrs(state, strict, location, *v.attrs, doc, context, drvsSeen);
} else
} else {
doc.writeEmptyElement("repeated");
}
}
else {

View file

@ -233,7 +233,9 @@ bool LegacyArgs::processFlag(Strings::iterator& pos, Strings::iterator end) {
return true;
}
bool res = parseArg(pos, end);
if (res) ++pos;
if (res) {
++pos;
}
return res;
}
@ -244,8 +246,9 @@ bool LegacyArgs::processArgs(const Strings& args, bool finish) {
assert(args.size() == 1);
Strings ss(args);
auto pos = ss.begin();
if (!parseArg(pos, ss.end()))
if (!parseArg(pos, ss.end())) {
throw UsageError(format("unexpected argument '%1%'") % args.front());
}
return true;
}
@ -346,8 +349,9 @@ RunPager::RunPager() {
toPager.create();
pid = startProcess([&]() {
if (dup2(toPager.readSide.get(), STDIN_FILENO) == -1)
if (dup2(toPager.readSide.get(), STDIN_FILENO) == -1) {
throw SysError("dupping stdin");
}
if (!getenv("LESS")) {
setenv("LESS", "FRSXMK", 1);
}
@ -363,8 +367,9 @@ RunPager::RunPager() {
pid.setKillSignal(SIGINT);
if (dup2(toPager.writeSide.get(), STDOUT_FILENO) == -1)
if (dup2(toPager.writeSide.get(), STDOUT_FILENO) == -1) {
throw SysError("dupping stdout");
}
}
RunPager::~RunPager() {

View file

@ -58,8 +58,9 @@ void detectStackOverflow() {
throw Error("cannot allocate alternative stack");
}
stack.ss_flags = 0;
if (sigaltstack(&stack, 0) == -1)
if (sigaltstack(&stack, 0) == -1) {
throw SysError("cannot set alternative stack");
}
struct sigaction act;
sigfillset(&act.sa_mask);

View file

@ -19,9 +19,10 @@
namespace nix {
BinaryCacheStore::BinaryCacheStore(const Params& params) : Store(params) {
if (secretKeyFile != "")
if (secretKeyFile != "") {
secretKey =
std::unique_ptr<SecretKey>(new SecretKey(readFile(secretKeyFile)));
}
StringSink sink;
sink << narVersionMagic1;
@ -44,10 +45,11 @@ void BinaryCacheStore::init() {
auto name = line.substr(0, colon);
auto value = trim(line.substr(colon + 1, std::string::npos));
if (name == "StoreDir") {
if (value != storeDir)
if (value != storeDir) {
throw Error(format("binary cache '%s' is for Nix stores with prefix "
"'%s', not '%s'") %
getUri() % value % storeDir);
}
} else if (name == "WantMassQuery") {
wantMassQuery_ = value == "1";
} else if (name == "Priority") {
@ -108,9 +110,10 @@ void BinaryCacheStore::writeNarInfo(ref<NarInfo> narInfo) {
state_->pathInfoCache.upsert(hashPart, std::shared_ptr<NarInfo>(narInfo));
}
if (diskCache)
if (diskCache) {
diskCache->upsertNarInfo(getUri(), hashPart,
std::shared_ptr<NarInfo>(narInfo));
}
}
void BinaryCacheStore::addToStore(const ValidPathInfo& info,
@ -123,7 +126,8 @@ void BinaryCacheStore::addToStore(const ValidPathInfo& info,
/* Verify that all references are valid. This may do some .narinfo
reads, but typically they'll already be cached. */
for (auto& ref : info.references) try {
for (auto& ref : info.references) {
try {
if (ref != info.path) {
queryPathInfo(ref);
}
@ -132,6 +136,7 @@ void BinaryCacheStore::addToStore(const ValidPathInfo& info,
"reference '%s' is not valid") %
info.path % ref);
}
}
assert(nar->compare(0, narMagic.size(), narMagic) == 0);
@ -140,10 +145,11 @@ void BinaryCacheStore::addToStore(const ValidPathInfo& info,
narInfo->narSize = nar->size();
narInfo->narHash = hashString(htSHA256, *nar);
if (info.narHash && info.narHash != narInfo->narHash)
if (info.narHash && info.narHash != narInfo->narHash) {
throw Error(
format("refusing to copy corrupted path '%1%' to binary cache") %
info.path);
}
auto accessor_ = std::dynamic_pointer_cast<RemoteFSAccessor>(accessor);
@ -203,8 +209,9 @@ void BinaryCacheStore::addToStore(const ValidPathInfo& info,
if (repair || !fileExists(narInfo->url)) {
stats.narWrite++;
upsertFile(narInfo->url, *narCompressed, "application/x-nix-nar");
} else
} else {
stats.narWriteAverted++;
}
stats.narWriteBytes += nar->size();
stats.narWriteCompressedBytes += narCompressed->size();
@ -349,9 +356,9 @@ void BinaryCacheStore::addSignatures(const Path& storePath,
std::shared_ptr<std::string> BinaryCacheStore::getBuildLog(const Path& path) {
Path drvPath;
if (isDerivation(path))
if (isDerivation(path)) {
drvPath = path;
else {
} else {
try {
auto info = queryPathInfo(path);
// FIXME: add a "Log" field to .narinfo

File diff suppressed because it is too large Load diff

View file

@ -32,8 +32,9 @@ Key::Key(const string& s) {
SecretKey::SecretKey(const string& s) : Key(s) {
#if HAVE_SODIUM
if (key.size() != crypto_sign_SECRETKEYBYTES)
if (key.size() != crypto_sign_SECRETKEYBYTES) {
throw Error("secret key is not valid");
}
#endif
}
@ -69,8 +70,9 @@ PublicKey SecretKey::toPublicKey() const {
PublicKey::PublicKey(const string& s) : Key(s) {
#if HAVE_SODIUM
if (key.size() != crypto_sign_PUBLICKEYBYTES)
if (key.size() != crypto_sign_PUBLICKEYBYTES) {
throw Error("public key is not valid");
}
#endif
}

View file

@ -19,16 +19,18 @@ void DerivationOutput::parseHashInfo(bool& recursive, Hash& hash) const {
}
HashType hashType = parseHashType(algo);
if (hashType == htUnknown)
if (hashType == htUnknown) {
throw Error(format("unknown hash algorithm '%1%'") % algo);
}
hash = Hash(this->hash, hashType);
}
Path BasicDerivation::findOutput(const string& id) const {
auto i = outputs.find(id);
if (i == outputs.end())
if (i == outputs.end()) {
throw Error(format("derivation has no output '%1%'") % id);
}
return i->second.path;
}
@ -57,8 +59,9 @@ Path writeDerivation(ref<Store> store, const Derivation& drv,
static void expect(std::istream& str, const string& s) {
char s2[s.size()];
str.read(s2, s.size());
if (string(s2, s.size()) != s)
if (string(s2, s.size()) != s) {
throw FormatError(format("expected string '%1%'") % s);
}
}
/* Read a C-style string from stream `str'. */
@ -66,26 +69,30 @@ static string parseString(std::istream& str) {
string res;
expect(str, "\"");
int c;
while ((c = str.get()) != '"')
while ((c = str.get()) != '"') {
if (c == '\\') {
c = str.get();
if (c == 'n')
if (c == 'n') {
res += '\n';
else if (c == 'r')
} else if (c == 'r') {
res += '\r';
else if (c == 't')
} else if (c == 't') {
res += '\t';
else
} else {
res += c;
} else
}
} else {
res += c;
}
}
return res;
}
static Path parsePath(std::istream& str) {
string s = parseString(str);
if (s.size() == 0 || s[0] != '/')
if (s.size() == 0 || s[0] != '/') {
throw FormatError(format("bad path '%1%' in derivation") % s);
}
return s;
}
@ -103,8 +110,9 @@ static bool endOfList(std::istream& str) {
static StringSet parseStrings(std::istream& str, bool arePaths) {
StringSet res;
while (!endOfList(str))
while (!endOfList(str)) {
res.insert(arePaths ? parsePath(str) : parseString(str));
}
return res;
}
@ -147,7 +155,9 @@ static Derivation parseDerivation(const string& s) {
/* Parse the builder arguments. */
expect(str, ",[");
while (!endOfList(str)) drv.args.push_back(parseString(str));
while (!endOfList(str)) {
drv.args.push_back(parseString(str));
}
/* Parse the environment variables. */
expect(str, ",[");

View file

@ -36,11 +36,12 @@ DownloadSettings downloadSettings;
static GlobalConfig::Register r1(&downloadSettings);
std::string resolveUri(const std::string& uri) {
if (uri.compare(0, 8, "channel:") == 0)
if (uri.compare(0, 8, "channel:") == 0) {
return "https://nixos.org/channels/" + std::string(uri, 8) +
"/nixexprs.tar.xz";
else
} else {
return uri;
}
}
struct CurlDownloader : public Downloader {
@ -92,18 +93,21 @@ struct CurlDownloader : public Downloader {
writtenToSink += len;
this->request.dataCallback((char*)data, len);
}
} else
} else {
this->result.data->append((char*)data, len);
}
}) {
LOG(INFO) << (request.data ? "uploading '" : "downloading '")
<< request.uri << "'";
if (!request.expectedETag.empty())
if (!request.expectedETag.empty()) {
requestHeaders = curl_slist_append(
requestHeaders, ("If-None-Match: " + request.expectedETag).c_str());
if (!request.mimeType.empty())
}
if (!request.mimeType.empty()) {
requestHeaders = curl_slist_append(
requestHeaders, ("Content-Type: " + request.mimeType).c_str());
}
}
~DownloadItem() {
@ -117,10 +121,11 @@ struct CurlDownloader : public Downloader {
curl_slist_free_all(requestHeaders);
}
try {
if (!done)
if (!done) {
fail(DownloadError(
Interrupted,
format("download of '%s' was interrupted") % request.uri));
}
} catch (...) {
ignoreException();
}
@ -147,8 +152,9 @@ struct CurlDownloader : public Downloader {
size_t realSize = size * nmemb;
result.bodySize += realSize;
if (!decompressionSink)
if (!decompressionSink) {
decompressionSink = makeDecompressionSink(encoding, finalSink);
}
(*decompressionSink)((unsigned char*)contents, realSize);
@ -192,11 +198,12 @@ struct CurlDownloader : public Downloader {
<< "shutting down on 200 HTTP response with expected ETag";
return 0;
}
} else if (name == "content-encoding")
} else if (name == "content-encoding") {
encoding = trim(string(line, i + 1));
else if (name == "accept-ranges" &&
toLower(trim(std::string(line, i + 1))) == "bytes")
} else if (name == "accept-ranges" &&
toLower(trim(std::string(line, i + 1))) == "bytes") {
acceptRanges = true;
}
}
}
return realSize;
@ -275,10 +282,11 @@ struct CurlDownloader : public Downloader {
curl_easy_setopt(req, CURLOPT_PIPEWAIT, 1);
#endif
#if LIBCURL_VERSION_NUM >= 0x072f00
if (downloadSettings.enableHttp2)
if (downloadSettings.enableHttp2) {
curl_easy_setopt(req, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
else
} else {
curl_easy_setopt(req, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
}
#endif
curl_easy_setopt(req, CURLOPT_WRITEFUNCTION,
DownloadItem::writeCallbackWrapper);
@ -306,8 +314,9 @@ struct CurlDownloader : public Downloader {
}
if (request.verifyTLS) {
if (settings.caFile != "")
if (settings.caFile != "") {
curl_easy_setopt(req, CURLOPT_CAINFO, settings.caFile.c_str());
}
} else {
curl_easy_setopt(req, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(req, CURLOPT_SSL_VERIFYHOST, 0);
@ -362,14 +371,14 @@ struct CurlDownloader : public Downloader {
httpStatus = 304;
}
if (writeException)
if (writeException) {
failEx(writeException);
else if (code == CURLE_OK &&
(httpStatus == 200 || httpStatus == 201 || httpStatus == 204 ||
httpStatus == 206 || httpStatus == 304 ||
httpStatus == 226 /* FTP */ ||
httpStatus == 0 /* other protocol */)) {
} else if (code == CURLE_OK &&
(httpStatus == 200 || httpStatus == 201 || httpStatus == 204 ||
httpStatus == 206 || httpStatus == 304 ||
httpStatus == 226 /* FTP */ ||
httpStatus == 0 /* other protocol */)) {
result.cached = httpStatus == 304;
done = true;
callback(std::move(result));
@ -464,8 +473,9 @@ struct CurlDownloader : public Downloader {
embargo =
std::chrono::steady_clock::now() + std::chrono::milliseconds(ms);
downloader.enqueueItem(shared_from_this());
} else
} else {
fail(exc);
}
}
}
};
@ -548,10 +558,11 @@ struct CurlDownloader : public Downloader {
/* Let curl do its thing. */
int running;
CURLMcode mc = curl_multi_perform(curlm, &running);
if (mc != CURLM_OK)
if (mc != CURLM_OK) {
throw nix::Error(
format("unexpected error from curl_multi_perform(): %s") %
curl_multi_strerror(mc));
}
/* Set the promises of any finished requests. */
CURLMsg* msg;
@ -584,9 +595,10 @@ struct CurlDownloader : public Downloader {
: maxSleepTimeMs;
DLOG(INFO) << "download thread waiting for " << sleepTimeMs << " ms";
mc = curl_multi_wait(curlm, extraFDs, 1, sleepTimeMs, &numfds);
if (mc != CURLM_OK)
if (mc != CURLM_OK) {
throw nix::Error(format("unexpected error from curl_multi_wait(): %s") %
curl_multi_strerror(mc));
}
nextWakeup = std::chrono::steady_clock::time_point();
@ -596,8 +608,9 @@ struct CurlDownloader : public Downloader {
if (extraFDs[0].revents & CURL_WAIT_POLLIN) {
char buf[1024];
auto res = read(extraFDs[0].fd, buf, sizeof(buf));
if (res == -1 && errno != EINTR)
if (res == -1 && errno != EINTR) {
throw SysError("reading curl wakeup socket");
}
}
std::vector<std::shared_ptr<DownloadItem>> incoming;
@ -612,8 +625,9 @@ struct CurlDownloader : public Downloader {
state->incoming.pop();
} else {
if (nextWakeup == std::chrono::steady_clock::time_point() ||
item->embargo < nextWakeup)
item->embargo < nextWakeup) {
nextWakeup = item->embargo;
}
break;
}
}
@ -643,22 +657,26 @@ struct CurlDownloader : public Downloader {
{
auto state(state_.lock());
while (!state->incoming.empty()) state->incoming.pop();
while (!state->incoming.empty()) {
state->incoming.pop();
}
state->quit = true;
}
}
void enqueueItem(std::shared_ptr<DownloadItem> item) {
if (item->request.data && !hasPrefix(item->request.uri, "http://") &&
!hasPrefix(item->request.uri, "https://"))
!hasPrefix(item->request.uri, "https://")) {
throw nix::Error("uploading to '%s' is not supported", item->request.uri);
}
{
auto state(state_.lock());
if (state->quit)
if (state->quit) {
throw nix::Error(
"cannot enqueue download request because the download thread is "
"shutting down");
}
state->incoming.push(item);
}
writeFull(wakeupPipe.writeSide.get(), " ");
@ -900,8 +918,9 @@ CachedDownloadResult Downloader::downloadCached(
expectedETag = ss[1];
}
}
} else
} else {
storePath = "";
}
}
if (!skip) {

View file

@ -46,9 +46,10 @@ void Store::exportPath(const Path& path, Sink& sink) {
filesystem corruption from spreading to other machines.
Don't complain if the stored hash is zero (unknown). */
Hash hash = hashAndWriteSink.currentHash();
if (hash != info->narHash && info->narHash != Hash(info->narHash.type))
if (hash != info->narHash && info->narHash != Hash(info->narHash.type)) {
throw Error(format("hash of path '%1%' has changed from '%2%' to '%3%'!") %
path % info->narHash.to_string() % hash.to_string());
}
hashAndWriteSink << exportMagic << path << info->references << info->deriver
<< 0;
@ -62,17 +63,19 @@ Paths Store::importPaths(Source& source, std::shared_ptr<FSAccessor> accessor,
if (n == 0) {
break;
}
if (n != 1)
if (n != 1) {
throw Error(
"input doesn't look like something created by 'nix-store --export'");
}
/* Extract the NAR from the source. */
TeeSink tee(source);
parseDump(tee, tee.source);
uint32_t magic = readInt(source);
if (magic != exportMagic)
if (magic != exportMagic) {
throw Error("Nix archive cannot be imported; wrong format");
}
ValidPathInfo info;

View file

@ -61,8 +61,9 @@ static void makeSymlink(const Path& link, const Path& target) {
createSymlink(target, tempLink);
/* Atomically replace the old one. */
if (rename(tempLink.c_str(), link.c_str()) == -1)
if (rename(tempLink.c_str(), link.c_str()) == -1) {
throw SysError(format("cannot rename '%1%' to '%2%'") % tempLink % link);
}
}
void LocalStore::syncWithGC() { AutoCloseFD fdGCLock = openGCLock(ltRead); }
@ -80,18 +81,21 @@ Path LocalFSStore::addPermRoot(const Path& _storePath, const Path& _gcRoot,
Path gcRoot(canonPath(_gcRoot));
assertStorePath(storePath);
if (isInStore(gcRoot))
if (isInStore(gcRoot)) {
throw Error(format("creating a garbage collector root (%1%) in the Nix "
"store is forbidden "
"(are you running nix-build inside the store?)") %
gcRoot);
}
if (indirect) {
/* Don't clobber the link if it already exists and doesn't
point to the Nix store. */
if (pathExists(gcRoot) && (!isLink(gcRoot) || !isInStore(readLink(gcRoot))))
if (pathExists(gcRoot) &&
(!isLink(gcRoot) || !isInStore(readLink(gcRoot)))) {
throw Error(format("cannot create symlink '%1%'; already exists") %
gcRoot);
}
makeSymlink(gcRoot, storePath);
addIndirectRoot(gcRoot);
}
@ -101,16 +105,18 @@ Path LocalFSStore::addPermRoot(const Path& _storePath, const Path& _gcRoot,
Path rootsDir =
canonPath((format("%1%/%2%") % stateDir % gcRootsDir).str());
if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/")
if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/") {
throw Error(format("path '%1%' is not a valid garbage collector root; "
"it's not in the directory '%2%'") %
gcRoot % rootsDir);
}
}
if (baseNameOf(gcRoot) == baseNameOf(storePath))
if (baseNameOf(gcRoot) == baseNameOf(storePath)) {
writeFile(gcRoot, "");
else
} else {
makeSymlink(gcRoot, storePath);
}
}
/* Check that the root can be found by the garbage collector.
@ -144,10 +150,11 @@ void LocalStore::addTempRoot(const Path& path) {
while (1) {
AutoCloseFD fdGCLock = openGCLock(ltRead);
if (pathExists(fnTempRoots))
if (pathExists(fnTempRoots)) {
/* It *must* be stale, since there can be no two
processes with the same pid. */
unlink(fnTempRoots.c_str());
}
state->fdTempRoots = openLockFile(fnTempRoots, true);
@ -159,8 +166,9 @@ void LocalStore::addTempRoot(const Path& path) {
/* Check whether the garbage collector didn't get in our
way. */
struct stat st;
if (fstat(state->fdTempRoots.get(), &st) == -1)
if (fstat(state->fdTempRoots.get(), &st) == -1) {
throw SysError(format("statting '%1%'") % fnTempRoots);
}
if (st.st_size == 0) {
break;
}
@ -245,11 +253,12 @@ void LocalStore::findTempRoots(FDs& fds, Roots& tempRoots, bool censor) {
void LocalStore::findRoots(const Path& path, unsigned char type, Roots& roots) {
auto foundRoot = [&](const Path& path, const Path& target) {
Path storePath = toStorePath(target);
if (isStorePath(storePath) && isValidPath(storePath))
if (isStorePath(storePath) && isValidPath(storePath)) {
roots[storePath].emplace(path);
else
} else {
LOG(INFO) << "skipping invalid root from '" << path << "' to '"
<< storePath << "'";
}
};
try {
@ -258,8 +267,9 @@ void LocalStore::findRoots(const Path& path, unsigned char type, Roots& roots) {
}
if (type == DT_DIR) {
for (auto& i : readDirectory(path))
for (auto& i : readDirectory(path)) {
findRoots(path + "/" + i.name, i.type, roots);
}
}
else if (type == DT_LNK) {
@ -292,8 +302,9 @@ void LocalStore::findRoots(const Path& path, unsigned char type, Roots& roots) {
else if (type == DT_REG) {
Path storePath = storeDir + "/" + baseNameOf(path);
if (isStorePath(storePath) && isValidPath(storePath))
if (isStorePath(storePath) && isValidPath(storePath)) {
roots[storePath].emplace(path);
}
}
}
@ -395,8 +406,9 @@ void LocalStore::findRuntimeRoots(Roots& roots, bool censor) {
}
struct dirent* fd_ent;
while (errno = 0, fd_ent = readdir(fdDir.get())) {
if (fd_ent->d_name[0] != '.')
if (fd_ent->d_name[0] != '.') {
readProcLink(fmt("%s/%s", fdStr, fd_ent->d_name), unchecked);
}
}
if (errno) {
if (errno == ESRCH) {
@ -412,8 +424,9 @@ void LocalStore::findRuntimeRoots(Roots& roots, bool censor) {
readFile(mapFile, true), "\n");
for (const auto& line : mapLines) {
auto match = std::smatch{};
if (std::regex_match(line, match, mapRegex))
if (std::regex_match(line, match, mapRegex)) {
unchecked[match[1]].emplace(mapFile);
}
}
auto envFile = fmt("/proc/%s/environ", ent->d_name);
@ -421,8 +434,9 @@ void LocalStore::findRuntimeRoots(Roots& roots, bool censor) {
auto env_end = std::sregex_iterator{};
for (auto i = std::sregex_iterator{envString.begin(), envString.end(),
storePathRegex};
i != env_end; ++i)
i != env_end; ++i) {
unchecked[i->str()].emplace(envFile);
}
} catch (SysError& e) {
if (errno == ENOENT || errno == EACCES || errno == ESRCH) {
continue;
@ -467,10 +481,11 @@ void LocalStore::findRuntimeRoots(Roots& roots, bool censor) {
Path path = toStorePath(target);
if (isStorePath(path) && isValidPath(path)) {
DLOG(INFO) << "got additional root " << path;
if (censor)
if (censor) {
roots[path].insert(censored);
else
} else {
roots[path].insert(links.begin(), links.end());
}
}
}
}
@ -514,10 +529,11 @@ void LocalStore::deletePathRecursive(GCState& state, const Path& path) {
if (isStorePath(path) && isValidPath(path)) {
PathSet referrers;
queryReferrers(path, referrers);
for (auto& i : referrers)
for (auto& i : referrers) {
if (i != path) {
deletePathRecursive(state, i);
}
}
size = queryPathInfo(path)->narSize;
invalidatePathChecked(path);
}
@ -546,12 +562,14 @@ void LocalStore::deletePathRecursive(GCState& state, const Path& path) {
// if the path was not valid, need to determine the actual
// size.
try {
if (chmod(realPath.c_str(), st.st_mode | S_IWUSR) == -1)
if (chmod(realPath.c_str(), st.st_mode | S_IWUSR) == -1) {
throw SysError(format("making '%1%' writable") % realPath);
}
Path tmp = trashDir + "/" + baseNameOf(path);
if (rename(realPath.c_str(), tmp.c_str()))
if (rename(realPath.c_str(), tmp.c_str())) {
throw SysError(format("unable to rename '%1%' to '%2%'") % realPath %
tmp);
}
state.bytesInvalidated += size;
} catch (SysError& e) {
if (e.errNo == ENOSPC) {
@ -560,8 +578,9 @@ void LocalStore::deletePathRecursive(GCState& state, const Path& path) {
deleteGarbage(state, realPath);
}
}
} else
} else {
deleteGarbage(state, realPath);
}
if (state.results.bytesFreed + state.bytesInvalidated >
state.options.maxFreed) {
@ -606,9 +625,11 @@ bool LocalStore::canReachRoot(GCState& state, PathSet& visited,
don't delete the derivation if any of the outputs are alive. */
if (state.gcKeepDerivations && isDerivation(path)) {
PathSet outputs = queryDerivationOutputs(path);
for (auto& i : outputs)
if (isValidPath(i) && queryPathInfo(i)->deriver == path)
for (auto& i : outputs) {
if (isValidPath(i) && queryPathInfo(i)->deriver == path) {
incoming.insert(i);
}
}
}
/* If keep-outputs is set, then don't delete this path if there
@ -620,12 +641,14 @@ bool LocalStore::canReachRoot(GCState& state, PathSet& visited,
}
}
for (auto& i : incoming)
if (i != path)
for (auto& i : incoming) {
if (i != path) {
if (canReachRoot(state, visited, i)) {
state.alive.insert(path);
return true;
}
}
}
return false;
}
@ -701,8 +724,9 @@ void LocalStore::removeUnusedLinks(const GCState& state) {
Path path = linksDir + "/" + name;
struct stat st;
if (lstat(path.c_str(), &st) == -1)
if (lstat(path.c_str(), &st) == -1) {
throw SysError(format("statting '%1%'") % path);
}
if (st.st_nlink != 1) {
actualSize += st.st_size;
@ -807,16 +831,18 @@ void LocalStore::collectGarbage(const GCOptions& options, GCResults& results) {
for (auto& i : options.pathsToDelete) {
assertStorePath(i);
tryToDelete(state, i);
if (state.dead.find(i) == state.dead.end())
if (state.dead.find(i) == state.dead.end()) {
throw Error(format("cannot delete path '%1%' since it is still alive") %
i);
}
}
} else if (options.maxFreed > 0) {
if (state.shouldDelete)
if (state.shouldDelete) {
LOG(INFO) << "deleting garbage...";
else
} else {
LOG(ERROR) << "determining live/dead paths...";
}
try {
AutoCloseDir dir(opendir(realStoreDir.c_str()));
@ -839,10 +865,11 @@ void LocalStore::collectGarbage(const GCOptions& options, GCResults& results) {
continue;
}
Path path = storeDir + "/" + name;
if (isStorePath(path) && isValidPath(path))
if (isStorePath(path) && isValidPath(path)) {
entries.push_back(path);
else
} else {
tryToDelete(state, path);
}
}
dir.reset();
@ -897,8 +924,9 @@ void LocalStore::autoGC(bool sync) {
static auto fakeFreeSpaceFile = getEnv("_NIX_TEST_FREE_SPACE_FILE", "");
auto getAvail = [this]() -> uint64_t {
if (!fakeFreeSpaceFile.empty())
if (!fakeFreeSpaceFile.empty()) {
return std::stoll(readFile(fakeFreeSpaceFile));
}
struct statvfs st;
if (statvfs(realStoreDir.c_str(), &st)) {
@ -922,8 +950,9 @@ void LocalStore::autoGC(bool sync) {
auto now = std::chrono::steady_clock::now();
if (now < state->lastGCCheck +
std::chrono::seconds(settings.minFreeCheckInterval))
std::chrono::seconds(settings.minFreeCheckInterval)) {
return;
}
auto avail = getAvail();

View file

@ -49,11 +49,12 @@ Settings::Settings()
if (caFile == "") {
for (auto& fn :
{"/etc/ssl/certs/ca-certificates.crt",
"/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"})
"/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"}) {
if (pathExists(fn)) {
caFile = fn;
break;
}
}
}
/* Backwards compatibility. */
@ -112,26 +113,28 @@ const string nixVersion = PACKAGE_VERSION;
template <>
void BaseSetting<SandboxMode>::set(const std::string& str) {
if (str == "true")
if (str == "true") {
value = smEnabled;
else if (str == "relaxed")
} else if (str == "relaxed") {
value = smRelaxed;
else if (str == "false")
} else if (str == "false") {
value = smDisabled;
else
} else {
throw UsageError("option '%s' has invalid value '%s'", name, str);
}
}
template <>
std::string BaseSetting<SandboxMode>::to_string() {
if (value == smEnabled)
if (value == smEnabled) {
return "true";
else if (value == smRelaxed)
} else if (value == smRelaxed) {
return "relaxed";
else if (value == smDisabled)
} else if (value == smDisabled) {
return "false";
else
} else {
abort();
}
}
template <>
@ -160,11 +163,12 @@ void BaseSetting<SandboxMode>::convertToArg(Args& args,
}
void MaxBuildJobsSetting::set(const std::string& str) {
if (str == "auto")
if (str == "auto") {
value = std::max(1U, std::thread::hardware_concurrency());
else if (!string2Int(str, value))
} else if (!string2Int(str, value)) {
throw UsageError(
"configuration setting '%s' should be 'auto' or an integer", name);
}
}
void initPlugins() {
@ -172,8 +176,9 @@ void initPlugins() {
Paths pluginFiles;
try {
auto ents = readDirectory(pluginFile);
for (const auto& ent : ents)
for (const auto& ent : ents) {
pluginFiles.emplace_back(pluginFile + "/" + ent.name);
}
} catch (SysError& e) {
if (e.errNo != ENOTDIR) {
throw;
@ -184,9 +189,10 @@ void initPlugins() {
/* handle is purposefully leaked as there may be state in the
DSO needed by the action of the plugin. */
void* handle = dlopen(file.c_str(), RTLD_LAZY | RTLD_LOCAL);
if (!handle)
if (!handle) {
throw Error("could not dynamically open plugin file '%s': %s", file,
dlerror());
}
}
}

View file

@ -408,17 +408,10 @@ class Settings : public Config {
this, true, "print-missing",
"Whether to print what paths need to be built or downloaded."};
Setting<std::string> preBuildHook {
this,
#if __APPLE__
nixLibexecDir + "/nix/resolve-system-dependencies",
#else
"",
#endif
"pre-build-hook",
"A program to run just before a build to set derivation-specific build "
"settings."
};
Setting<std::string> preBuildHook{
this, "", "pre-build-hook",
"A program to run just before a build to set derivation-specific build "
"settings."};
Setting<std::string> postBuildHook{
this, "", "post-build-hook",

View file

@ -113,9 +113,10 @@ class HttpBinaryCacheStore : public BinaryCacheStore {
try {
getDownloader()->download(std::move(request), sink);
} catch (DownloadError& e) {
if (e.error == Downloader::NotFound || e.error == Downloader::Forbidden)
if (e.error == Downloader::NotFound || e.error == Downloader::Forbidden) {
throw NoSuchBinaryCacheFile(
"file '%s' does not exist in binary cache '%s'", path, getUri());
}
maybeDisable();
throw;
}
@ -137,8 +138,9 @@ class HttpBinaryCacheStore : public BinaryCacheStore {
(*callbackPtr)(result.get().data);
} catch (DownloadError& e) {
if (e.error == Downloader::NotFound ||
e.error == Downloader::Forbidden)
e.error == Downloader::Forbidden) {
return (*callbackPtr)(std::shared_ptr<std::string>());
}
maybeDisable();
callbackPtr->rethrow();
} catch (...) {
@ -154,8 +156,9 @@ static RegisterStoreImplementation regStore(
if (std::string(uri, 0, 7) != "http://" &&
std::string(uri, 0, 8) != "https://" &&
(getEnv("_NIX_FORCE_HTTP_BINARY_CACHE_STORE") != "1" ||
std::string(uri, 0, 7) != "file://"))
std::string(uri, 0, 7) != "file://")) {
return 0;
}
auto store = std::make_shared<HttpBinaryCacheStore>(params, uri);
store->init();
return store;

View file

@ -69,12 +69,14 @@ struct LegacySSHStore : public Store {
conn->to.flush();
unsigned int magic = readInt(conn->from);
if (magic != SERVE_MAGIC_2)
if (magic != SERVE_MAGIC_2) {
throw Error("protocol mismatch with 'nix-store --serve' on '%s'", host);
}
conn->remoteVersion = readInt(conn->from);
if (GET_PROTOCOL_MAJOR(conn->remoteVersion) != 0x200)
if (GET_PROTOCOL_MAJOR(conn->remoteVersion) != 0x200) {
throw Error("unsupported 'nix-store --serve' protocol version on '%s'",
host);
}
} catch (EndOfFile& e) {
throw Error("cannot connect to '%1%'", host);
@ -160,9 +162,10 @@ struct LegacySSHStore : public Store {
conn->to.flush();
}
if (readInt(conn->from) != 1)
if (readInt(conn->from) != 1) {
throw Error(
"failed to add path '%s' to remote host '%s', info.path, host");
}
}
void narFromPath(const Path& path, Sink& sink) override {
@ -194,10 +197,12 @@ struct LegacySSHStore : public Store {
conn->to << cmdBuildDerivation << drvPath << drv << settings.maxSilentTime
<< settings.buildTimeout;
if (GET_PROTOCOL_MINOR(conn->remoteVersion) >= 2)
if (GET_PROTOCOL_MINOR(conn->remoteVersion) >= 2) {
conn->to << settings.maxLogSize;
if (GET_PROTOCOL_MINOR(conn->remoteVersion) >= 3)
}
if (GET_PROTOCOL_MINOR(conn->remoteVersion) >= 3) {
conn->to << settings.buildRepeat << settings.enforceDeterminism;
}
conn->to.flush();
@ -205,9 +210,10 @@ struct LegacySSHStore : public Store {
status.status = (BuildResult::Status)readInt(conn->from);
conn->from >> status.errorMsg;
if (GET_PROTOCOL_MINOR(conn->remoteVersion) >= 3)
if (GET_PROTOCOL_MINOR(conn->remoteVersion) >= 3) {
conn->from >> status.timesBuilt >> status.isNonDeterministic >>
status.startTime >> status.stopTime;
}
return status;
}

View file

@ -26,9 +26,10 @@ class LocalBinaryCacheStore : public BinaryCacheStore {
try {
readFile(binaryCacheDir + "/" + path, sink);
} catch (SysError& e) {
if (e.errNo == ENOENT)
if (e.errNo == ENOENT) {
throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache",
path);
}
}
}
@ -36,8 +37,9 @@ class LocalBinaryCacheStore : public BinaryCacheStore {
PathSet paths;
for (auto& entry : readDirectory(binaryCacheDir)) {
if (entry.name.size() != 40 || !hasSuffix(entry.name, ".narinfo"))
if (entry.name.size() != 40 || !hasSuffix(entry.name, ".narinfo")) {
continue;
}
paths.insert(storeDir + "/" +
entry.name.substr(0, entry.name.size() - 8));
}
@ -55,8 +57,9 @@ static void atomicWrite(const Path& path, const std::string& s) {
Path tmp = path + ".tmp." + std::to_string(getpid());
AutoDelete del(tmp, false);
writeFile(tmp, s);
if (rename(tmp.c_str(), path.c_str()))
if (rename(tmp.c_str(), path.c_str())) {
throw SysError(format("renaming '%1%' to '%2%'") % tmp % path);
}
del.cancel();
}
@ -74,8 +77,9 @@ static RegisterStoreImplementation regStore(
[](const std::string& uri,
const Store::Params& params) -> std::shared_ptr<Store> {
if (getEnv("_NIX_FORCE_HTTP_BINARY_CACHE_STORE") == "1" ||
std::string(uri, 0, 7) != "file://")
std::string(uri, 0, 7) != "file://") {
return 0;
}
auto store =
std::make_shared<LocalBinaryCacheStore>(params, std::string(uri, 7));
store->init();

View file

@ -16,9 +16,10 @@ struct LocalStoreAccessor : public FSAccessor {
Path toRealPath(const Path& path) {
Path storePath = store->toStorePath(path);
if (!store->isValidPath(storePath))
if (!store->isValidPath(storePath)) {
throw InvalidPath(format("path '%1%' is not a valid store path") %
storePath);
}
return store->getRealStoreDir() + std::string(path, store->storeDir.size());
}
@ -27,13 +28,15 @@ struct LocalStoreAccessor : public FSAccessor {
struct stat st;
if (lstat(realPath.c_str(), &st)) {
if (errno == ENOENT || errno == ENOTDIR)
if (errno == ENOENT || errno == ENOTDIR) {
return {Type::tMissing, 0, false};
}
throw SysError(format("getting status of '%1%'") % path);
}
if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode))
if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode)) {
throw Error(format("file '%1%' has unsupported type") % path);
}
return {S_ISREG(st.st_mode)
? Type::tRegular

View file

@ -73,8 +73,9 @@ LocalStore::LocalStore(const Params& params)
for (auto& perUserDir :
{profilesDir + "/per-user", gcRootsDir + "/per-user"}) {
createDirs(perUserDir);
if (chmod(perUserDir.c_str(), 0755) == -1)
if (chmod(perUserDir.c_str(), 0755) == -1) {
throw SysError("could not set permissions on '%s' to 755", perUserDir);
}
}
createUser(getUserName(), getuid());
@ -90,18 +91,21 @@ LocalStore::LocalStore(const Params& params)
<< "' specified in 'build-users-group' does not exist";
} else {
struct stat st;
if (stat(realStoreDir.c_str(), &st))
if (stat(realStoreDir.c_str(), &st)) {
throw SysError(format("getting attributes of path '%1%'") %
realStoreDir);
}
if (st.st_uid != 0 || st.st_gid != gr->gr_gid ||
(st.st_mode & ~S_IFMT) != perm) {
if (chown(realStoreDir.c_str(), 0, gr->gr_gid) == -1)
if (chown(realStoreDir.c_str(), 0, gr->gr_gid) == -1) {
throw SysError(format("changing ownership of path '%1%'") %
realStoreDir);
if (chmod(realStoreDir.c_str(), perm) == -1)
}
if (chmod(realStoreDir.c_str(), perm) == -1) {
throw SysError(format("changing permissions on path '%1%'") %
realStoreDir);
}
}
}
}
@ -111,13 +115,15 @@ LocalStore::LocalStore(const Params& params)
Path path = realStoreDir;
struct stat st;
while (path != "/") {
if (lstat(path.c_str(), &st))
if (lstat(path.c_str(), &st)) {
throw SysError(format("getting status of '%1%'") % path);
if (S_ISLNK(st.st_mode))
}
if (S_ISLNK(st.st_mode)) {
throw Error(format("the path '%1%' is a symlink; "
"this is not allowed for the Nix store and its "
"parent directories") %
path);
}
path = dirOf(path);
}
}
@ -168,17 +174,19 @@ LocalStore::LocalStore(const Params& params)
openDB(*state, true);
writeFile(schemaPath, (format("%1%") % nixSchemaVersion).str());
} else if (curSchema < nixSchemaVersion) {
if (curSchema < 5)
if (curSchema < 5) {
throw Error(
"Your Nix store has a database in Berkeley DB format,\n"
"which is no longer supported. To convert to the new format,\n"
"please upgrade Nix to version 0.12 first.");
}
if (curSchema < 6)
if (curSchema < 6) {
throw Error(
"Your Nix store has a database in flat file format,\n"
"which is no longer supported. To convert to the new format,\n"
"please upgrade Nix to version 1.11 first.");
}
if (!lockFile(globalLock.get(), ltWrite, false)) {
LOG(INFO) << "waiting for exclusive access to the Nix store...";
@ -295,24 +303,27 @@ int LocalStore::getSchema() {
int curSchema = 0;
if (pathExists(schemaPath)) {
string s = readFile(schemaPath);
if (!string2Int(s, curSchema))
if (!string2Int(s, curSchema)) {
throw Error(format("'%1%' is corrupt") % schemaPath);
}
}
return curSchema;
}
void LocalStore::openDB(State& state, bool create) {
if (access(dbDir.c_str(), R_OK | W_OK))
if (access(dbDir.c_str(), R_OK | W_OK)) {
throw SysError(format("Nix database directory '%1%' is not writable") %
dbDir);
}
/* Open the Nix database. */
string dbPath = dbDir + "/db.sqlite";
auto& db(state.db);
if (sqlite3_open_v2(dbPath.c_str(), &db.db,
SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0),
0) != SQLITE_OK)
0) != SQLITE_OK) {
throw Error(format("cannot open Nix database '%1%'") % dbPath);
}
#ifdef __CYGWIN__
/* The cygwin version of sqlite3 has a patch which calls
@ -354,15 +365,17 @@ void LocalStore::openDB(State& state, bool create) {
}
if (prevMode != mode &&
sqlite3_exec(db, ("pragma main.journal_mode = " + mode + ";").c_str(), 0,
0, 0) != SQLITE_OK)
0, 0) != SQLITE_OK) {
throwSQLiteError(db, "setting journal mode");
}
/* Increase the auto-checkpoint interval to 40000 pages. This
seems enough to ensure that instantiating the NixOS system
derivation is done in a single fsync(). */
if (mode == "wal" && sqlite3_exec(db, "pragma wal_autocheckpoint = 40000;", 0,
0, 0) != SQLITE_OK)
0, 0) != SQLITE_OK) {
throwSQLiteError(db, "setting autocheckpoint interval");
}
/* Initialise the database schema, if necessary. */
if (create) {
@ -382,15 +395,18 @@ void LocalStore::makeStoreWritable() {
}
/* Check if /nix/store is on a read-only mount. */
struct statvfs stat;
if (statvfs(realStoreDir.c_str(), &stat) != 0)
if (statvfs(realStoreDir.c_str(), &stat) != 0) {
throw SysError("getting info about the Nix store mount point");
}
if (stat.f_flag & ST_RDONLY) {
if (unshare(CLONE_NEWNS) == -1)
if (unshare(CLONE_NEWNS) == -1) {
throw SysError("setting up a private mount namespace");
}
if (mount(0, realStoreDir.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
if (mount(0, realStoreDir.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1) {
throw SysError(format("remounting %1% writable") % realStoreDir);
}
}
#endif
}
@ -405,8 +421,9 @@ static void canonicaliseTimestampAndPermissions(const Path& path,
if (mode != 0444 && mode != 0555) {
mode = (st.st_mode & S_IFMT) | 0444 | (st.st_mode & S_IXUSR ? 0111 : 0);
if (chmod(path.c_str(), mode) == -1)
if (chmod(path.c_str(), mode) == -1) {
throw SysError(format("changing mode of '%1%' to %2$o") % path % mode);
}
}
}
@ -417,20 +434,23 @@ static void canonicaliseTimestampAndPermissions(const Path& path,
times[1].tv_sec = mtimeStore;
times[1].tv_usec = 0;
#if HAVE_LUTIMES
if (lutimes(path.c_str(), times) == -1)
if (lutimes(path.c_str(), times) == -1) {
if (errno != ENOSYS ||
(!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1))
(!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1)) {
#else
if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1)
#endif
throw SysError(format("changing modification time of '%1%'") % path);
}
}
}
} // namespace nix
}
void canonicaliseTimestampAndPermissions(const Path& path) {
struct stat st;
if (lstat(path.c_str(), &st))
if (lstat(path.c_str(), &st)) {
throw SysError(format("getting attributes of path '%1%'") % path);
}
canonicaliseTimestampAndPermissions(path, st);
}
@ -449,25 +469,29 @@ static void canonicalisePathMetaData_(const Path& path, uid_t fromUid,
#endif
struct stat st;
if (lstat(path.c_str(), &st))
if (lstat(path.c_str(), &st)) {
throw SysError(format("getting attributes of path '%1%'") % path);
}
/* Really make sure that the path is of a supported type. */
if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)))
if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))) {
throw Error(format("file '%1%' has an unsupported type") % path);
}
#if __linux__
/* Remove extended attributes / ACLs. */
ssize_t eaSize = llistxattr(path.c_str(), nullptr, 0);
if (eaSize < 0) {
if (errno != ENOTSUP && errno != ENODATA)
if (errno != ENOTSUP && errno != ENODATA) {
throw SysError("querying extended attributes of '%s'", path);
}
} else if (eaSize > 0) {
std::vector<char> eaBuf(eaSize);
if ((eaSize = llistxattr(path.c_str(), eaBuf.data(), eaBuf.size())) < 0)
if ((eaSize = llistxattr(path.c_str(), eaBuf.data(), eaBuf.size())) < 0) {
throw SysError("querying extended attributes of '%s'", path);
}
for (auto& eaName : tokenizeString<Strings>(
std::string(eaBuf.data(), eaSize), std::string("\000", 1))) {
@ -476,9 +500,10 @@ static void canonicalisePathMetaData_(const Path& path, uid_t fromUid,
if (eaName == "security.selinux") {
continue;
}
if (lremovexattr(path.c_str(), eaName.c_str()) == -1)
if (lremovexattr(path.c_str(), eaName.c_str()) == -1) {
throw SysError("removing extended attribute '%s' from '%s'", eaName,
path);
}
}
}
#endif
@ -491,8 +516,9 @@ static void canonicalisePathMetaData_(const Path& path, uid_t fromUid,
(i.e. "touch $out/foo; ln $out/foo $out/bar"). */
if (fromUid != (uid_t)-1 && st.st_uid != fromUid) {
assert(!S_ISDIR(st.st_mode));
if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end())
if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end()) {
throw BuildError(format("invalid ownership on file '%1%'") % path);
}
mode_t mode = st.st_mode & ~S_IFMT;
assert(S_ISLNK(st.st_mode) ||
(st.st_uid == geteuid() && (mode == 0444 || mode == 0555) &&
@ -513,18 +539,20 @@ static void canonicalisePathMetaData_(const Path& path, uid_t fromUid,
users group); we check for this case below. */
if (st.st_uid != geteuid()) {
#if HAVE_LCHOWN
if (lchown(path.c_str(), geteuid(), getegid()) == -1)
if (lchown(path.c_str(), geteuid(), getegid()) == -1) {
#else
if (!S_ISLNK(st.st_mode) && chown(path.c_str(), geteuid(), getegid()) == -1)
#endif
throw SysError(format("changing owner of '%1%' to %2%") % path %
geteuid());
}
}
if (S_ISDIR(st.st_mode)) {
DirEntries entries = readDirectory(path);
for (auto& i : entries)
for (auto& i : entries) {
canonicalisePathMetaData_(path + "/" + i.name, fromUid, inodesSeen);
}
}
}
@ -535,8 +563,9 @@ void canonicalisePathMetaData(const Path& path, uid_t fromUid,
/* On platforms that don't have lchown(), the top-level path can't
be a symlink, since we can't change its ownership. */
struct stat st;
if (lstat(path.c_str(), &st))
if (lstat(path.c_str(), &st)) {
throw SysError(format("getting attributes of path '%1%'") % path);
}
if (st.st_uid != geteuid()) {
assert(S_ISLNK(st.st_mode));
@ -557,10 +586,11 @@ void LocalStore::checkDerivationOutputs(const Path& drvPath,
if (drv.isFixedOutput()) {
DerivationOutputs::const_iterator out = drv.outputs.find("out");
if (out == drv.outputs.end())
if (out == drv.outputs.end()) {
throw Error(
format("derivation '%1%' does not have an output named 'out'") %
drvPath);
}
bool recursive;
Hash h;
@ -569,11 +599,12 @@ void LocalStore::checkDerivationOutputs(const Path& drvPath,
StringPairs::const_iterator j = drv.env.find("out");
if (out->second.path != outPath || j == drv.env.end() ||
j->second != outPath)
j->second != outPath) {
throw Error(
format(
"derivation '%1%' has incorrect output '%2%', should be '%3%'") %
drvPath % out->second.path % outPath);
}
}
else {
@ -589,21 +620,23 @@ void LocalStore::checkDerivationOutputs(const Path& drvPath,
Path outPath = makeOutputPath(i.first, h, drvName);
StringPairs::const_iterator j = drv.env.find(i.first);
if (i.second.path != outPath || j == drv.env.end() ||
j->second != outPath)
j->second != outPath) {
throw Error(format("derivation '%1%' has incorrect output '%2%', "
"should be '%3%'") %
drvPath % i.second.path % outPath);
}
}
}
}
uint64_t LocalStore::addValidPath(State& state, const ValidPathInfo& info,
bool checkOutputs) {
if (info.ca != "" && !info.isContentAddressed(*this))
if (info.ca != "" && !info.isContentAddressed(*this)) {
throw Error(
"cannot add path '%s' to the Nix store because it claims to be "
"content-addressed but isn't",
info.path);
}
state.stmtRegisterValidPath
.use()(info.path)(info.narHash.to_string(Base16))(
@ -697,8 +730,9 @@ void LocalStore::queryPathInfoUncached(
/* Get the references. */
auto useQueryReferences(state->stmtQueryReferences.use()(info->id));
while (useQueryReferences.next())
while (useQueryReferences.next()) {
info->references.insert(useQueryReferences.getStr(0));
}
return info;
}));
@ -740,10 +774,11 @@ bool LocalStore::isValidPathUncached(const Path& path) {
PathSet LocalStore::queryValidPaths(const PathSet& paths,
SubstituteFlag maybeSubstitute) {
PathSet res;
for (auto& i : paths)
for (auto& i : paths) {
if (isValidPath(i)) {
res.insert(i);
}
}
return res;
}
@ -752,7 +787,9 @@ PathSet LocalStore::queryAllValidPaths() {
auto state(_state.lock());
auto use(state->stmtQueryValidPaths.use());
PathSet res;
while (use.next()) res.insert(use.getStr(0));
while (use.next()) {
res.insert(use.getStr(0));
}
return res;
});
}
@ -761,8 +798,9 @@ void LocalStore::queryReferrers(State& state, const Path& path,
PathSet& referrers) {
auto useQueryReferrers(state.stmtQueryReferrers.use()(path));
while (useQueryReferrers.next())
while (useQueryReferrers.next()) {
referrers.insert(useQueryReferrers.getStr(0));
}
}
void LocalStore::queryReferrers(const Path& path, PathSet& referrers) {
@ -782,8 +820,9 @@ PathSet LocalStore::queryValidDerivers(const Path& path) {
auto useQueryValidDerivers(state->stmtQueryValidDerivers.use()(path));
PathSet derivers;
while (useQueryValidDerivers.next())
while (useQueryValidDerivers.next()) {
derivers.insert(useQueryValidDerivers.getStr(1));
}
return derivers;
});
@ -797,8 +836,9 @@ PathSet LocalStore::queryDerivationOutputs(const Path& path) {
queryValidPathId(*state, path)));
PathSet outputs;
while (useQueryDerivationOutputs.next())
while (useQueryDerivationOutputs.next()) {
outputs.insert(useQueryDerivationOutputs.getStr(1));
}
return outputs;
});
@ -812,8 +852,9 @@ StringSet LocalStore::queryDerivationOutputNames(const Path& path) {
queryValidPathId(*state, path)));
StringSet outputNames;
while (useQueryDerivationOutputs.next())
while (useQueryDerivationOutputs.next()) {
outputNames.insert(useQueryDerivationOutputs.getStr(0));
}
return outputNames;
});
@ -865,11 +906,13 @@ PathSet LocalStore::querySubstitutablePaths(const PathSet& paths) {
auto valid = sub->queryValidPaths(remaining);
PathSet remaining2;
for (auto& path : remaining)
if (valid.count(path))
for (auto& path : remaining) {
if (valid.count(path)) {
res.insert(path);
else
} else {
remaining2.insert(path);
}
}
std::swap(remaining, remaining2);
}
@ -935,24 +978,26 @@ void LocalStore::registerValidPaths(const ValidPathInfos& infos) {
for (auto& i : infos) {
assert(i.narHash.type == htSHA256);
if (isValidPath_(*state, i.path))
if (isValidPath_(*state, i.path)) {
updatePathInfo(*state, i);
else
} else {
addValidPath(*state, i, false);
}
paths.insert(i.path);
}
for (auto& i : infos) {
auto referrer = queryValidPathId(*state, i.path);
for (auto& j : i.references)
for (auto& j : i.references) {
state->stmtAddReference.use()(referrer)(queryValidPathId(*state, j))
.exec();
}
}
/* Check that the derivation outputs are correct. We can't do
this in addValidPath() above, because the references might
not be valid yet. */
for (auto& i : infos)
for (auto& i : infos) {
if (isDerivation(i.path)) {
// FIXME: inefficient; we already loaded the
// derivation in addValidPath().
@ -960,6 +1005,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos& infos) {
readDerivation(realStoreDir + "/" + baseNameOf(i.path));
checkDerivationOutputs(i.path, drv);
}
}
/* Do a topological sort of the paths. This will throw an
error if a cycle is detected and roll back the
@ -989,8 +1035,9 @@ void LocalStore::invalidatePath(State& state, const Path& path) {
const PublicKeys& LocalStore::getPublicKeys() {
auto state(_state.lock());
if (!state->publicKeys)
if (!state->publicKeys) {
state->publicKeys = std::make_unique<PublicKeys>(getDefaultPublicKeys());
}
return *state->publicKeys;
}
@ -1039,15 +1086,17 @@ void LocalStore::addToStore(const ValidPathInfo& info, Source& source,
auto hashResult = hashSink.finish();
if (hashResult.first != info.narHash)
if (hashResult.first != info.narHash) {
throw Error(
"hash mismatch importing path '%s';\n wanted: %s\n got: %s",
info.path, info.narHash.to_string(), hashResult.first.to_string());
}
if (hashResult.second != info.narSize)
if (hashResult.second != info.narSize) {
throw Error(
"size mismatch importing path '%s';\n wanted: %s\n got: %s",
info.path, info.narSize, hashResult.second);
}
autoGC();
@ -1130,10 +1179,11 @@ Path LocalStore::addToStore(const string& name, const Path& _srcPath,
method for very large paths, but `copyPath' is mainly used for
small files. */
StringSink sink;
if (recursive)
if (recursive) {
dumpPath(srcPath, sink, filter);
else
} else {
sink.s = make_ref<std::string>(readFile(srcPath));
}
return addToStoreFromDump(*sink.s, name, recursive, hashAlgo, repair);
}
@ -1206,10 +1256,11 @@ void LocalStore::invalidatePathChecked(const Path& path) {
PathSet referrers;
queryReferrers(*state, path, referrers);
referrers.erase(path); /* ignore self-references */
if (!referrers.empty())
if (!referrers.empty()) {
throw PathInUse(
format("cannot delete path '%1%' because it is in use by %2%") %
path % showPaths(referrers));
}
invalidatePath(*state, path);
}
@ -1238,8 +1289,9 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) {
fdGCLock = -1;
for (auto& i : validPaths2)
for (auto& i : validPaths2) {
verifyPath(i, store, done, validPaths, repair, errors);
}
/* Optionally, check the content hashes (slow). */
if (checkContents) {
@ -1328,13 +1380,14 @@ void LocalStore::verifyPath(const Path& path, const PathSet& store,
bool canInvalidate = true;
PathSet referrers;
queryReferrers(path, referrers);
for (auto& i : referrers)
for (auto& i : referrers) {
if (i != path) {
verifyPath(i, store, done, validPaths, repair, errors);
if (validPaths.find(i) != validPaths.end()) {
canInvalidate = false;
}
}
}
if (canInvalidate) {
LOG(WARNING) << "path '" << path
@ -1463,10 +1516,12 @@ void LocalStore::createUser(const std::string& userName, uid_t userId) {
for (auto& dir : {fmt("%s/profiles/per-user/%s", stateDir, userName),
fmt("%s/gcroots/per-user/%s", stateDir, userName)}) {
createDirs(dir);
if (chmod(dir.c_str(), 0755) == -1)
if (chmod(dir.c_str(), 0755) == -1) {
throw SysError("changing permissions of directory '%s'", dir);
if (chown(dir.c_str(), userId, getgid()) == -1)
}
if (chown(dir.c_str(), userId, getgid()) == -1) {
throw SysError("changing owner of directory '%s'", dir);
}
}
}

View file

@ -47,35 +47,44 @@ void Store::computeFSClosure(const PathSet& startPaths, PathSet& paths_,
if (flipDirection) {
PathSet referrers;
queryReferrers(path, referrers);
for (auto& ref : referrers)
for (auto& ref : referrers) {
if (ref != path) {
enqueue(ref);
}
}
if (includeOutputs)
if (includeOutputs) {
for (auto& i : queryValidDerivers(path)) {
enqueue(i);
}
}
if (includeDerivers && isDerivation(path))
for (auto& i : queryDerivationOutputs(path))
if (isValidPath(i) && queryPathInfo(i)->deriver == path)
if (includeDerivers && isDerivation(path)) {
for (auto& i : queryDerivationOutputs(path)) {
if (isValidPath(i) && queryPathInfo(i)->deriver == path) {
enqueue(i);
}
}
}
} else {
for (auto& ref : info->references)
for (auto& ref : info->references) {
if (ref != path) {
enqueue(ref);
}
}
if (includeOutputs && isDerivation(path))
for (auto& i : queryDerivationOutputs(path))
if (includeOutputs && isDerivation(path)) {
for (auto& i : queryDerivationOutputs(path)) {
if (isValidPath(i)) {
enqueue(i);
}
}
}
if (includeDerivers && isValidPath(info->deriver))
if (includeDerivers && isValidPath(info->deriver)) {
enqueue(info->deriver);
}
}
{
@ -105,7 +114,9 @@ void Store::computeFSClosure(const PathSet& startPaths, PathSet& paths_,
{
auto state(state_.lock());
while (state->pending) state.wait(done);
while (state->pending) {
state.wait(done);
}
if (state->exc) {
std::rethrow_exception(state->exc);
}
@ -154,9 +165,10 @@ void Store::queryMissing(const PathSet& targets, PathSet& willBuild_,
state->willBuild.insert(drvPath);
}
for (auto& i : drv.inputDrvs)
for (auto& i : drv.inputDrvs) {
pool.enqueue(
std::bind(doPath, makeDrvPathWithOutputs(i.first, i.second)));
}
};
auto checkOutput = [&](const Path& drvPath, ref<Derivation> drv,
@ -181,8 +193,9 @@ void Store::queryMissing(const PathSet& targets, PathSet& willBuild_,
drvState->left--;
drvState->outPaths.insert(outPath);
if (!drvState->left) {
for (auto& path : drvState->outPaths)
for (auto& path : drvState->outPaths) {
pool.enqueue(std::bind(doPath, path));
}
}
}
}
@ -211,20 +224,24 @@ void Store::queryMissing(const PathSet& targets, PathSet& willBuild_,
ParsedDerivation parsedDrv(i2.first, drv);
PathSet invalid;
for (auto& j : drv.outputs)
if (wantOutput(j.first, i2.second) && !isValidPath(j.second.path))
for (auto& j : drv.outputs) {
if (wantOutput(j.first, i2.second) && !isValidPath(j.second.path)) {
invalid.insert(j.second.path);
}
}
if (invalid.empty()) {
return;
}
if (settings.useSubstitutes && parsedDrv.substitutesAllowed()) {
auto drvState = make_ref<Sync<DrvState>>(DrvState(invalid.size()));
for (auto& output : invalid)
for (auto& output : invalid) {
pool.enqueue(std::bind(checkOutput, i2.first,
make_ref<Derivation>(drv), output, drvState));
} else
}
} else {
mustBuildDrv(i2.first, drv);
}
} else {
if (isValidPath(path)) {
@ -250,8 +267,9 @@ void Store::queryMissing(const PathSet& targets, PathSet& willBuild_,
state->narSize += info->second.narSize;
}
for (auto& ref : info->second.references)
for (auto& ref : info->second.references) {
pool.enqueue(std::bind(doPath, ref));
}
}
};
@ -269,10 +287,11 @@ Paths Store::topoSortPaths(const PathSet& paths) {
std::function<void(const Path& path, const Path* parent)> dfsVisit;
dfsVisit = [&](const Path& path, const Path* parent) {
if (parents.find(path) != parents.end())
if (parents.find(path) != parents.end()) {
throw BuildError(
format("cycle detected in the references of '%1%' from '%2%'") %
path % *parent);
}
if (visited.find(path) != visited.end()) {
return;
@ -286,12 +305,13 @@ Paths Store::topoSortPaths(const PathSet& paths) {
} catch (InvalidPath&) {
}
for (auto& i : references)
for (auto& i : references) {
/* Don't traverse into paths that don't exist. That can
happen due to substitutes for non-existent paths. */
if (i != path && paths.find(i) != paths.end()) {
dfsVisit(i, &path);
}
}
sorted.push_front(path);
parents.erase(path);

View file

@ -45,14 +45,17 @@ struct NarAccessor : public FSAccessor {
void createMember(const Path& path, NarMember member) {
size_t level = std::count(path.begin(), path.end(), '/');
while (parents.size() > level) parents.pop();
while (parents.size() > level) {
parents.pop();
}
if (parents.empty()) {
acc.root = std::move(member);
parents.push(&acc.root);
} else {
if (parents.top()->type != FSAccessor::Type::tDirectory)
if (parents.top()->type != FSAccessor::Type::tDirectory) {
throw Error("NAR file missing parent directory of path '%s'", path);
}
auto result = parents.top()->children.emplace(baseNameOf(path),
std::move(member));
parents.push(&result.first->second);
@ -118,8 +121,9 @@ struct NarAccessor : public FSAccessor {
} else if (type == "symlink") {
member.type = FSAccessor::Type::tSymlink;
member.target = v.value("target", "");
} else
} else {
return;
}
};
json v = json::parse(listing);
@ -157,8 +161,9 @@ struct NarAccessor : public FSAccessor {
NarMember& get(const Path& path) {
auto result = find(path);
if (result == nullptr)
if (result == nullptr) {
throw Error("NAR file does not contain path '%1%'", path);
}
return *result;
}
@ -173,9 +178,10 @@ struct NarAccessor : public FSAccessor {
StringSet readDirectory(const Path& path) override {
auto i = get(path);
if (i.type != FSAccessor::Type::tDirectory)
if (i.type != FSAccessor::Type::tDirectory) {
throw Error(format("path '%1%' inside NAR file is not a directory") %
path);
}
StringSet res;
for (auto& child : i.children) {
@ -187,9 +193,10 @@ struct NarAccessor : public FSAccessor {
std::string readFile(const Path& path) override {
auto i = get(path);
if (i.type != FSAccessor::Type::tRegular)
if (i.type != FSAccessor::Type::tRegular) {
throw Error(format("path '%1%' inside NAR file is not a regular file") %
path);
}
if (getNarBytes) {
return getNarBytes(i.start, i.size);
@ -201,8 +208,9 @@ struct NarAccessor : public FSAccessor {
std::string readLink(const Path& path) override {
auto i = get(path);
if (i.type != FSAccessor::Type::tSymlink)
if (i.type != FSAccessor::Type::tSymlink) {
throw Error(format("path '%1%' inside NAR file is not a symlink") % path);
}
return i.target;
}
};
@ -241,8 +249,9 @@ void listNar(JSONPlaceholder& res, ref<FSAccessor> accessor, const Path& path,
if (recurse) {
auto res3 = res2.placeholder(name);
listNar(res3, accessor, path + "/" + name, true);
} else
} else {
res2.object(name);
}
}
}
break;

View file

@ -76,8 +76,9 @@ class NarInfoDiskCacheImpl : public NarInfoDiskCache {
state->db = SQLite(dbPath);
if (sqlite3_busy_timeout(state->db, 60 * 60 * 1000) != SQLITE_OK)
if (sqlite3_busy_timeout(state->db, 60 * 60 * 1000) != SQLITE_OK) {
throwSQLiteError(state->db, "setting timeout");
}
// We can always reproduce the cache.
state->db.exec("pragma synchronous = off");
@ -224,12 +225,15 @@ class NarInfoDiskCacheImpl : public NarInfoDiskCache {
narInfo->fileSize = queryNAR.getInt(5);
narInfo->narHash = Hash(queryNAR.getStr(6));
narInfo->narSize = queryNAR.getInt(7);
for (auto& r : tokenizeString<Strings>(queryNAR.getStr(8), " "))
for (auto& r : tokenizeString<Strings>(queryNAR.getStr(8), " ")) {
narInfo->references.insert(cache.storeDir + "/" + r);
if (!queryNAR.isNull(9))
}
if (!queryNAR.isNull(9)) {
narInfo->deriver = cache.storeDir + "/" + queryNAR.getStr(9);
for (auto& sig : tokenizeString<Strings>(queryNAR.getStr(10), " "))
}
for (auto& sig : tokenizeString<Strings>(queryNAR.getStr(10), " ")) {
narInfo->sigs.insert(sig);
}
narInfo->ca = queryNAR.getStr(11);
return {oValid, narInfo};

View file

@ -40,19 +40,19 @@ NarInfo::NarInfo(const Store& store, const std::string& s,
corrupt();
}
path = value;
} else if (name == "URL")
} else if (name == "URL") {
url = value;
else if (name == "Compression")
} else if (name == "Compression") {
compression = value;
else if (name == "FileHash")
} else if (name == "FileHash") {
fileHash = parseHashField(value);
else if (name == "FileSize") {
} else if (name == "FileSize") {
if (!string2Int(value, fileSize)) {
corrupt();
}
} else if (name == "NarHash")
} else if (name == "NarHash") {
narHash = parseHashField(value);
else if (name == "NarSize") {
} else if (name == "NarSize") {
if (!string2Int(value, narSize)) {
corrupt();
}
@ -76,11 +76,11 @@ NarInfo::NarInfo(const Store& store, const std::string& s,
}
deriver = p;
}
} else if (name == "System")
} else if (name == "System") {
system = value;
else if (name == "Sig")
} else if (name == "Sig") {
sigs.insert(value);
else if (name == "CA") {
} else if (name == "CA") {
if (!ca.empty()) {
corrupt();
}

View file

@ -17,10 +17,12 @@ namespace nix {
static void makeWritable(const Path& path) {
struct stat st;
if (lstat(path.c_str(), &st))
if (lstat(path.c_str(), &st)) {
throw SysError(format("getting attributes of path '%1%'") % path);
if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
}
if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1) {
throw SysError(format("changing writability of '%1%'") % path);
}
}
struct MakeReadOnly {
@ -98,8 +100,9 @@ void LocalStore::optimisePath_(OptimiseStats& stats, const Path& path,
checkInterrupt();
struct stat st;
if (lstat(path.c_str(), &st))
if (lstat(path.c_str(), &st)) {
throw SysError(format("getting attributes of path '%1%'") % path);
}
#if __APPLE__
/* HFS/macOS has some undocumented security feature disabling hardlinking for
@ -192,8 +195,9 @@ retry:
/* Yes! We've seen a file with the same contents. Replace the
current file with a hard link to that file. */
struct stat stLink;
if (lstat(linkPath.c_str(), &stLink))
if (lstat(linkPath.c_str(), &stLink)) {
throw SysError(format("getting attributes of path '%1%'") % linkPath);
}
if (st.st_ino == stLink.st_ino) {
DLOG(INFO) << path << " is already linked to " << linkPath;

View file

@ -20,40 +20,44 @@ std::optional<std::string> ParsedDerivation::getStringAttr(
const std::string& name) const {
if (structuredAttrs) {
auto i = structuredAttrs->find(name);
if (i == structuredAttrs->end())
if (i == structuredAttrs->end()) {
return {};
else {
if (!i->is_string())
} else {
if (!i->is_string()) {
throw Error("attribute '%s' of derivation '%s' must be a string", name,
drvPath);
}
return i->get<std::string>();
}
} else {
auto i = drv.env.find(name);
if (i == drv.env.end())
if (i == drv.env.end()) {
return {};
else
} else {
return i->second;
}
}
}
bool ParsedDerivation::getBoolAttr(const std::string& name, bool def) const {
if (structuredAttrs) {
auto i = structuredAttrs->find(name);
if (i == structuredAttrs->end())
if (i == structuredAttrs->end()) {
return def;
else {
if (!i->is_boolean())
} else {
if (!i->is_boolean()) {
throw Error("attribute '%s' of derivation '%s' must be a Boolean", name,
drvPath);
}
return i->get<bool>();
}
} else {
auto i = drv.env.find(name);
if (i == drv.env.end())
if (i == drv.env.end()) {
return def;
else
} else {
return i->second == "1";
}
}
}
@ -61,48 +65,54 @@ std::optional<Strings> ParsedDerivation::getStringsAttr(
const std::string& name) const {
if (structuredAttrs) {
auto i = structuredAttrs->find(name);
if (i == structuredAttrs->end())
if (i == structuredAttrs->end()) {
return {};
else {
if (!i->is_array())
} else {
if (!i->is_array()) {
throw Error(
"attribute '%s' of derivation '%s' must be a list of strings", name,
drvPath);
}
Strings res;
for (auto j = i->begin(); j != i->end(); ++j) {
if (!j->is_string())
if (!j->is_string()) {
throw Error(
"attribute '%s' of derivation '%s' must be a list of strings",
name, drvPath);
}
res.push_back(j->get<std::string>());
}
return res;
}
} else {
auto i = drv.env.find(name);
if (i == drv.env.end())
if (i == drv.env.end()) {
return {};
else
} else {
return tokenizeString<Strings>(i->second);
}
}
}
StringSet ParsedDerivation::getRequiredSystemFeatures() const {
StringSet res;
for (auto& i : getStringsAttr("requiredSystemFeatures").value_or(Strings()))
for (auto& i : getStringsAttr("requiredSystemFeatures").value_or(Strings())) {
res.insert(i);
}
return res;
}
bool ParsedDerivation::canBuildLocally() const {
if (drv.platform != settings.thisSystem.get() &&
!settings.extraPlatforms.get().count(drv.platform) && !drv.isBuiltin())
!settings.extraPlatforms.get().count(drv.platform) && !drv.isBuiltin()) {
return false;
}
for (auto& feature : getRequiredSystemFeatures())
for (auto& feature : getRequiredSystemFeatures()) {
if (!settings.systemFeatures.get().count(feature)) {
return false;
}
}
return true;
}

View file

@ -18,8 +18,9 @@ AutoCloseFD openLockFile(const Path& path, bool create) {
AutoCloseFD fd;
fd = open(path.c_str(), O_CLOEXEC | O_RDWR | (create ? O_CREAT : 0), 0600);
if (!fd && (create || errno != ENOENT))
if (!fd && (create || errno != ENOENT)) {
throw SysError(format("opening lock file '%1%'") % path);
}
return fd;
}
@ -37,22 +38,24 @@ void deleteLockFile(const Path& path, int fd) {
bool lockFile(int fd, LockType lockType, bool wait) {
int type;
if (lockType == ltRead)
if (lockType == ltRead) {
type = LOCK_SH;
else if (lockType == ltWrite)
} else if (lockType == ltWrite) {
type = LOCK_EX;
else if (lockType == ltNone)
} else if (lockType == ltNone) {
type = LOCK_UN;
else
} else {
abort();
}
if (wait) {
while (flock(fd, type) != 0) {
checkInterrupt();
if (errno != EINTR)
if (errno != EINTR) {
throw SysError(format("acquiring/releasing lock"));
else
} else {
return false;
}
}
} else {
while (flock(fd, type | LOCK_NB) != 0) {
@ -118,16 +121,18 @@ bool PathLocks::lockPaths(const PathSet& paths, const string& waitMsg,
/* Check that the lock file hasn't become stale (i.e.,
hasn't been unlinked). */
struct stat st;
if (fstat(fd.get(), &st) == -1)
if (fstat(fd.get(), &st) == -1) {
throw SysError(format("statting lock file '%1%'") % lockPath);
if (st.st_size != 0)
}
if (st.st_size != 0) {
/* This lock file has been unlinked, so we're holding
a lock on a deleted file. This means that other
processes may create and acquire a lock on
`lockPath', and proceed. So we must retry. */
DLOG(INFO) << "open lock file '" << lockPath << "' has become stale";
else
} else {
break;
}
}
/* Use borrow so that the descriptor isn't closed. */

View file

@ -28,10 +28,11 @@ static int parseName(const string& profileName, const string& name) {
return -1;
}
int n;
if (string2Int(string(s, 0, p), n) && n >= 0)
if (string2Int(string(s, 0, p), n) && n >= 0) {
return n;
else
} else {
return -1;
}
}
Generations findGenerations(Path profile, int& curGen) {
@ -47,8 +48,9 @@ Generations findGenerations(Path profile, int& curGen) {
gen.path = profileDir + "/" + i.name;
gen.number = n;
struct stat st;
if (lstat(gen.path.c_str(), &st) != 0)
if (lstat(gen.path.c_str(), &st) != 0) {
throw SysError(format("statting '%1%'") % gen.path);
}
gen.creationTime = st.st_mtime;
gens.push_back(gen);
}
@ -105,8 +107,9 @@ Path createGeneration(ref<LocalFSStore> store, Path profile, Path outPath) {
}
static void removeFile(const Path& path) {
if (remove(path.c_str()) == -1)
if (remove(path.c_str()) == -1) {
throw SysError(format("cannot unlink '%1%'") % path);
}
}
void deleteGeneration(const Path& profile, unsigned int gen) {
@ -134,9 +137,10 @@ void deleteGenerations(const Path& profile,
int curGen;
Generations gens = findGenerations(profile, curGen);
if (gensToDelete.find(curGen) != gensToDelete.end())
if (gensToDelete.find(curGen) != gensToDelete.end()) {
throw Error(format("cannot delete current generation of profile %1%'") %
profile);
}
for (auto& i : gens) {
if (gensToDelete.find(i.number) == gensToDelete.end()) {
@ -176,10 +180,11 @@ void deleteOldGenerations(const Path& profile, bool dryRun) {
int curGen;
Generations gens = findGenerations(profile, curGen);
for (auto& i : gens)
for (auto& i : gens) {
if (i.number != curGen) {
deleteGeneration2(profile, i.number, dryRun);
}
}
}
void deleteGenerationsOlderThan(const Path& profile, time_t t, bool dryRun) {
@ -190,7 +195,7 @@ void deleteGenerationsOlderThan(const Path& profile, time_t t, bool dryRun) {
Generations gens = findGenerations(profile, curGen);
bool canDelete = false;
for (auto i = gens.rbegin(); i != gens.rend(); ++i)
for (auto i = gens.rbegin(); i != gens.rend(); ++i) {
if (canDelete) {
assert(i->creationTime < t);
if (i->number != curGen) {
@ -203,6 +208,7 @@ void deleteGenerationsOlderThan(const Path& profile, time_t t, bool dryRun) {
time. */
canDelete = true;
}
}
}
void deleteGenerationsOlderThan(const Path& profile, const string& timeSpec,
@ -211,8 +217,9 @@ void deleteGenerationsOlderThan(const Path& profile, const string& timeSpec,
string strDays = string(timeSpec, 0, timeSpec.size() - 1);
int days;
if (!string2Int(strDays, days) || days < 1)
if (!string2Int(strDays, days) || days < 1) {
throw Error(format("invalid number of days specifier '%1%'") % timeSpec);
}
time_t oldTime = curTime - days * 24 * 3600;

View file

@ -21,20 +21,22 @@ static void search(const unsigned char* s, size_t len, StringSet& hashes,
for (unsigned int i = 0; i < 256; ++i) {
isBase32[i] = false;
}
for (unsigned int i = 0; i < base32Chars.size(); ++i)
for (unsigned int i = 0; i < base32Chars.size(); ++i) {
isBase32[(unsigned char)base32Chars[i]] = true;
}
initialised = true;
}
for (size_t i = 0; i + refLength <= len;) {
int j;
bool match = true;
for (j = refLength - 1; j >= 0; --j)
for (j = refLength - 1; j >= 0; --j) {
if (!isBase32[(unsigned char)s[i + j]]) {
i += j + 1;
match = false;
break;
}
}
if (!match) {
continue;
}

View file

@ -48,9 +48,10 @@ std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path& path_) {
auto storePath = store->toStorePath(path);
std::string restPath = std::string(path, storePath.size());
if (!store->isValidPath(storePath))
if (!store->isValidPath(storePath)) {
throw InvalidPath(format("path '%1%' is not a valid store path") %
storePath);
}
auto i = nars.find(storePath);
if (i != nars.end()) {
@ -73,8 +74,9 @@ std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path& path_) {
throw SysError("opening NAR cache file '%s'", cacheFile);
}
if (lseek(fd.get(), offset, SEEK_SET) != (off_t)offset)
if (lseek(fd.get(), offset, SEEK_SET) != (off_t)offset) {
throw SysError("seeking in '%s'", cacheFile);
}
std::string buf(length, 0);
readFull(fd.get(), (unsigned char*)buf.data(), length);

View file

@ -57,9 +57,10 @@ RemoteStore::RemoteStore(const Params& params)
})) {}
ref<RemoteStore::Connection> RemoteStore::openConnectionWrapper() {
if (failed)
if (failed) {
throw Error("opening a connection to remote store '%s' previously failed",
getUri());
}
try {
return openConnection();
} catch (...) {
@ -105,12 +106,14 @@ ref<RemoteStore::Connection> UDSRemoteStore::openConnection() {
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
if (socketPath.size() + 1 >= sizeof(addr.sun_path))
if (socketPath.size() + 1 >= sizeof(addr.sun_path)) {
throw Error(format("socket path '%1%' is too long") % socketPath);
}
strcpy(addr.sun_path, socketPath.c_str());
if (::connect(conn->fd.get(), (struct sockaddr*)&addr, sizeof(addr)) == -1)
if (::connect(conn->fd.get(), (struct sockaddr*)&addr, sizeof(addr)) == -1) {
throw SysError(format("cannot connect to daemon at '%1%'") % socketPath);
}
conn->from.fd = conn->fd.get();
conn->to.fd = conn->fd.get();
@ -134,18 +137,21 @@ void RemoteStore::initConnection(Connection& conn) {
conn.from >> conn.daemonVersion;
if (GET_PROTOCOL_MAJOR(conn.daemonVersion) !=
GET_PROTOCOL_MAJOR(PROTOCOL_VERSION))
GET_PROTOCOL_MAJOR(PROTOCOL_VERSION)) {
throw Error("Nix daemon protocol version not supported");
if (GET_PROTOCOL_MINOR(conn.daemonVersion) < 10)
}
if (GET_PROTOCOL_MINOR(conn.daemonVersion) < 10) {
throw Error("the Nix daemon version is too old");
}
conn.to << PROTOCOL_VERSION;
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 14) {
int cpu = sameMachine() && settings.lockCPU ? lockToCurrentCPU() : -1;
if (cpu != -1)
if (cpu != -1) {
conn.to << 1 << cpu;
else
} else {
conn.to << 0;
}
}
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 11) {
@ -249,10 +255,11 @@ PathSet RemoteStore::queryValidPaths(const PathSet& paths,
auto conn(getConnection());
if (GET_PROTOCOL_MINOR(conn->daemonVersion) < 12) {
PathSet res;
for (auto& i : paths)
for (auto& i : paths) {
if (isValidPath(i)) {
res.insert(i);
}
}
return res;
} else {
conn->to << wopQueryValidPaths << paths;
@ -344,8 +351,9 @@ void RemoteStore::queryPathInfoUncached(
conn.processStderr();
} catch (Error& e) {
// Ugly backwards compatibility hack.
if (e.msg().find("is not valid") != std::string::npos)
if (e.msg().find("is not valid") != std::string::npos) {
throw InvalidPath(e.what());
}
throw;
}
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 17) {
@ -456,9 +464,10 @@ void RemoteStore::addToStore(const ValidPathInfo& info, Source& source,
Path RemoteStore::addToStore(const string& name, const Path& _srcPath,
bool recursive, HashType hashAlgo,
PathFilter& filter, RepairFlag repair) {
if (repair)
if (repair) {
throw Error(
"repairing is not supported when building through the Nix daemon");
}
auto conn(getConnection());
@ -483,10 +492,12 @@ Path RemoteStore::addToStore(const string& name, const Path& _srcPath,
} catch (SysError& e) {
/* Daemon closed while we were sending the path. Probably OOM
or I/O error. */
if (e.errNo == EPIPE) try {
if (e.errNo == EPIPE) {
try {
conn.processStderr();
} catch (EndOfFile& e) {
}
}
throw;
}
@ -495,9 +506,10 @@ Path RemoteStore::addToStore(const string& name, const Path& _srcPath,
Path RemoteStore::addTextToStore(const string& name, const string& s,
const PathSet& references, RepairFlag repair) {
if (repair)
if (repair) {
throw Error(
"repairing is not supported when building through the Nix daemon");
}
auto conn(getConnection());
conn->to << wopAddTextToStore << name << s << references;
@ -511,15 +523,16 @@ void RemoteStore::buildPaths(const PathSet& drvPaths, BuildMode buildMode) {
conn->to << wopBuildPaths;
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 13) {
conn->to << drvPaths;
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 15)
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 15) {
conn->to << buildMode;
else
} else
/* Old daemons did not take a 'buildMode' parameter, so we
need to validate it here on the client side. */
if (buildMode != bmNormal)
if (buildMode != bmNormal) {
throw Error(
"repairing or checking is not supported when building through the "
"Nix daemon");
}
} else {
/* For backwards compatibility with old daemons, strip output
identifiers. */

View file

@ -31,8 +31,9 @@ namespace nix {
SQLite::SQLite(const Path& path) {
if (sqlite3_open_v2(path.c_str(), &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
0) != SQLITE_OK)
0) != SQLITE_OK) {
throw Error(format("cannot open SQLite database '%s'") % path);
}
}
SQLite::~SQLite() {
@ -47,24 +48,27 @@ SQLite::~SQLite() {
void SQLite::exec(const std::string& stmt) {
retrySQLite<void>([&]() {
if (sqlite3_exec(db, stmt.c_str(), 0, 0, 0) != SQLITE_OK)
if (sqlite3_exec(db, stmt.c_str(), 0, 0, 0) != SQLITE_OK) {
throwSQLiteError(db, format("executing SQLite statement '%s'") % stmt);
}
});
}
void SQLiteStmt::create(sqlite3* db, const string& sql) {
checkInterrupt();
assert(!stmt);
if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, 0) != SQLITE_OK)
if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, 0) != SQLITE_OK) {
throwSQLiteError(db, fmt("creating statement '%s'", sql));
}
this->db = db;
this->sql = sql;
}
SQLiteStmt::~SQLiteStmt() {
try {
if (stmt && sqlite3_finalize(stmt) != SQLITE_OK)
if (stmt && sqlite3_finalize(stmt) != SQLITE_OK) {
throwSQLiteError(db, fmt("finalizing statement '%s'", sql));
}
} catch (...) {
ignoreException();
}
@ -83,8 +87,9 @@ SQLiteStmt::Use& SQLiteStmt::Use::operator()(const std::string& value,
bool notNull) {
if (notNull) {
if (sqlite3_bind_text(stmt, curArg++, value.c_str(), -1,
SQLITE_TRANSIENT) != SQLITE_OK)
SQLITE_TRANSIENT) != SQLITE_OK) {
throwSQLiteError(stmt.db, "binding argument");
}
} else {
bind();
}
@ -93,8 +98,9 @@ SQLiteStmt::Use& SQLiteStmt::Use::operator()(const std::string& value,
SQLiteStmt::Use& SQLiteStmt::Use::operator()(int64_t value, bool notNull) {
if (notNull) {
if (sqlite3_bind_int64(stmt, curArg++, value) != SQLITE_OK)
if (sqlite3_bind_int64(stmt, curArg++, value) != SQLITE_OK) {
throwSQLiteError(stmt.db, "binding argument");
}
} else {
bind();
}
@ -113,14 +119,16 @@ int SQLiteStmt::Use::step() { return sqlite3_step(stmt); }
void SQLiteStmt::Use::exec() {
int r = step();
assert(r != SQLITE_ROW);
if (r != SQLITE_DONE)
if (r != SQLITE_DONE) {
throwSQLiteError(stmt.db, fmt("executing SQLite statement '%s'", stmt.sql));
}
}
bool SQLiteStmt::Use::next() {
int r = step();
if (r != SQLITE_DONE && r != SQLITE_ROW)
if (r != SQLITE_DONE && r != SQLITE_ROW) {
throwSQLiteError(stmt.db, fmt("executing SQLite query '%s'", stmt.sql));
}
return r == SQLITE_ROW;
}

View file

@ -10,13 +10,15 @@ SSHMaster::SSHMaster(const std::string& host, const std::string& keyFile,
useMaster(useMaster && !fakeSSH),
compress(compress),
logFD(logFD) {
if (host == "" || hasPrefix(host, "-"))
if (host == "" || hasPrefix(host, "-")) {
throw Error("invalid SSH host name '%s'", host);
}
}
void SSHMaster::addCommonSSHOpts(Strings& args) {
for (auto& i : tokenizeString<Strings>(getEnv("NIX_SSHOPTS")))
for (auto& i : tokenizeString<Strings>(getEnv("NIX_SSHOPTS"))) {
args.push_back(i);
}
if (!keyFile.empty()) {
args.insert(args.end(), {"-i", keyFile});
}
@ -44,12 +46,15 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(
close(in.writeSide.get());
close(out.readSide.get());
if (dup2(in.readSide.get(), STDIN_FILENO) == -1)
if (dup2(in.readSide.get(), STDIN_FILENO) == -1) {
throw SysError("duping over stdin");
if (dup2(out.writeSide.get(), STDOUT_FILENO) == -1)
}
if (dup2(out.writeSide.get(), STDOUT_FILENO) == -1) {
throw SysError("duping over stdout");
if (logFD != -1 && dup2(logFD, STDERR_FILENO) == -1)
}
if (logFD != -1 && dup2(logFD, STDERR_FILENO) == -1) {
throw SysError("duping over stderr");
}
Strings args;
@ -112,8 +117,9 @@ Path SSHMaster::startMaster() {
close(out.readSide.get());
if (dup2(out.writeSide.get(), STDOUT_FILENO) == -1)
if (dup2(out.writeSide.get(), STDOUT_FILENO) == -1) {
throw SysError("duping over stdout");
}
Strings args = {"ssh", host.c_str(),
"-M", "-N",
@ -136,8 +142,9 @@ Path SSHMaster::startMaster() {
} catch (EndOfFile& e) {
}
if (reply != "started")
if (reply != "started") {
throw Error("failed to start SSH master connection to '%s'", host);
}
return state->socketPath;
}

View file

@ -25,18 +25,21 @@ bool Store::isStorePath(const Path& path) const {
}
void Store::assertStorePath(const Path& path) const {
if (!isStorePath(path))
if (!isStorePath(path)) {
throw Error(format("path '%1%' is not in the Nix store") % path);
}
}
Path Store::toStorePath(const Path& path) const {
if (!isInStore(path))
if (!isInStore(path)) {
throw Error(format("path '%1%' is not in the Nix store") % path);
}
Path::size_type slash = path.find('/', storeDir.size() + 1);
if (slash == Path::npos)
if (slash == Path::npos) {
return path;
else
} else {
return Path(path, 0, slash);
}
}
Path Store::followLinksToStore(const Path& _path) const {
@ -48,8 +51,9 @@ Path Store::followLinksToStore(const Path& _path) const {
string target = readLink(path);
path = absPath(target, dirOf(path));
}
if (!isInStore(path))
if (!isInStore(path)) {
throw Error(format("path '%1%' is not in the Nix store") % path);
}
return path;
}
@ -86,17 +90,20 @@ void checkStoreName(const string& name) {
/* Disallow names starting with a dot for possible security
reasons (e.g., "." and ".."). */
if (string(name, 0, 1) == ".")
if (string(name, 0, 1) == ".") {
throw Error(baseError % "it is illegal to start the name with a period");
}
/* Disallow names longer than 211 characters. ext4s max is 256,
but we need extra space for the hash and .chroot extensions. */
if (name.length() > 211)
if (name.length() > 211) {
throw Error(baseError % "name must be less than 212 characters");
for (auto& i : name)
}
for (auto& i : name) {
if (!((i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z') ||
(i >= '0' && i <= '9') || validChars.find(i) != string::npos)) {
throw Error(baseError % (format("the '%1%' character is invalid") % i));
}
}
}
/* Store paths have the following form:
@ -261,9 +268,10 @@ bool Store::isValidPath(const Path& storePath) {
bool valid = isValidPathUncached(storePath);
if (diskCache && !valid)
if (diskCache && !valid) {
// FIXME: handle valid = true case.
diskCache->upsertNarInfo(getUri(), hashPart, 0);
}
return valid;
}
@ -306,8 +314,9 @@ void Store::queryPathInfo(const Path& storePath,
auto res = state.lock()->pathInfoCache.get(hashPart);
if (res) {
stats.narInfoReadAverted++;
if (!*res)
if (!*res) {
throw InvalidPath(format("path '%s' is not valid") % storePath);
}
return callback(ref<ValidPathInfo>(*res));
}
}
@ -323,8 +332,9 @@ void Store::queryPathInfo(const Path& storePath,
res.first == NarInfoDiskCache::oInvalid ? 0 : res.second);
if (res.first == NarInfoDiskCache::oInvalid ||
(res.second->path != storePath &&
storePathToName(storePath) != ""))
storePathToName(storePath) != "")) {
throw InvalidPath(format("path '%s' is not valid") % storePath);
}
}
return callback(ref<ValidPathInfo>(res.second));
}
@ -483,8 +493,9 @@ void Store::pathInfoToJSON(JSONPlaceholder& jsonOut, const PathSet& storePaths,
jsonPath.attr("deriver", info->deriver);
}
if (info->registrationTime)
if (info->registrationTime) {
jsonPath.attr("registrationTime", info->registrationTime);
}
if (info->ultimate) {
jsonPath.attr("ultimate", info->ultimate);
@ -504,12 +515,15 @@ void Store::pathInfoToJSON(JSONPlaceholder& jsonOut, const PathSet& storePaths,
if (!narInfo->url.empty()) {
jsonPath.attr("url", narInfo->url);
}
if (narInfo->fileHash)
if (narInfo->fileHash) {
jsonPath.attr("downloadHash", narInfo->fileHash.to_string());
if (narInfo->fileSize)
}
if (narInfo->fileSize) {
jsonPath.attr("downloadSize", narInfo->fileSize);
if (showClosureSize)
}
if (showClosureSize) {
jsonPath.attr("closureDownloadSize", closureSizes.second);
}
}
}
@ -544,10 +558,11 @@ const Store::Stats& Store::getStats() {
}
void Store::buildPaths(const PathSet& paths, BuildMode buildMode) {
for (auto& path : paths)
for (auto& path : paths) {
if (isDerivation(path)) {
unsupported("buildPaths");
}
}
if (queryValidPaths(paths).size() != paths.size()) {
unsupported("buildPaths");
@ -621,10 +636,11 @@ void copyPaths(ref<Store> srcStore, ref<Store> dstStore,
PathSet valid = dstStore->queryValidPaths(storePaths, substitute);
PathSet missing;
for (auto& path : storePaths)
for (auto& path : storePaths) {
if (!valid.count(path)) {
missing.insert(path);
}
}
if (missing.empty()) {
return;
@ -729,10 +745,11 @@ string showPaths(const PathSet& paths) {
}
std::string ValidPathInfo::fingerprint() const {
if (narSize == 0 || !narHash)
if (narSize == 0 || !narHash) {
throw Error(format("cannot calculate fingerprint of path '%s' because its "
"size/hash is not known") %
path);
}
return "1;" + path + ";" + narHash.to_string(Base32) + ";" +
std::to_string(narSize) + ";" + concatStringsSep(",", references);
}
@ -749,10 +766,11 @@ bool ValidPathInfo::isContentAddressed(const Store& store) const {
if (hasPrefix(ca, "text:")) {
Hash hash(std::string(ca, 5));
if (store.makeTextPath(storePathToName(path), hash, references) == path)
if (store.makeTextPath(storePathToName(path), hash, references) == path) {
return true;
else
} else {
warn();
}
}
else if (hasPrefix(ca, "fixed:")) {
@ -760,10 +778,11 @@ bool ValidPathInfo::isContentAddressed(const Store& store) const {
Hash hash(std::string(ca, recursive ? 8 : 6));
if (references.empty() &&
store.makeFixedOutputPath(recursive, hash, storePathToName(path)) ==
path)
path) {
return true;
else
} else {
warn();
}
}
return false;
@ -776,10 +795,11 @@ size_t ValidPathInfo::checkSignatures(const Store& store,
}
size_t good = 0;
for (auto& sig : sigs)
for (auto& sig : sigs) {
if (checkSignature(publicKeys, sig)) {
good++;
}
}
return good;
}
@ -838,16 +858,18 @@ std::pair<std::string, Store::Params> splitUriAndParams(
std::string decoded;
for (size_t i = 0; i < value.size();) {
if (value[i] == '%') {
if (i + 2 >= value.size())
if (i + 2 >= value.size()) {
throw Error("invalid URI parameter '%s'", value);
}
try {
decoded += std::stoul(std::string(value, i + 1, 2), 0, 16);
i += 3;
} catch (...) {
throw Error("invalid URI parameter '%s'", value);
}
} else
} else {
decoded += value[i++];
}
}
params[s.substr(0, e)] = decoded;
}
@ -880,9 +902,9 @@ StoreType getStoreType(const std::string& uri, const std::string& stateDir) {
} else if (uri == "local" || hasPrefix(uri, "/")) {
return tLocal;
} else if (uri == "" || uri == "auto") {
if (access(stateDir.c_str(), R_OK | W_OK) == 0)
if (access(stateDir.c_str(), R_OK | W_OK) == 0) {
return tLocal;
else if (pathExists(settings.nixDaemonSocketFile)) {
} else if (pathExists(settings.nixDaemonSocketFile)) {
return tDaemon;
} else {
return tLocal;

View file

@ -76,9 +76,10 @@ static void dump(const Path& path, Sink& sink, PathFilter& filter) {
if (S_ISREG(st.st_mode)) {
sink << "type"
<< "regular";
if (st.st_mode & S_IXUSR)
if (st.st_mode & S_IXUSR) {
sink << "executable"
<< "";
}
dumpContents(path, (size_t)st.st_size, sink);
}
@ -89,7 +90,7 @@ static void dump(const Path& path, Sink& sink, PathFilter& filter) {
/* If we're on a case-insensitive system like macOS, undo
the case hack applied by restorePath(). */
std::map<string, string> unhacked;
for (auto& i : readDirectory(path))
for (auto& i : readDirectory(path)) {
if (archiveSettings.useCaseHack) {
string name(i.name);
size_t pos = i.name.find(caseHackSuffix);
@ -99,14 +100,17 @@ static void dump(const Path& path, Sink& sink, PathFilter& filter) {
name.erase(pos);
}
if (unhacked.find(name) != unhacked.end())
if (unhacked.find(name) != unhacked.end()) {
throw Error(format("file name collision in between '%1%' and '%2%'") %
(path + "/" + unhacked[name]) % (path + "/" + i.name));
}
unhacked[name] = i.name;
} else
} else {
unhacked[i.name] = i.name;
}
}
for (auto& i : unhacked)
for (auto& i : unhacked) {
if (filter(path + "/" + i.first)) {
sink << "entry"
<< "("
@ -114,15 +118,17 @@ static void dump(const Path& path, Sink& sink, PathFilter& filter) {
dump(path + "/" + i.second, sink, filter);
sink << ")";
}
}
}
else if (S_ISLNK(st.st_mode))
else if (S_ISLNK(st.st_mode)) {
sink << "type"
<< "symlink"
<< "target" << readLink(path);
else
} else {
throw Error(format("file '%1%' has an unsupported type") % path);
}
sink << ")";
}
@ -222,8 +228,9 @@ static void parse(ParseSink& sink, Source& source, const Path& path) {
type = tpSymlink;
}
else
else {
throw badArchive("unknown file type " + t);
}
}
@ -258,8 +265,9 @@ static void parse(ParseSink& sink, Source& source, const Path& path) {
name = readString(source);
if (name.empty() || name == "." || name == ".." ||
name.find('/') != string::npos ||
name.find((char)0) != string::npos)
name.find((char)0) != string::npos) {
throw Error(format("NAR contains invalid file name '%1%'") % name);
}
if (name <= prevName) {
throw Error("NAR directory is not sorted");
}
@ -271,16 +279,18 @@ static void parse(ParseSink& sink, Source& source, const Path& path) {
<< name << "'";
name += caseHackSuffix;
name += std::to_string(++i->second);
} else
} else {
names[name] = 0;
}
}
} else if (s == "node") {
if (s.empty()) {
throw badArchive("entry name missing");
}
parse(sink, source, path + "/" + name);
} else
} else {
throw badArchive("unknown field " + s);
}
}
}
@ -289,8 +299,9 @@ static void parse(ParseSink& sink, Source& source, const Path& path) {
sink.createSymlink(path, target);
}
else
else {
throw badArchive("unknown field " + s);
}
}
}
@ -302,8 +313,9 @@ void parseDump(ParseSink& sink, Source& source) {
/* This generally means the integer at the start couldn't be
decoded. Ignore and throw the exception below. */
}
if (version != narVersionMagic1)
if (version != narVersionMagic1) {
throw badArchive("input doesn't look like a Nix archive");
}
parse(sink, source, "");
}
@ -313,8 +325,9 @@ struct RestoreSink : ParseSink {
void createDirectory(const Path& path) {
Path p = dstPath + path;
if (mkdir(p.c_str(), 0777) == -1)
if (mkdir(p.c_str(), 0777) == -1) {
throw SysError(format("creating directory '%1%'") % p);
}
};
void createRegularFile(const Path& path) {
@ -330,8 +343,9 @@ struct RestoreSink : ParseSink {
if (fstat(fd.get(), &st) == -1) {
throw SysError("fstat");
}
if (fchmod(fd.get(), st.st_mode | (S_IXUSR | S_IXGRP | S_IXOTH)) == -1)
if (fchmod(fd.get(), st.st_mode | (S_IXUSR | S_IXGRP | S_IXOTH)) == -1) {
throw SysError("fchmod");
}
}
void preallocateContents(unsigned long long len) {
@ -342,8 +356,9 @@ struct RestoreSink : ParseSink {
filesystem doesn't support preallocation (e.g. on
OpenSolaris). Since preallocation is just an
optimisation, ignore it. */
if (errno && errno != EINVAL && errno != EOPNOTSUPP && errno != ENOSYS)
if (errno && errno != EINVAL && errno != EOPNOTSUPP && errno != ENOSYS) {
throw SysError(format("preallocating file of %1% bytes") % len);
}
}
#endif
}

View file

@ -30,13 +30,14 @@ void Args::parseCmdline(const Strings& _cmdline) {
*pos = (string) "-" + arg[1];
auto next = pos;
++next;
for (unsigned int j = 2; j < arg.length(); j++)
if (isalpha(arg[j]))
for (unsigned int j = 2; j < arg.length(); j++) {
if (isalpha(arg[j])) {
cmdline.insert(next, (string) "-" + arg[j]);
else {
} else {
cmdline.insert(next, string(arg, j));
break;
}
}
arg = *pos;
}
@ -44,8 +45,9 @@ void Args::parseCmdline(const Strings& _cmdline) {
dashDash = true;
++pos;
} else if (!dashDash && std::string(arg, 0, 1) == "-") {
if (!processFlag(pos, cmdline.end()))
if (!processFlag(pos, cmdline.end())) {
throw UsageError(format("unrecognised flag '%1%'") % arg);
}
} else {
pendingArgs.push_back(*pos++);
if (processArgs(pendingArgs, false)) {
@ -141,8 +143,9 @@ bool Args::processFlag(Strings::iterator& pos, Strings::iterator end) {
bool Args::processArgs(const Strings& args, bool finish) {
if (expectedArgs.empty()) {
if (!args.empty())
if (!args.empty()) {
throw UsageError(format("unexpected argument '%1%'") % args.front());
}
return true;
}
@ -161,8 +164,9 @@ bool Args::processArgs(const Strings& args, bool finish) {
res = true;
}
if (finish && !expectedArgs.empty() && !expectedArgs.front().optional)
if (finish && !expectedArgs.empty() && !expectedArgs.front().optional) {
throw UsageError("more arguments are required");
}
return res;
}
@ -184,7 +188,9 @@ Strings argvToStrings(int argc, char** argv) {
Strings args;
argc--;
argv++;
while (argc--) args.push_back(*argv++);
while (argc--) {
args.push_back(*argv++);
}
return args;
}

View file

@ -49,8 +49,9 @@ struct XzDecompressionSink : CompressionSink {
XzDecompressionSink(Sink& nextSink) : nextSink(nextSink) {
lzma_ret ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
if (ret != LZMA_OK)
if (ret != LZMA_OK) {
throw CompressionError("unable to initialise lzma decoder");
}
strm.next_out = outbuf;
strm.avail_out = sizeof(outbuf);
@ -71,8 +72,9 @@ struct XzDecompressionSink : CompressionSink {
checkInterrupt();
lzma_ret ret = lzma_code(&strm, data ? LZMA_RUN : LZMA_FINISH);
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
throw CompressionError("error %d while decompressing xz file", ret);
}
finished = ret == LZMA_STREAM_END;
@ -93,8 +95,9 @@ struct BzipDecompressionSink : ChunkedCompressionSink {
BzipDecompressionSink(Sink& nextSink) : nextSink(nextSink) {
memset(&strm, 0, sizeof(strm));
int ret = BZ2_bzDecompressInit(&strm, 0, 0);
if (ret != BZ_OK)
if (ret != BZ_OK) {
throw CompressionError("unable to initialise bzip2 decoder");
}
strm.next_out = (char*)outbuf;
strm.avail_out = sizeof(outbuf);
@ -117,8 +120,9 @@ struct BzipDecompressionSink : ChunkedCompressionSink {
checkInterrupt();
int ret = BZ2_bzDecompress(&strm);
if (ret != BZ_OK && ret != BZ_STREAM_END)
if (ret != BZ_OK && ret != BZ_STREAM_END) {
throw CompressionError("error while decompressing bzip2 file");
}
finished = ret == BZ_STREAM_END;
@ -160,8 +164,9 @@ struct BrotliDecompressionSink : ChunkedCompressionSink {
checkInterrupt();
if (!BrotliDecoderDecompressStream(state, &avail_in, &next_in, &avail_out,
&next_out, nullptr))
&next_out, nullptr)) {
throw CompressionError("error while decompressing brotli file");
}
if (avail_out < sizeof(outbuf) || avail_in == 0) {
nextSink(outbuf, sizeof(outbuf) - avail_out);
@ -184,16 +189,17 @@ ref<std::string> decompress(const std::string& method, const std::string& in) {
ref<CompressionSink> makeDecompressionSink(const std::string& method,
Sink& nextSink) {
if (method == "none" || method == "")
if (method == "none" || method == "") {
return make_ref<NoneSink>(nextSink);
else if (method == "xz")
} else if (method == "xz") {
return make_ref<XzDecompressionSink>(nextSink);
else if (method == "bzip2")
} else if (method == "bzip2") {
return make_ref<BzipDecompressionSink>(nextSink);
else if (method == "br")
} else if (method == "br") {
return make_ref<BrotliDecompressionSink>(nextSink);
else
} else {
throw UnknownCompressionMethod("unknown compression method '%s'", method);
}
}
struct XzCompressionSink : CompressionSink {
@ -258,8 +264,9 @@ struct XzCompressionSink : CompressionSink {
checkInterrupt();
lzma_ret ret = lzma_code(&strm, data ? LZMA_RUN : LZMA_FINISH);
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
throw CompressionError("error %d while compressing xz file", ret);
}
finished = ret == LZMA_STREAM_END;
@ -280,8 +287,9 @@ struct BzipCompressionSink : ChunkedCompressionSink {
BzipCompressionSink(Sink& nextSink) : nextSink(nextSink) {
memset(&strm, 0, sizeof(strm));
int ret = BZ2_bzCompressInit(&strm, 9, 0, 30);
if (ret != BZ_OK)
if (ret != BZ_OK) {
throw CompressionError("unable to initialise bzip2 encoder");
}
strm.next_out = (char*)outbuf;
strm.avail_out = sizeof(outbuf);
@ -304,8 +312,9 @@ struct BzipCompressionSink : ChunkedCompressionSink {
checkInterrupt();
int ret = BZ2_bzCompress(&strm, data ? BZ_RUN : BZ_FINISH);
if (ret != BZ_RUN_OK && ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
if (ret != BZ_RUN_OK && ret != BZ_FINISH_OK && ret != BZ_STREAM_END) {
throw CompressionError("error %d while compressing bzip2 file", ret);
}
finished = ret == BZ_STREAM_END;
@ -349,8 +358,9 @@ struct BrotliCompressionSink : ChunkedCompressionSink {
if (!BrotliEncoderCompressStream(
state, data ? BROTLI_OPERATION_PROCESS : BROTLI_OPERATION_FINISH,
&avail_in, &next_in, &avail_out, &next_out, nullptr))
&avail_in, &next_in, &avail_out, &next_out, nullptr)) {
throw CompressionError("error while compressing brotli compression");
}
if (avail_out < sizeof(outbuf) || avail_in == 0) {
nextSink(outbuf, sizeof(outbuf) - avail_out);
@ -365,17 +375,18 @@ struct BrotliCompressionSink : ChunkedCompressionSink {
ref<CompressionSink> makeCompressionSink(const std::string& method,
Sink& nextSink, const bool parallel) {
if (method == "none")
if (method == "none") {
return make_ref<NoneSink>(nextSink);
else if (method == "xz")
} else if (method == "xz") {
return make_ref<XzCompressionSink>(nextSink, parallel);
else if (method == "bzip2")
} else if (method == "bzip2") {
return make_ref<BzipCompressionSink>(nextSink);
else if (method == "br")
} else if (method == "br") {
return make_ref<BrotliCompressionSink>(nextSink);
else
} else {
throw UnknownCompressionMethod(format("unknown compression method '%s'") %
method);
}
}
ref<std::string> compress(const std::string& method, const std::string& in,

View file

@ -21,8 +21,9 @@ bool Config::set(const std::string& name, const std::string& value) {
void Config::addSetting(AbstractSetting* setting) {
_settings.emplace(setting->name, Config::SettingData(false, setting));
for (auto& alias : setting->aliases)
for (auto& alias : setting->aliases) {
_settings.emplace(alias, Config::SettingData(true, setting));
}
bool set = false;
@ -68,11 +69,13 @@ void AbstractConfig::reapplyUnknownSettings() {
void Config::getSettings(std::map<std::string, SettingInfo>& res,
bool overridenOnly) {
for (auto& opt : _settings)
for (auto& opt : _settings) {
if (!opt.second.isAlias &&
(!overridenOnly || opt.second.setting->overriden))
(!overridenOnly || opt.second.setting->overriden)) {
res.emplace(opt.first, SettingInfo{opt.second.setting->to_string(),
opt.second.setting->description});
}
}
}
void AbstractConfig::applyConfigFile(const Path& path) {
@ -83,8 +86,9 @@ void AbstractConfig::applyConfigFile(const Path& path) {
while (pos < contents.size()) {
string line;
while (pos < contents.size() && contents[pos] != '\n')
while (pos < contents.size() && contents[pos] != '\n') {
line += contents[pos++];
}
pos++;
string::size_type hash = line.find('#');
@ -97,23 +101,25 @@ void AbstractConfig::applyConfigFile(const Path& path) {
continue;
}
if (tokens.size() < 2)
if (tokens.size() < 2) {
throw UsageError("illegal configuration line '%1%' in '%2%'", line,
path);
}
auto include = false;
auto ignoreMissing = false;
if (tokens[0] == "include")
if (tokens[0] == "include") {
include = true;
else if (tokens[0] == "!include") {
} else if (tokens[0] == "!include") {
include = true;
ignoreMissing = true;
}
if (include) {
if (tokens.size() != 2)
if (tokens.size() != 2) {
throw UsageError("illegal configuration line '%1%' in '%2%'", line,
path);
}
auto p = absPath(tokens[1], dirOf(path));
if (pathExists(p)) {
applyConfigFile(p);
@ -123,9 +129,10 @@ void AbstractConfig::applyConfigFile(const Path& path) {
continue;
}
if (tokens[1] != "=")
if (tokens[1] != "=") {
throw UsageError("illegal configuration line '%1%' in '%2%'", line,
path);
}
string name = tokens[0];
@ -146,20 +153,22 @@ void Config::resetOverriden() {
}
void Config::toJSON(JSONObject& out) {
for (auto& s : _settings)
for (auto& s : _settings) {
if (!s.second.isAlias) {
JSONObject out2(out.object(s.first));
out2.attr("description", s.second.setting->description);
JSONPlaceholder out3(out2.placeholder("value"));
s.second.setting->toJSON(out3);
}
}
}
void Config::convertToArgs(Args& args, const std::string& category) {
for (auto& s : _settings)
for (auto& s : _settings) {
if (!s.second.isAlias) {
s.second.setting->convertToArg(args, category);
}
}
}
AbstractSetting::AbstractSetting(const std::string& name,
@ -202,8 +211,9 @@ std::string BaseSetting<std::string>::to_string() {
template <typename T>
void BaseSetting<T>::set(const std::string& str) {
static_assert(std::is_integral<T>::value, "Integer required.");
if (!string2Int(str, value))
if (!string2Int(str, value)) {
throw UsageError("setting '%s' has invalid value '%s'", name, str);
}
}
template <typename T>
@ -214,12 +224,13 @@ std::string BaseSetting<T>::to_string() {
template <>
void BaseSetting<bool>::set(const std::string& str) {
if (str == "true" || str == "yes" || str == "1")
if (str == "true" || str == "yes" || str == "1") {
value = true;
else if (str == "false" || str == "no" || str == "0")
} else if (str == "false" || str == "no" || str == "0") {
value = false;
else
} else {
throw UsageError("Boolean setting '%s' has invalid value '%s'", name, str);
}
}
template <>
@ -290,19 +301,22 @@ template class BaseSetting<StringSet>;
void PathSetting::set(const std::string& str) {
if (str == "") {
if (allowEmpty)
if (allowEmpty) {
value = "";
else
} else {
throw UsageError("setting '%s' cannot be empty", name);
} else
}
} else {
value = canonPath(str);
}
}
bool GlobalConfig::set(const std::string& name, const std::string& value) {
for (auto& config : *configRegistrations)
for (auto& config : *configRegistrations) {
if (config->set(name, value)) {
return true;
}
}
unknownSettings.emplace(name, value);
@ -311,8 +325,9 @@ bool GlobalConfig::set(const std::string& name, const std::string& value) {
void GlobalConfig::getSettings(std::map<std::string, SettingInfo>& res,
bool overridenOnly) {
for (auto& config : *configRegistrations)
for (auto& config : *configRegistrations) {
config->getSettings(res, overridenOnly);
}
}
void GlobalConfig::resetOverriden() {
@ -328,8 +343,9 @@ void GlobalConfig::toJSON(JSONObject& out) {
}
void GlobalConfig::convertToArgs(Args& args, const std::string& category) {
for (auto& config : *configRegistrations)
for (auto& config : *configRegistrations) {
config->convertToArgs(args, category);
}
}
GlobalConfig globalConfig;

View file

@ -132,8 +132,9 @@ Hash::Hash(const std::string& s, HashType type) : type(type) {
sep = s.find('-');
if (sep != string::npos) {
isSRI = true;
} else if (type == htUnknown)
} else if (type == htUnknown) {
throw BadHash("hash '%s' does not include a type", s);
}
}
if (sep != string::npos) {
@ -142,8 +143,9 @@ Hash::Hash(const std::string& s, HashType type) : type(type) {
if (this->type == htUnknown) {
throw BadHash("unknown hash type '%s'", hts);
}
if (type != htUnknown && type != this->type)
if (type != htUnknown && type != this->type) {
throw BadHash("hash '%s' should have type '%s'", s, printHashType(type));
}
pos = sep + 1;
}
@ -175,10 +177,11 @@ Hash::Hash(const std::string& s, HashType type) : type(type) {
for (unsigned int n = 0; n < size; ++n) {
char c = s[pos + size - n - 1];
unsigned char digit;
for (digit = 0; digit < base32Chars.size(); ++digit) /* !!! slow */
for (digit = 0; digit < base32Chars.size(); ++digit) { /* !!! slow */
if (base32Chars[digit] == c) {
break;
}
}
if (digit >= 32) {
throw BadHash("invalid base-32 hash '%s'", s);
}
@ -199,15 +202,17 @@ Hash::Hash(const std::string& s, HashType type) : type(type) {
else if (isSRI || size == base64Len()) {
auto d = base64Decode(std::string(s, pos));
if (d.size() != hashSize)
if (d.size() != hashSize) {
throw BadHash("invalid %s hash '%s'", isSRI ? "SRI" : "base-64", s);
}
assert(hashSize);
memcpy(hash, d.data(), hashSize);
}
else
else {
throw BadHash("hash '%s' has wrong length for hash type '%s'", s,
printHashType(type));
}
}
union Ctx {
@ -218,37 +223,40 @@ union Ctx {
};
static void start(HashType ht, Ctx& ctx) {
if (ht == htMD5)
if (ht == htMD5) {
MD5_Init(&ctx.md5);
else if (ht == htSHA1)
} else if (ht == htSHA1) {
SHA1_Init(&ctx.sha1);
else if (ht == htSHA256)
} else if (ht == htSHA256) {
SHA256_Init(&ctx.sha256);
else if (ht == htSHA512)
} else if (ht == htSHA512) {
SHA512_Init(&ctx.sha512);
}
}
static void update(HashType ht, Ctx& ctx, const unsigned char* bytes,
size_t len) {
if (ht == htMD5)
if (ht == htMD5) {
MD5_Update(&ctx.md5, bytes, len);
else if (ht == htSHA1)
} else if (ht == htSHA1) {
SHA1_Update(&ctx.sha1, bytes, len);
else if (ht == htSHA256)
} else if (ht == htSHA256) {
SHA256_Update(&ctx.sha256, bytes, len);
else if (ht == htSHA512)
} else if (ht == htSHA512) {
SHA512_Update(&ctx.sha512, bytes, len);
}
}
static void finish(HashType ht, Ctx& ctx, unsigned char* hash) {
if (ht == htMD5)
if (ht == htMD5) {
MD5_Final(hash, &ctx.md5);
else if (ht == htSHA1)
} else if (ht == htSHA1) {
SHA1_Final(hash, &ctx.sha1);
else if (ht == htSHA256)
} else if (ht == htSHA256) {
SHA256_Final(hash, &ctx.sha256);
else if (ht == htSHA512)
} else if (ht == htSHA512) {
SHA512_Final(hash, &ctx.sha512);
}
}
Hash hashString(HashType ht, const string& s) {
@ -331,29 +339,31 @@ Hash compressHash(const Hash& hash, unsigned int newSize) {
}
HashType parseHashType(const string& s) {
if (s == "md5")
if (s == "md5") {
return htMD5;
else if (s == "sha1")
} else if (s == "sha1") {
return htSHA1;
else if (s == "sha256")
} else if (s == "sha256") {
return htSHA256;
else if (s == "sha512")
} else if (s == "sha512") {
return htSHA512;
else
} else {
return htUnknown;
}
}
string printHashType(HashType ht) {
if (ht == htMD5)
if (ht == htMD5) {
return "md5";
else if (ht == htSHA1)
} else if (ht == htSHA1) {
return "sha1";
else if (ht == htSHA256)
} else if (ht == htSHA256) {
return "sha256";
else if (ht == htSHA512)
} else if (ht == htSHA512) {
return "sha512";
else
} else {
abort();
}
}
} // namespace nix

View file

@ -7,28 +7,31 @@ namespace nix {
void toJSON(std::ostream& str, const char* start, const char* end) {
str << '"';
for (auto i = start; i != end; i++)
if (*i == '\"' || *i == '\\')
for (auto i = start; i != end; i++) {
if (*i == '\"' || *i == '\\') {
str << '\\' << *i;
else if (*i == '\n')
} else if (*i == '\n') {
str << "\\n";
else if (*i == '\r')
} else if (*i == '\r') {
str << "\\r";
else if (*i == '\t')
} else if (*i == '\t') {
str << "\\t";
else if (*i >= 0 && *i < 32)
} else if (*i >= 0 && *i < 32) {
str << "\\u" << std::setfill('0') << std::setw(4) << std::hex
<< (uint16_t)*i << std::dec;
else
} else {
str << *i;
}
}
str << '"';
}
void toJSON(std::ostream& str, const char* s) {
if (!s)
if (!s) {
str << "null";
else
} else {
toJSON(str, s, s + strlen(s));
}
}
template <>

View file

@ -173,7 +173,7 @@ std::unique_ptr<Source> sinkToSource(std::function<void(Sink&)> fun,
size_t pos = 0;
size_t read(unsigned char* data, size_t len) override {
if (!coro)
if (!coro) {
coro = coro_t::pull_type([&](coro_t::push_type& yield) {
LambdaSink sink([&](const unsigned char* data, size_t len) {
if (len) {
@ -182,6 +182,7 @@ std::unique_ptr<Source> sinkToSource(std::function<void(Sink&)> fun,
});
fun(sink);
});
}
if (!*coro) {
eof();
@ -189,7 +190,9 @@ std::unique_ptr<Source> sinkToSource(std::function<void(Sink&)> fun,
}
if (pos == cur.size()) {
if (!cur.empty()) (*coro)();
if (!cur.empty()) {
(*coro)();
}
cur = coro->get();
pos = 0;
}
@ -247,10 +250,11 @@ void readPadding(size_t len, Source& source) {
unsigned char zero[8];
size_t n = 8 - (len % 8);
source(zero, n);
for (unsigned int i = 0; i < n; i++)
for (unsigned int i = 0; i < n; i++) {
if (zero[i]) {
throw SerialisationError("non-zero padding");
}
}
}
}
@ -284,7 +288,9 @@ template <class T>
T readStrings(Source& source) {
auto count = readNum<size_t>(source);
T ss;
while (count--) ss.insert(ss.end(), readString(source));
while (count--) {
ss.insert(ss.end(), readString(source));
}
return ss;
}

View file

@ -50,8 +50,9 @@ void ThreadPool::enqueue(const work_t& t) {
state->pending.push(t);
/* Note: process() also executes items, so count it as a worker. */
if (state->pending.size() > state->workers.size() + 1 &&
state->workers.size() + 1 < maxThreads)
state->workers.size() + 1 < maxThreads) {
state->workers.emplace_back(&ThreadPool::doWork, this, false);
}
work.notify_one();
}
@ -111,8 +112,9 @@ void ThreadPool::doWork(bool mainThread) {
std::rethrow_exception(exc);
} catch (std::exception& e) {
if (!dynamic_cast<Interrupted*>(&e) &&
!dynamic_cast<ThreadPoolShutDown*>(&e))
!dynamic_cast<ThreadPoolShutDown*>(&e)) {
ignoreException();
}
} catch (...) {
}
}

View file

@ -60,9 +60,10 @@ std::map<std::string, std::string> getEnv() {
for (size_t i = 0; environ[i]; ++i) {
auto s = environ[i];
auto eq = strchr(s, '=');
if (!eq)
if (!eq) {
// invalid env, just keep going
continue;
}
env.emplace(std::string(s, eq), std::string(eq + 1));
}
return env;
@ -91,18 +92,19 @@ Path absPath(Path path, Path dir) {
if (buf == NULL)
#else
char buf[PATH_MAX];
if (!getcwd(buf, sizeof(buf)))
if (!getcwd(buf, sizeof(buf))) {
#endif
throw SysError("cannot get cwd");
dir = buf;
#ifdef __GNU__
free(buf);
#endif
}
path = dir + "/" + path;
dir = buf;
#ifdef __GNU__
free(buf);
#endif
}
return canonPath(path);
path = dir + "/" + path;
}
return canonPath(path);
} // namespace nix
Path canonPath(const Path& path, bool resolveSymlinks) {
assert(path != "");
@ -122,7 +124,9 @@ Path canonPath(const Path& path, bool resolveSymlinks) {
while (1) {
/* Skip slashes. */
while (i != end && *i == '/') i++;
while (i != end && *i == '/') {
i++;
}
if (i == end) {
break;
}
@ -144,14 +148,17 @@ Path canonPath(const Path& path, bool resolveSymlinks) {
/* Normal component; copy it. */
else {
s += '/';
while (i != end && *i != '/') s += *i++;
while (i != end && *i != '/') {
s += *i++;
}
/* If s points to a symlink, resolve it and restart (since
the symlink target might contain new symlinks). */
if (resolveSymlinks && isLink(s)) {
if (++followCount >= maxFollow)
if (++followCount >= maxFollow) {
throw Error(format("infinite symlink recursion in path '%1%'") %
path);
}
temp = absPath(readLink(s), dirOf(s)) + string(i, end);
i = temp.begin(); /* restart */
end = temp.end();
@ -182,10 +189,11 @@ string baseNameOf(const Path& path) {
}
Path::size_type pos = path.rfind('/', last);
if (pos == string::npos)
if (pos == string::npos) {
pos = 0;
else
} else {
pos += 1;
}
return string(path, pos, last - pos + 1);
}
@ -201,8 +209,9 @@ bool isDirOrInDir(const Path& path, const Path& dir) {
struct stat lstat(const Path& path) {
struct stat st;
if (lstat(path.c_str(), &st))
if (lstat(path.c_str(), &st)) {
throw SysError(format("getting status of '%1%'") % path);
}
return st;
}
@ -213,8 +222,9 @@ bool pathExists(const Path& path) {
if (!res) {
return true;
}
if (errno != ENOENT && errno != ENOTDIR)
if (errno != ENOENT && errno != ENOTDIR) {
throw SysError(format("getting status of %1%") % path);
}
return false;
}
@ -224,13 +234,15 @@ Path readLink(const Path& path) {
for (ssize_t bufSize = PATH_MAX / 4; true; bufSize += bufSize / 2) {
buf.resize(bufSize);
ssize_t rlSize = readlink(path.c_str(), buf.data(), bufSize);
if (rlSize == -1)
if (errno == EINVAL)
if (rlSize == -1) {
if (errno == EINVAL) {
throw Error("'%1%' is not a symlink", path);
else
} else {
throw SysError("reading symbolic link '%1%'", path);
else if (rlSize < bufSize)
}
} else if (rlSize < bufSize) {
return string(buf.data(), rlSize);
}
}
}
@ -351,9 +363,9 @@ string readLine(int fd) {
if (errno != EINTR) {
throw SysError("reading a line");
}
} else if (rd == 0)
} else if (rd == 0) {
throw EndOfFile("unexpected EOF reading a line");
else {
} else {
if (ch == '\n') {
return s;
}
@ -386,12 +398,14 @@ static void _deletePath(const Path& path, unsigned long long& bytesFreed) {
/* Make the directory accessible. */
const auto PERM_MASK = S_IRUSR | S_IWUSR | S_IXUSR;
if ((st.st_mode & PERM_MASK) != PERM_MASK) {
if (chmod(path.c_str(), st.st_mode | PERM_MASK) == -1)
if (chmod(path.c_str(), st.st_mode | PERM_MASK) == -1) {
throw SysError(format("chmod '%1%'") % path);
}
}
for (auto& i : readDirectory(path))
for (auto& i : readDirectory(path)) {
_deletePath(path + "/" + i.name, bytesFreed);
}
}
if (remove(path.c_str()) == -1) {
@ -418,11 +432,12 @@ static Path tempName(Path tmpRoot, const Path& prefix, bool includePid,
int& counter) {
tmpRoot =
canonPath(tmpRoot.empty() ? getEnv("TMPDIR", "/tmp") : tmpRoot, true);
if (includePid)
if (includePid) {
return (format("%1%/%2%-%3%-%4%") % tmpRoot % prefix % getpid() % counter++)
.str();
else
} else {
return (format("%1%/%2%-%3%") % tmpRoot % prefix % counter++).str();
}
}
Path createTempDir(const Path& tmpRoot, const Path& prefix, bool includePid,
@ -449,8 +464,9 @@ Path createTempDir(const Path& tmpRoot, const Path& prefix, bool includePid,
#endif
return tmpDir;
}
if (errno != EEXIST)
if (errno != EEXIST) {
throw SysError(format("creating directory '%1%'") % tmpDir);
}
}
}
@ -470,8 +486,9 @@ static Lazy<Path> getHome2([]() {
struct passwd pwbuf;
struct passwd* pw;
if (getpwuid_r(geteuid(), &pwbuf, buf.data(), buf.size(), &pw) != 0 ||
!pw || !pw->pw_dir || !pw->pw_dir[0])
!pw || !pw->pw_dir || !pw->pw_dir[0]) {
throw Error("cannot determine user's home directory");
}
homeDir = pw->pw_dir;
}
return homeDir;
@ -521,25 +538,29 @@ Paths createDirs(const Path& path) {
struct stat st;
if (lstat(path.c_str(), &st) == -1) {
created = createDirs(dirOf(path));
if (mkdir(path.c_str(), 0777) == -1 && errno != EEXIST)
if (mkdir(path.c_str(), 0777) == -1 && errno != EEXIST) {
throw SysError(format("creating directory '%1%'") % path);
}
st = lstat(path);
created.push_back(path);
}
if (S_ISLNK(st.st_mode) && stat(path.c_str(), &st) == -1)
if (S_ISLNK(st.st_mode) && stat(path.c_str(), &st) == -1) {
throw SysError(format("statting symlink '%1%'") % path);
}
if (!S_ISDIR(st.st_mode))
if (!S_ISDIR(st.st_mode)) {
throw Error(format("'%1%' is not a directory") % path);
}
return created;
}
void createSymlink(const Path& target, const Path& link) {
if (symlink(target.c_str(), link.c_str()))
if (symlink(target.c_str(), link.c_str())) {
throw SysError(format("creating symlink from '%1%' to '%2%'") % link %
target);
}
}
void replaceSymlink(const Path& target, const Path& link) {
@ -555,8 +576,9 @@ void replaceSymlink(const Path& target, const Path& link) {
throw;
}
if (rename(tmp.c_str(), link.c_str()) != 0)
if (rename(tmp.c_str(), link.c_str()) != 0) {
throw SysError(format("renaming '%1%' to '%2%'") % tmp % link);
}
break;
}
@ -612,15 +634,17 @@ void drainFD(int fd, Sink& sink, bool block) {
Finally finally([&]() {
if (!block) {
if (fcntl(fd, F_SETFL, saved) == -1)
if (fcntl(fd, F_SETFL, saved) == -1) {
throw SysError("making file descriptor blocking");
}
}
});
if (!block) {
saved = fcntl(fd, F_GETFL);
if (fcntl(fd, F_SETFL, saved | O_NONBLOCK) == -1)
if (fcntl(fd, F_SETFL, saved | O_NONBLOCK) == -1) {
throw SysError("making file descriptor non-blocking");
}
}
std::vector<unsigned char> buf(64 * 1024);
@ -634,10 +658,11 @@ void drainFD(int fd, Sink& sink, bool block) {
if (errno != EINTR) {
throw SysError("reading from file");
}
} else if (rd == 0)
} else if (rd == 0) {
break;
else
} else {
sink(buf.data(), rd);
}
}
}
@ -656,8 +681,9 @@ AutoDelete::~AutoDelete() {
if (recursive) {
deletePath(path);
} else {
if (remove(path.c_str()) == -1)
if (remove(path.c_str()) == -1) {
throw SysError(format("cannot unlink '%1%'") % path);
}
}
}
} catch (...) {
@ -700,8 +726,9 @@ int AutoCloseFD::get() const { return fd; }
void AutoCloseFD::close() {
if (fd != -1) {
if (::close(fd) == -1) /* This should never happen. */
if (::close(fd) == -1) { /* This should never happen. */
throw SysError(format("closing file descriptor %1%") % fd);
}
}
}
@ -835,8 +862,9 @@ void killUser(uid_t uid) {
if (errno == ESRCH) {
break;
} /* no more processes */
if (errno != EINTR)
if (errno != EINTR) {
throw SysError(format("cannot kill processes for uid '%1%'") % uid);
}
}
_exit(0);
@ -844,9 +872,10 @@ void killUser(uid_t uid) {
options);
int status = pid.wait();
if (status != 0)
if (status != 0) {
throw Error(format("cannot kill processes for uid '%1%': %2%") % uid %
statusToString(status));
}
/* !!! We should really do some check to make sure that there are
no processes left running under `uid', but there is no portable
@ -877,8 +906,9 @@ pid_t startProcess(std::function<void()> fun, const ProcessOptions& options) {
auto wrapper = [&]() {
try {
#if __linux__
if (options.dieWithParent && prctl(PR_SET_PDEATHSIG, SIGKILL) == -1)
if (options.dieWithParent && prctl(PR_SET_PDEATHSIG, SIGKILL) == -1) {
throw SysError("setting death signal");
}
#endif
restoreAffinity();
fun();
@ -889,10 +919,11 @@ pid_t startProcess(std::function<void()> fun, const ProcessOptions& options) {
}
} catch (...) {
}
if (options.runExitHandlers)
if (options.runExitHandlers) {
exit(1);
else
} else {
_exit(1);
}
};
pid_t pid = doFork(options.allowVfork, wrapper);
@ -920,9 +951,10 @@ string runProgram(Path program, bool searchPath, const Strings& args,
auto res = runProgram(opts);
if (!statusOk(res.first))
if (!statusOk(res.first)) {
throw ExecError(res.first, fmt("program '%1%' %2%", program,
statusToString(res.first)));
}
return res.second;
}
@ -980,33 +1012,42 @@ void runProgram2(const RunOptions& options) {
replaceEnv(*options.environment);
}
if (options.standardOut &&
dup2(out.writeSide.get(), STDOUT_FILENO) == -1)
dup2(out.writeSide.get(), STDOUT_FILENO) == -1) {
throw SysError("dupping stdout");
if (options.mergeStderrToStdout)
if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1)
}
if (options.mergeStderrToStdout) {
if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1) {
throw SysError("cannot dup stdout into stderr");
if (source && dup2(in.readSide.get(), STDIN_FILENO) == -1)
}
}
if (source && dup2(in.readSide.get(), STDIN_FILENO) == -1) {
throw SysError("dupping stdin");
}
if (options.chdir && chdir((*options.chdir).c_str()) == -1)
if (options.chdir && chdir((*options.chdir).c_str()) == -1) {
throw SysError("chdir failed");
if (options.gid && setgid(*options.gid) == -1)
}
if (options.gid && setgid(*options.gid) == -1) {
throw SysError("setgid failed");
}
/* Drop all other groups if we're setgid. */
if (options.gid && setgroups(0, 0) == -1)
if (options.gid && setgroups(0, 0) == -1) {
throw SysError("setgroups failed");
if (options.uid && setuid(*options.uid) == -1)
}
if (options.uid && setuid(*options.uid) == -1) {
throw SysError("setuid failed");
}
Strings args_(options.args);
args_.push_front(options.program);
restoreSignals();
if (options.searchPath)
if (options.searchPath) {
execvp(options.program.c_str(), stringsToCharPtrs(args_).data());
else
} else {
execv(options.program.c_str(), stringsToCharPtrs(args_).data());
}
throw SysError("executing '%1%'", options.program);
},
@ -1058,9 +1099,10 @@ void runProgram2(const RunOptions& options) {
promise.get_future().get();
}
if (status)
if (status) {
throw ExecError(status, fmt("program '%1%' %2%", options.program,
statusToString(status)));
}
}
void closeMostFDs(const set<int>& exceptions) {
@ -1080,17 +1122,19 @@ void closeMostFDs(const set<int>& exceptions) {
int maxFD = 0;
maxFD = sysconf(_SC_OPEN_MAX);
for (int fd = 0; fd < maxFD; ++fd)
for (int fd = 0; fd < maxFD; ++fd) {
if (!exceptions.count(fd)) {
close(fd);
} /* ignore result */
}
}
void closeOnExec(int fd) {
int prev;
if ((prev = fcntl(fd, F_GETFD, 0)) == -1 ||
fcntl(fd, F_SETFD, prev | FD_CLOEXEC) == -1)
fcntl(fd, F_SETFD, prev | FD_CLOEXEC) == -1) {
throw SysError("setting close-on-exec flag");
}
}
//////////////////////////////////////////////////////////////////////
@ -1187,9 +1231,9 @@ string replaceStrings(const std::string& s, const std::string& from,
string statusToString(int status) {
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
if (WIFEXITED(status))
if (WIFEXITED(status)) {
return (format("failed with exit code %1%") % WEXITSTATUS(status)).str();
else if (WIFSIGNALED(status)) {
} else if (WIFSIGNALED(status)) {
int sig = WTERMSIG(status);
#if HAVE_STRSIGNAL
const char* description = strsignal(sig);
@ -1198,10 +1242,12 @@ string statusToString(int status) {
#else
return (format("failed due to signal %1%") % sig).str();
#endif
} else
} else {
return "died abnormally";
} else
}
} else {
return "succeeded";
}
}
bool statusOk(int status) {
@ -1227,11 +1273,13 @@ std::string toLower(const std::string& s) {
std::string shellEscape(const std::string& s) {
std::string r = "'";
for (auto& i : s)
if (i == '\'')
for (auto& i : s) {
if (i == '\'') {
r += "'\\''";
else
} else {
r += i;
}
}
r += '\'';
return r;
}
@ -1259,9 +1307,13 @@ std::string filterANSIEscapes(const std::string& s, bool filterAll,
if (i != s.end() && *i == '[') {
e += *i++;
// eat parameter bytes
while (i != s.end() && *i >= 0x30 && *i <= 0x3f) e += *i++;
while (i != s.end() && *i >= 0x30 && *i <= 0x3f) {
e += *i++;
}
// eat intermediate bytes
while (i != s.end() && *i >= 0x20 && *i <= 0x2f) e += *i++;
while (i != s.end() && *i >= 0x20 && *i <= 0x2f) {
e += *i++;
}
// eat final byte
if (i != s.end() && *i >= 0x40 && *i <= 0x7e) {
e += last = *i++;
@ -1287,11 +1339,11 @@ std::string filterANSIEscapes(const std::string& s, bool filterAll,
}
}
else if (*i == '\r')
else if (*i == '\r') {
// do nothing for now
i++;
else {
} else {
t += *i++;
w++;
}
@ -1319,7 +1371,9 @@ string base64Encode(const string& s) {
if (nbits) {
res.push_back(base64Chars[data << (6 - nbits) & 0x3f]);
}
while (res.size() % 4) res.push_back('=');
while (res.size() % 4) {
res.push_back('=');
}
return res;
}
@ -1395,10 +1449,10 @@ static void signalHandlerThread(sigset_t set) {
int signal = 0;
sigwait(&set, &signal);
if (signal == SIGINT || signal == SIGTERM || signal == SIGHUP)
if (signal == SIGINT || signal == SIGTERM || signal == SIGHUP) {
triggerInterrupt();
else if (signal == SIGWINCH) {
} else if (signal == SIGWINCH) {
updateWindowSize();
}
}
@ -1424,8 +1478,9 @@ static sigset_t savedSignalMask;
void startSignalHandlerThread() {
updateWindowSize();
if (sigprocmask(SIG_BLOCK, nullptr, &savedSignalMask))
if (sigprocmask(SIG_BLOCK, nullptr, &savedSignalMask)) {
throw SysError("quering signal mask");
}
sigset_t set;
sigemptyset(&set);
@ -1434,15 +1489,17 @@ void startSignalHandlerThread() {
sigaddset(&set, SIGHUP);
sigaddset(&set, SIGPIPE);
sigaddset(&set, SIGWINCH);
if (pthread_sigmask(SIG_BLOCK, &set, nullptr))
if (pthread_sigmask(SIG_BLOCK, &set, nullptr)) {
throw SysError("blocking signals");
}
std::thread(signalHandlerThread, set).detach();
}
void restoreSignals() {
if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr))
if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr)) {
throw SysError("restoring signals");
}
}
/* RAII helper to automatically deregister a callback. */

View file

@ -16,7 +16,9 @@ void XMLWriter::close() {
if (closed) {
return;
}
while (!pendingElems.empty()) closeElement();
while (!pendingElems.empty()) {
closeElement();
}
closed = true;
}
@ -68,20 +70,21 @@ void XMLWriter::writeAttrs(const XMLAttrs& attrs) {
output << " " << i.first << "=\"";
for (size_t j = 0; j < i.second.size(); ++j) {
char c = i.second[j];
if (c == '"')
if (c == '"') {
output << "&quot;";
else if (c == '<')
} else if (c == '<') {
output << "&lt;";
else if (c == '>')
} else if (c == '>') {
output << "&gt;";
else if (c == '&')
} else if (c == '&') {
output << "&amp;";
/* Escape newlines to prevent attribute normalisation (see
XML spec, section 3.3.3. */
else if (c == '\n')
/* Escape newlines to prevent attribute normalisation (see
XML spec, section 3.3.3. */
} else if (c == '\n') {
output << "&#xA;";
else
} else {
output << c;
}
}
output << "\"";
}

View file

@ -125,9 +125,11 @@ static void _main(int argc, char** argv) {
line = chomp(line);
std::smatch match;
if (std::regex_match(line, match,
std::regex("^#!\\s*nix-shell (.*)$")))
for (const auto& word : shellwords(match[1].str()))
std::regex("^#!\\s*nix-shell (.*)$"))) {
for (const auto& word : shellwords(match[1].str())) {
args.push_back(word);
}
}
}
}
} catch (SysError&) {
@ -145,63 +147,63 @@ static void _main(int argc, char** argv) {
showManPage(myName);
}
else if (*arg == "--version")
else if (*arg == "--version") {
printVersion(myName);
else if (*arg == "--add-drv-link" || *arg == "--indirect")
} else if (*arg == "--add-drv-link" || *arg == "--indirect") {
; // obsolete
else if (*arg == "--no-out-link" || *arg == "--no-link")
} else if (*arg == "--no-out-link" || *arg == "--no-link") {
outLink = (Path)tmpDir + "/result";
else if (*arg == "--attr" || *arg == "-A")
} else if (*arg == "--attr" || *arg == "-A") {
attrPaths.push_back(getArg(*arg, arg, end));
else if (*arg == "--drv-link")
} else if (*arg == "--drv-link") {
getArg(*arg, arg, end); // obsolete
else if (*arg == "--out-link" || *arg == "-o")
} else if (*arg == "--out-link" || *arg == "-o") {
outLink = getArg(*arg, arg, end);
else if (*arg == "--add-root")
} else if (*arg == "--add-root") {
gcRoot = getArg(*arg, arg, end);
else if (*arg == "--dry-run")
} else if (*arg == "--dry-run") {
dryRun = true;
else if (*arg == "--repair") {
} else if (*arg == "--repair") {
repair = Repair;
buildMode = bmRepair;
}
else if (*arg == "--run-env") // obsolete
else if (*arg == "--run-env") { // obsolete
runEnv = true;
else if (*arg == "--command" || *arg == "--run") {
} else if (*arg == "--command" || *arg == "--run") {
if (*arg == "--run") {
interactive = false;
}
envCommand = getArg(*arg, arg, end) + "\nexit";
}
else if (*arg == "--check")
else if (*arg == "--check") {
buildMode = bmCheck;
else if (*arg == "--exclude")
} else if (*arg == "--exclude") {
envExclude.push_back(getArg(*arg, arg, end));
else if (*arg == "--expr" || *arg == "-E")
} else if (*arg == "--expr" || *arg == "-E") {
fromArgs = true;
else if (*arg == "--pure")
} else if (*arg == "--pure") {
pure = true;
else if (*arg == "--impure")
} else if (*arg == "--impure") {
pure = false;
else if (*arg == "--packages" || *arg == "-p")
} else if (*arg == "--packages" || *arg == "-p") {
packages = true;
else if (inShebang && *arg == "-i") {
} else if (inShebang && *arg == "-i") {
auto interpreter = getArg(*arg, arg, end);
interactive = false;
auto execArgs = "";
@ -210,8 +212,9 @@ static void _main(int argc, char** argv) {
// executes it unless it contains the string "perl" or "indir",
// or (undocumented) argv[0] does not contain "perl". Exploit
// the latter by doing "exec -a".
if (std::regex_search(interpreter, std::regex("perl")))
if (std::regex_search(interpreter, std::regex("perl"))) {
execArgs = "-a PERL";
}
std::ostringstream joined;
for (const auto& i : savedArgs) {
@ -233,17 +236,18 @@ static void _main(int argc, char** argv) {
}
}
else if (*arg == "--keep")
else if (*arg == "--keep") {
keepVars.insert(getArg(*arg, arg, end));
else if (*arg == "-")
} else if (*arg == "-") {
readStdin = true;
else if (*arg != "" && arg->at(0) == '-')
} else if (*arg != "" && arg->at(0) == '-') {
return false;
else
} else {
left.push_back(*arg);
}
return true;
});
@ -252,8 +256,9 @@ static void _main(int argc, char** argv) {
initPlugins();
if (packages && fromArgs)
if (packages && fromArgs) {
throw UsageError("'-p' and '-E' are mutually exclusive");
}
auto store = openStore();
@ -290,22 +295,22 @@ static void _main(int argc, char** argv) {
/* Parse the expressions. */
std::vector<Expr*> exprs;
if (readStdin)
if (readStdin) {
exprs = {state->parseStdin()};
else
} else {
for (auto i : left) {
if (fromArgs)
if (fromArgs) {
exprs.push_back(state->parseExprFromString(i, absPath(".")));
else {
} else {
auto absolute = i;
try {
absolute = canonPath(absPath(i), true);
} catch (Error& e) {
};
if (store->isStorePath(absolute) &&
std::regex_match(absolute, std::regex(".*\\.drv(!.*)?")))
std::regex_match(absolute, std::regex(".*\\.drv(!.*)?"))) {
drvs.push_back(DrvInfo(*state, store, absolute));
else
} else {
/* If we're in a #! script, interpret filenames
relative to the script. */
exprs.push_back(
@ -313,8 +318,10 @@ static void _main(int argc, char** argv) {
lookupFileArg(*state, inShebang && !packages
? absPath(i, absPath(dirOf(script)))
: i)))));
}
}
}
}
/* Evaluate them into derivations. */
if (attrPaths.empty()) {
@ -342,9 +349,10 @@ static void _main(int argc, char** argv) {
store->queryMissing(paths, willBuild, willSubstitute, unknown, downloadSize,
narSize);
if (settings.printMissing)
if (settings.printMissing) {
printMissing(ref<Store>(store), willBuild, willSubstitute, unknown,
downloadSize, narSize);
}
if (!dryRun) {
store->buildPaths(paths, buildMode);
@ -352,8 +360,9 @@ static void _main(int argc, char** argv) {
};
if (runEnv) {
if (drvs.size() != 1)
if (drvs.size() != 1) {
throw UsageError("nix-shell requires a single derivation");
}
auto& drvInfo = drvs.front();
auto drv = store->derivationFromPath(drvInfo.queryDrvPath());
@ -374,10 +383,11 @@ static void _main(int argc, char** argv) {
state->eval(expr, v);
auto drv = getDerivation(*state, v, false);
if (!drv)
if (!drv) {
throw Error(
"the 'bashInteractive' attribute in <nixpkgs> did not evaluate "
"to a derivation");
}
pathsToBuild.insert(drv->queryDrvPath());
@ -390,13 +400,15 @@ static void _main(int argc, char** argv) {
}
// Build or fetch all dependencies of the derivation.
for (const auto& input : drv.inputDrvs)
for (const auto& input : drv.inputDrvs) {
if (std::all_of(envExclude.cbegin(), envExclude.cend(),
[&](const string& exclude) {
return !std::regex_search(input.first,
std::regex(exclude));
}))
})) {
pathsToBuild.insert(makeDrvPathWithOutputs(input.first, input.second));
}
}
for (const auto& src : drv.inputSrcs) {
pathsToBuild.insert(src);
}
@ -414,10 +426,11 @@ static void _main(int argc, char** argv) {
if (pure) {
decltype(env) newEnv;
for (auto& i : env)
for (auto& i : env) {
if (keepVars.count(i.first)) {
newEnv.emplace(i);
}
}
env = newEnv;
// NixOS hack: prevent /etc/bashrc from sourcing /etc/profile.
env["__ETC_PROFILE_SOURCED"] = "1";
@ -433,15 +446,17 @@ static void _main(int argc, char** argv) {
bool keepTmp = false;
int fileNr = 0;
for (auto& var : drv.env)
for (auto& var : drv.env) {
if (passAsFile.count(var.first)) {
keepTmp = true;
string fn = ".attr-" + std::to_string(fileNr++);
Path p = (Path)tmpDir + "/" + fn;
writeFile(p, var.second);
env[var.first + "Path"] = p;
} else
} else {
env[var.first] = var.second;
}
}
restoreAffinity();
@ -507,16 +522,17 @@ static void _main(int argc, char** argv) {
auto outPath = drvInfo.queryOutPath();
auto outputName = drvInfo.queryOutputName();
if (outputName == "")
if (outputName == "") {
throw Error("derivation '%s' lacks an 'outputName' attribute", drvPath);
}
pathsToBuild.insert(drvPath + "!" + outputName);
std::string drvPrefix;
auto i = drvPrefixes.find(drvPath);
if (i != drvPrefixes.end())
if (i != drvPrefixes.end()) {
drvPrefix = i->second;
else {
} else {
drvPrefix = outLink;
if (drvPrefixes.size()) {
drvPrefix += fmt("-%d", drvPrefixes.size() + 1);
@ -539,9 +555,11 @@ static void _main(int argc, char** argv) {
return;
}
for (auto& symlink : resultSymlinks)
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
for (auto& symlink : resultSymlinks) {
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>()) {
store2->addPermRoot(symlink.second, absPath(symlink.first), true);
}
}
for (auto& path : outPaths) {
std::cout << path << '\n';

View file

@ -40,18 +40,22 @@ static void readChannels() {
static void writeChannels() {
auto channelsFD = AutoCloseFD{open(
channelsList.c_str(), O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC, 0644)};
if (!channelsFD)
if (!channelsFD) {
throw SysError(format("opening '%1%' for writing") % channelsList);
for (const auto& channel : channels)
}
for (const auto& channel : channels) {
writeFull(channelsFD.get(), channel.second + " " + channel.first + "\n");
}
}
// Adds a channel.
static void addChannel(const string& url, const string& name) {
if (!regex_search(url, std::regex("^(file|http|https)://")))
if (!regex_search(url, std::regex("^(file|http|https)://"))) {
throw Error(format("invalid channel URL '%1%'") % url);
if (!regex_search(name, std::regex("^[a-zA-Z0-9_][a-zA-Z0-9_\\.-]*$")))
}
if (!regex_search(name, std::regex("^[a-zA-Z0-9_][a-zA-Z0-9_\\.-]*$"))) {
throw Error(format("invalid channel identifier '%1%'") % name);
}
readChannels();
channels[name] = url;
writeChannels();
@ -157,10 +161,12 @@ static void update(const StringSet& channelNames) {
// Make the channels appear in nix-env.
struct stat st;
if (lstat(nixDefExpr.c_str(), &st) == 0) {
if (S_ISLNK(st.st_mode))
if (S_ISLNK(st.st_mode)) {
// old-skool ~/.nix-defexpr
if (unlink(nixDefExpr.c_str()) == -1)
if (unlink(nixDefExpr.c_str()) == -1) {
throw SysError(format("unlinking %1%") % nixDefExpr);
}
}
} else if (errno != ENOENT) {
throw SysError(format("getting status of %1%") % nixDefExpr);
}
@ -210,8 +216,9 @@ static int _main(int argc, char** argv) {
case cNone:
throw UsageError("no command specified");
case cAdd:
if (args.size() < 1 || args.size() > 2)
if (args.size() < 1 || args.size() > 2) {
throw UsageError("'--add' requires one or two arguments");
}
{
auto url = args[0];
std::string name;
@ -226,8 +233,9 @@ static int _main(int argc, char** argv) {
}
break;
case cRemove:
if (args.size() != 1)
if (args.size() != 1) {
throw UsageError("'--remove' requires one argument");
}
removeChannel(args[0]);
break;
case cList:
@ -235,15 +243,17 @@ static int _main(int argc, char** argv) {
throw UsageError("'--list' expects no arguments");
}
readChannels();
for (const auto& channel : channels)
for (const auto& channel : channels) {
std::cout << channel.first << ' ' << channel.second << '\n';
}
break;
case cUpdate:
update(StringSet(args.begin(), args.end()));
break;
case cRollback:
if (args.size() > 1)
if (args.size() > 1) {
throw UsageError("'--rollback' has at most one argument");
}
Strings envArgs{"--profile", profile};
if (args.size() == 1) {
envArgs.push_back("--switch-generation");

View file

@ -42,10 +42,11 @@ void removeOldGenerations(std::string dir) {
}
if (link.find("link") != string::npos) {
LOG(INFO) << "removing old generations of profile " << path;
if (deleteOlderThan != "")
if (deleteOlderThan != "") {
deleteGenerationsOlderThan(path, deleteOlderThan, dryRun);
else
} else {
deleteOldGenerations(path, dryRun);
}
}
} else if (type == DT_DIR) {
removeOldGenerations(path);
@ -61,22 +62,23 @@ static int _main(int argc, char** argv) {
parseCmdLine(
argc, argv, [&](Strings::iterator& arg, const Strings::iterator& end) {
if (*arg == "--help")
if (*arg == "--help") {
showManPage("nix-collect-garbage");
else if (*arg == "--version")
} else if (*arg == "--version") {
printVersion("nix-collect-garbage");
else if (*arg == "--delete-old" || *arg == "-d")
} else if (*arg == "--delete-old" || *arg == "-d") {
removeOld = true;
else if (*arg == "--delete-older-than") {
} else if (*arg == "--delete-older-than") {
removeOld = true;
deleteOlderThan = getArg(*arg, arg, end);
} else if (*arg == "--dry-run")
} else if (*arg == "--dry-run") {
dryRun = true;
else if (*arg == "--max-freed") {
} else if (*arg == "--max-freed") {
long long maxFreed = getIntArg<long long>(*arg, arg, end, true);
options.maxFreed = maxFreed >= 0 ? maxFreed : 0;
} else
} else {
return false;
}
return true;
});

View file

@ -18,32 +18,33 @@ static int _main(int argc, char** argv) {
parseCmdLine(
argc, argv, [&](Strings::iterator& arg, const Strings::iterator& end) {
if (*arg == "--help")
if (*arg == "--help") {
showManPage("nix-copy-closure");
else if (*arg == "--version")
} else if (*arg == "--version") {
printVersion("nix-copy-closure");
else if (*arg == "--gzip" || *arg == "--bzip2" || *arg == "--xz") {
} else if (*arg == "--gzip" || *arg == "--bzip2" || *arg == "--xz") {
if (*arg != "--gzip") {
LOG(WARNING) << "'" << *arg
<< "' is not implemented, falling back to gzip";
}
gzip = true;
} else if (*arg == "--from")
} else if (*arg == "--from") {
toMode = false;
else if (*arg == "--to")
} else if (*arg == "--to") {
toMode = true;
else if (*arg == "--include-outputs")
} else if (*arg == "--include-outputs") {
includeOutputs = true;
else if (*arg == "--show-progress")
} else if (*arg == "--show-progress") {
LOG(WARNING) << "'--show-progress' is not implemented";
else if (*arg == "--dry-run")
} else if (*arg == "--dry-run") {
dryRun = true;
else if (*arg == "--use-substitutes" || *arg == "-s")
} else if (*arg == "--use-substitutes" || *arg == "-s") {
useSubstitutes = Substitute;
else if (sshHost.empty())
} else if (sshHost.empty()) {
sshHost = *arg;
else
} else {
storePaths.insert(*arg);
}
return true;
});
@ -58,8 +59,9 @@ static int _main(int argc, char** argv) {
auto from = toMode ? openStore() : openStore(remoteUri);
PathSet storePaths2;
for (auto& path : storePaths)
for (auto& path : storePaths) {
storePaths2.insert(from->followLinksToStorePath(path));
}
PathSet closure;
from->computeFSClosure(storePaths2, closure, false, includeOutputs);

View file

@ -90,8 +90,9 @@ struct TunnelLogger {
state->canSendStderr = false;
throw;
}
} else
} else {
state->pendingMsgs.push_back(s);
}
}
void log(const FormatOrString& fs) {
@ -253,14 +254,15 @@ static void performOp(TunnelLogger* logger, ref<Store> store, bool trusted,
Path path = readStorePath(*store, from);
logger->startWork();
PathSet paths;
if (op == wopQueryReferences)
if (op == wopQueryReferences) {
paths = store->queryPathInfo(path)->references;
else if (op == wopQueryReferrers)
} else if (op == wopQueryReferrers) {
store->queryReferrers(path, paths);
else if (op == wopQueryValidDerivers)
} else if (op == wopQueryValidDerivers) {
paths = store->queryValidDerivers(path);
else
} else {
paths = store->queryDerivationOutputs(path);
}
logger->stopWork();
to << paths;
break;
@ -377,10 +379,11 @@ static void performOp(TunnelLogger* logger, ref<Store> store, bool trusted,
/* Repairing is not atomic, so disallowed for "untrusted"
clients. */
if (mode == bmRepair && !trusted)
if (mode == bmRepair && !trusted) {
throw Error(
"repairing is not allowed because you are not in "
"'trusted-users'");
}
}
logger->startWork();
store->buildPaths(drvs, mode);
@ -451,10 +454,11 @@ static void performOp(TunnelLogger* logger, ref<Store> store, bool trusted,
to << size;
for (auto& [target, links] : roots)
for (auto& [target, links] : roots) {
for (auto& link : links) {
to << link << target;
}
}
break;
}
@ -472,8 +476,9 @@ static void performOp(TunnelLogger* logger, ref<Store> store, bool trusted,
GCResults results;
logger->startWork();
if (options.ignoreLiveness)
if (options.ignoreLiveness) {
throw Error("you are not allowed to ignore liveness");
}
store->collectGarbage(options, results);
logger->stopWork();
@ -522,30 +527,33 @@ static void performOp(TunnelLogger* logger, ref<Store> store, bool trusted,
}
Strings subs;
auto ss = tokenizeString<Strings>(value);
for (auto& s : ss)
if (trusted.count(s))
for (auto& s : ss) {
if (trusted.count(s)) {
subs.push_back(s);
else
} else {
LOG(WARNING) << "ignoring untrusted substituter '" << s << "'";
}
}
res = subs;
return true;
};
try {
if (name == "ssh-auth-sock") // obsolete
if (name == "ssh-auth-sock") { // obsolete
;
else if (trusted || name == settings.buildTimeout.name ||
name == "connect-timeout" ||
(name == "builders" && value == ""))
} else if (trusted || name == settings.buildTimeout.name ||
name == "connect-timeout" ||
(name == "builders" && value == "")) {
settings.set(name, value);
else if (setSubstituters(settings.substituters))
} else if (setSubstituters(settings.substituters)) {
;
else if (setSubstituters(settings.extraSubstituters))
} else if (setSubstituters(settings.extraSubstituters)) {
;
else
} else {
LOG(WARNING) << "ignoring the user-specified setting '" << name
<< "', because it is a "
<< "restricted setting and you are not a trusted user";
}
} catch (UsageError& e) {
LOG(WARNING) << e.what();
}
@ -562,9 +570,9 @@ static void performOp(TunnelLogger* logger, ref<Store> store, bool trusted,
store->querySubstitutablePathInfos({path}, infos);
logger->stopWork();
SubstitutablePathInfos::iterator i = infos.find(path);
if (i == infos.end())
if (i == infos.end()) {
to << 0;
else {
} else {
to << 1 << i->second.deriver << i->second.references
<< i->second.downloadSize << i->second.narSize;
}
@ -632,8 +640,9 @@ static void performOp(TunnelLogger* logger, ref<Store> store, bool trusted,
bool checkContents, repair;
from >> checkContents >> repair;
logger->startWork();
if (repair && !trusted)
if (repair && !trusted) {
throw Error("you are not privileged to repair paths");
}
bool errors = store->verifyStore(checkContents, (RepairFlag)repair);
logger->stopWork();
to << errors;
@ -746,8 +755,9 @@ static void processConnection(bool trusted, const std::string& userName,
DLOG(INFO) << opCount << " operations";
});
if (GET_PROTOCOL_MINOR(clientVersion) >= 14 && readInt(from))
if (GET_PROTOCOL_MINOR(clientVersion) >= 14 && readInt(from)) {
setAffinityTo(readInt(from));
}
readInt(from); // obsolete reserveSpace
@ -823,8 +833,9 @@ static void sigChldHandler(int sigNo) {
// Ensure we don't modify errno of whatever we've interrupted
auto saved_errno = errno;
/* Reap all dead children. */
while (waitpid(-1, 0, WNOHANG) > 0)
while (waitpid(-1, 0, WNOHANG) > 0) {
;
}
errno = saved_errno;
}
@ -833,8 +844,9 @@ static void setSigChldAction(bool autoReap) {
act.sa_handler = autoReap ? sigChldHandler : SIG_DFL;
sigfillset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(SIGCHLD, &act, &oact))
if (sigaction(SIGCHLD, &act, &oact)) {
throw SysError("setting SIGCHLD handler");
}
}
bool matchUser(const string& user, const string& group, const Strings& users) {
@ -846,7 +858,7 @@ bool matchUser(const string& user, const string& group, const Strings& users) {
return true;
}
for (auto& i : users)
for (auto& i : users) {
if (string(i, 0, 1) == "@") {
if (group == string(i, 1)) {
return true;
@ -855,11 +867,13 @@ bool matchUser(const string& user, const string& group, const Strings& users) {
if (!gr) {
continue;
}
for (char** mem = gr->gr_mem; *mem; mem++)
for (char** mem = gr->gr_mem; *mem; mem++) {
if (user == string(*mem)) {
return true;
}
}
}
}
return false;
}
@ -881,8 +895,9 @@ static PeerInfo getPeerInfo(int remote) {
ucred cred;
socklen_t credLen = sizeof(cred);
if (getsockopt(remote, SOL_SOCKET, SO_PEERCRED, &cred, &credLen) == -1)
if (getsockopt(remote, SOL_SOCKET, SO_PEERCRED, &cred, &credLen) == -1) {
throw SysError("getting peer credentials");
}
peer = {true, cred.pid, true, cred.uid, true, cred.gid};
#elif defined(LOCAL_PEERCRED)
@ -918,8 +933,9 @@ static void daemonLoop(char** argv) {
/* Handle socket-based activation by systemd. */
if (getEnv("LISTEN_FDS") != "") {
if (getEnv("LISTEN_PID") != std::to_string(getpid()) ||
getEnv("LISTEN_FDS") != "1")
getEnv("LISTEN_FDS") != "1") {
throw Error("unexpected systemd environment variables");
}
fdSocket = SD_LISTEN_FDS_START;
}
@ -938,14 +954,16 @@ 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. */
if (chdir(dirOf(socketPath).c_str()) == -1)
if (chdir(dirOf(socketPath).c_str()) == -1) {
throw SysError("cannot change current directory");
}
Path socketPathRel = "./" + baseNameOf(socketPath);
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
if (socketPathRel.size() >= sizeof(addr.sun_path))
if (socketPathRel.size() >= sizeof(addr.sun_path)) {
throw Error(format("socket path '%1%' is too long") % socketPathRel);
}
strcpy(addr.sun_path, socketPathRel.c_str());
unlink(socketPath.c_str());
@ -956,14 +974,17 @@ static void daemonLoop(char** argv) {
mode_t oldMode = umask(0111);
int res = bind(fdSocket.get(), (struct sockaddr*)&addr, sizeof(addr));
umask(oldMode);
if (res == -1)
if (res == -1) {
throw SysError(format("cannot bind to socket '%1%'") % socketPath);
}
if (chdir("/") == -1) /* back to the root */
if (chdir("/") == -1) { /* back to the root */
throw SysError("cannot change current directory");
}
if (listen(fdSocket.get(), 5) == -1)
if (listen(fdSocket.get(), 5) == -1) {
throw SysError(format("cannot listen on socket '%1%'") % socketPath);
}
}
closeOnExec(fdSocket.get());
@ -1062,16 +1083,17 @@ static int _main(int argc, char** argv) {
parseCmdLine(argc, argv,
[&](Strings::iterator& arg, const Strings::iterator& end) {
if (*arg == "--daemon")
if (*arg == "--daemon") {
; /* ignored for backwards compatibility */
else if (*arg == "--help")
} else if (*arg == "--help") {
showManPage("nix-daemon");
else if (*arg == "--version")
} else if (*arg == "--version") {
printVersion("nix-daemon");
else if (*arg == "--stdio")
} else if (*arg == "--stdio") {
stdio = true;
else
} else {
return false;
}
return true;
});
@ -1087,20 +1109,23 @@ static int _main(int argc, char** argv) {
}
auto socketDir = dirOf(socketPath);
if (chdir(socketDir.c_str()) == -1)
if (chdir(socketDir.c_str()) == -1) {
throw SysError(format("changing to socket directory '%1%'") %
socketDir);
}
auto socketName = baseNameOf(socketPath);
auto addr = sockaddr_un{};
addr.sun_family = AF_UNIX;
if (socketName.size() + 1 >= sizeof(addr.sun_path))
if (socketName.size() + 1 >= sizeof(addr.sun_path)) {
throw Error(format("socket name %1% is too long") % socketName);
}
strcpy(addr.sun_path, socketName.c_str());
if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) == -1)
if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
throw SysError(format("cannot connect to daemon at %1%") %
socketPath);
}
auto nfds = (s > STDIN_FILENO ? s : STDIN_FILENO) + 1;
while (true) {
@ -1108,23 +1133,26 @@ static int _main(int argc, char** argv) {
FD_ZERO(&fds);
FD_SET(s, &fds);
FD_SET(STDIN_FILENO, &fds);
if (select(nfds, &fds, nullptr, nullptr, nullptr) == -1)
if (select(nfds, &fds, nullptr, nullptr, nullptr) == -1) {
throw SysError("waiting for data from client or server");
}
if (FD_ISSET(s, &fds)) {
auto res = splice(s, nullptr, STDOUT_FILENO, nullptr, SSIZE_MAX,
SPLICE_F_MOVE);
if (res == -1)
if (res == -1) {
throw SysError("splicing data from daemon socket to stdout");
else if (res == 0)
} else if (res == 0) {
throw EndOfFile("unexpected EOF from daemon socket");
}
}
if (FD_ISSET(STDIN_FILENO, &fds)) {
auto res = splice(STDIN_FILENO, nullptr, s, nullptr, SSIZE_MAX,
SPLICE_F_MOVE);
if (res == -1)
if (res == -1) {
throw SysError("splicing data from stdin to daemon socket");
else if (res == 0)
} else if (res == 0) {
return 0;
}
}
}
} else {

View file

@ -60,22 +60,24 @@ struct Globals {
typedef void (*Operation)(Globals& globals, Strings opFlags, Strings opArgs);
static string needArg(Strings::iterator& i, Strings& args, const string& arg) {
if (i == args.end())
if (i == args.end()) {
throw UsageError(format("'%1%' requires an argument") % arg);
}
return *i++;
}
static bool parseInstallSourceOptions(Globals& globals, Strings::iterator& i,
Strings& args, const string& arg) {
if (arg == "--from-expression" || arg == "-E")
if (arg == "--from-expression" || arg == "-E") {
globals.instSource.type = srcNixExprs;
else if (arg == "--from-profile") {
} else if (arg == "--from-profile") {
globals.instSource.type = srcProfile;
globals.instSource.profile = needArg(i, args, arg);
} else if (arg == "--attr" || arg == "-A")
} else if (arg == "--attr" || arg == "-A") {
globals.instSource.type = srcAttrPath;
else
} else {
return false;
}
return true;
}
@ -102,8 +104,9 @@ static void getAllExprs(EvalState& state, const Path& path, StringSet& attrs,
Path path2 = path + "/" + i;
struct stat st;
if (stat(path2.c_str(), &st) == -1)
if (stat(path2.c_str(), &st) == -1) {
continue; // ignore dangling symlinks in ~/.nix-defexpr
}
if (isNixExpr(path2, st) &&
(!S_ISREG(st.st_mode) || hasSuffix(path2, ".nix"))) {
@ -112,8 +115,9 @@ static void getAllExprs(EvalState& state, const Path& path, StringSet& attrs,
`-A' option. Useful if you want to stick a Nix
expression directly in ~/.nix-defexpr. */
string attrName = i;
if (hasSuffix(attrName, ".nix"))
if (hasSuffix(attrName, ".nix")) {
attrName = string(attrName, 0, attrName.size() - 4);
}
if (attrs.find(attrName) != attrs.end()) {
LOG(WARNING) << "name collision in input Nix expressions, skipping '"
<< path2 << "'";
@ -124,21 +128,24 @@ static void getAllExprs(EvalState& state, const Path& path, StringSet& attrs,
Value& vFun = state.getBuiltin("import");
Value& vArg(*state.allocValue());
mkString(vArg, path2);
if (v.attrs->size() == v.attrs->capacity())
if (v.attrs->size() == v.attrs->capacity()) {
throw Error(format("too many Nix expressions in directory '%1%'") %
path);
}
mkApp(*state.allocAttr(v, state.symbols.create(attrName)), vFun, vArg);
} else if (S_ISDIR(st.st_mode))
} else if (S_ISDIR(st.st_mode)) {
/* `path2' is a directory (with no default.nix in it);
recurse into it. */
getAllExprs(state, path2, attrs, v);
}
}
}
static void loadSourceExpr(EvalState& state, const Path& path, Value& v) {
struct stat st;
if (stat(path.c_str(), &st) == -1)
if (stat(path.c_str(), &st) == -1) {
throw SysError(format("getting information about '%1%'") % path);
}
if (isNixExpr(path, st)) {
state.evalFile(path, v);
@ -159,8 +166,9 @@ static void loadSourceExpr(EvalState& state, const Path& path, Value& v) {
v.attrs->sort();
}
else
else {
throw Error("path '%s' is not a directory or a Nix expression", path);
}
}
static void loadDerivations(EvalState& state, Path nixExprPath,
@ -205,9 +213,11 @@ static bool isPrebuilt(EvalState& state, DrvInfo& elem) {
static void checkSelectorUse(DrvNames& selectors) {
/* Check that all selectors have been used. */
for (auto& i : selectors)
if (i.hits == 0 && i.fullName != "*")
for (auto& i : selectors) {
if (i.hits == 0 && i.fullName != "*") {
throw Error(format("selector '%1%' matches no derivations") % i.fullName);
}
}
}
static DrvInfos filterBySelector(EvalState& state, const DrvInfos& allElems,
@ -263,9 +273,10 @@ static DrvInfos filterBySelector(EvalState& state, const DrvInfos& allElems,
if (d == 0) {
d = comparePriorities(state, j.first, k->second.first);
}
if (d == 0)
if (d == 0) {
d = compareVersions(drvName.version,
DrvName(k->second.first.queryName()).version);
}
}
if (d > 0) {
@ -279,21 +290,23 @@ static DrvInfos filterBySelector(EvalState& state, const DrvInfos& allElems,
matches.clear();
for (auto& j : newest) {
if (multiple.find(j.second.first.queryName()) != multiple.end())
if (multiple.find(j.second.first.queryName()) != multiple.end()) {
LOG(WARNING) << "warning: there are multiple derivations named '"
<< j.second.first.queryName()
<< "'; using the first one";
}
matches.push_back(j.second);
}
}
/* Insert only those elements in the final list that we
haven't inserted before. */
for (auto& j : matches)
for (auto& j : matches) {
if (done.find(j.second) == done.end()) {
done.insert(j.second);
elems.push_back(j.first);
}
}
}
checkSelectorUse(selectors);
@ -307,8 +320,9 @@ static void queryInstSources(EvalState& state, InstallSourceInfo& instSource,
const Strings& args, DrvInfos& elems,
bool newestOnly) {
InstallSourceType type = instSource.type;
if (type == srcUnknown && args.size() > 0 && isPath(args.front()))
if (type == srcUnknown && args.size() > 0 && isPath(args.front())) {
type = srcStorePaths;
}
switch (type) {
/* Get the available user environment elements from the
@ -369,10 +383,12 @@ static void queryInstSources(EvalState& state, InstallSourceInfo& instSource,
elem.setOutPath(
state.store->derivationFromPath(path).findOutput("out"));
if (name.size() >= drvExtension.size() &&
string(name, name.size() - drvExtension.size()) == drvExtension)
string(name, name.size() - drvExtension.size()) == drvExtension) {
name = string(name, 0, name.size() - drvExtension.size());
} else
}
} else {
elem.setOutPath(path);
}
elems.push_back(elem);
}
@ -405,10 +421,11 @@ static void printMissing(EvalState& state, DrvInfos& elems) {
PathSet targets;
for (auto& i : elems) {
Path drvPath = i.queryDrvPath();
if (drvPath != "")
if (drvPath != "") {
targets.insert(drvPath);
else
} else {
targets.insert(i.queryOutPath());
}
}
printMissing(state.store, targets);
@ -425,9 +442,11 @@ static void installDerivations(Globals& globals, const Strings& args,
queryInstSources(*globals.state, globals.instSource, args, newElemsTmp, true);
/* If --prebuilt-only is given, filter out source-only packages. */
for (auto& i : newElemsTmp)
if (!globals.prebuiltOnly || isPrebuilt(*globals.state, i))
for (auto& i : newElemsTmp) {
if (!globals.prebuiltOnly || isPrebuilt(*globals.state, i)) {
newElems.push_back(i);
}
}
StringSet newNames;
for (auto& i : newElems) {
@ -454,10 +473,11 @@ static void installDerivations(Globals& globals, const Strings& args,
for (auto& i : installedElems) {
DrvName drvName(i.queryName());
if (!globals.preserveInstalled &&
newNames.find(drvName.name) != newNames.end() && !keep(i))
newNames.find(drvName.name) != newNames.end() && !keep(i)) {
LOG(INFO) << "replacing old '" << i.queryName() << "'";
else
} else {
allElems.push_back(i);
}
}
for (auto& i : newElems) {
@ -472,22 +492,24 @@ static void installDerivations(Globals& globals, const Strings& args,
}
if (createUserEnv(*globals.state, allElems, profile,
settings.envKeepDerivations, lockToken))
settings.envKeepDerivations, lockToken)) {
break;
}
}
}
static void opInstall(Globals& globals, Strings opFlags, Strings opArgs) {
for (Strings::iterator i = opFlags.begin(); i != opFlags.end();) {
string arg = *i++;
if (parseInstallSourceOptions(globals, i, opFlags, arg))
if (parseInstallSourceOptions(globals, i, opFlags, arg)) {
;
else if (arg == "--preserve-installed" || arg == "-P")
} else if (arg == "--preserve-installed" || arg == "-P") {
globals.preserveInstalled = true;
else if (arg == "--remove-all" || arg == "-r")
} else if (arg == "--remove-all" || arg == "-r") {
globals.removeAll = true;
else
} else {
throw UsageError(format("unknown flag '%1%'") % arg);
}
}
installDerivations(globals, opArgs, globals.profile);
@ -569,8 +591,9 @@ static void upgradeDerivations(Globals& globals, const Strings& args,
LOG(INFO) << action << " '" << i.queryName() << "' to '"
<< bestElem->queryName() << "'";
newElems.push_back(*bestElem);
} else
} else {
newElems.push_back(i);
}
} catch (Error& e) {
e.addPrefix(
@ -586,8 +609,9 @@ static void upgradeDerivations(Globals& globals, const Strings& args,
}
if (createUserEnv(*globals.state, newElems, globals.profile,
settings.envKeepDerivations, lockToken))
settings.envKeepDerivations, lockToken)) {
break;
}
}
}
@ -595,18 +619,19 @@ static void opUpgrade(Globals& globals, Strings opFlags, Strings opArgs) {
UpgradeType upgradeType = utLt;
for (Strings::iterator i = opFlags.begin(); i != opFlags.end();) {
string arg = *i++;
if (parseInstallSourceOptions(globals, i, opFlags, arg))
if (parseInstallSourceOptions(globals, i, opFlags, arg)) {
;
else if (arg == "--lt")
} else if (arg == "--lt") {
upgradeType = utLt;
else if (arg == "--leq")
} else if (arg == "--leq") {
upgradeType = utLeq;
else if (arg == "--eq")
} else if (arg == "--eq") {
upgradeType = utEq;
else if (arg == "--always")
} else if (arg == "--always") {
upgradeType = utAlways;
else
} else {
throw UsageError(format("unknown flag '%1%'") % arg);
}
}
upgradeDerivations(globals, opArgs, upgradeType);
@ -620,10 +645,12 @@ static void setMetaFlag(EvalState& state, DrvInfo& drv, const string& name,
}
static void opSetFlag(Globals& globals, Strings opFlags, Strings opArgs) {
if (opFlags.size() > 0)
if (opFlags.size() > 0) {
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
if (opArgs.size() < 2)
}
if (opArgs.size() < 2) {
throw UsageError("not enough arguments to '--set-flag'");
}
Strings::iterator arg = opArgs.begin();
string flagName = *arg++;
@ -638,21 +665,23 @@ static void opSetFlag(Globals& globals, Strings opFlags, Strings opArgs) {
/* Update all matching derivations. */
for (auto& i : installedElems) {
DrvName drvName(i.queryName());
for (auto& j : selectors)
for (auto& j : selectors) {
if (j.matches(drvName)) {
LOG(INFO) << "setting flag on '" << i.queryName() << "'";
j.hits++;
setMetaFlag(*globals.state, i, flagName, flagValue);
break;
}
}
}
checkSelectorUse(selectors);
/* Write the new user environment. */
if (createUserEnv(*globals.state, installedElems, globals.profile,
settings.envKeepDerivations, lockToken))
settings.envKeepDerivations, lockToken)) {
break;
}
}
}
@ -664,10 +693,11 @@ static void opSet(Globals& globals, Strings opFlags, Strings opArgs) {
for (Strings::iterator i = opFlags.begin(); i != opFlags.end();) {
string arg = *i++;
if (parseInstallSourceOptions(globals, i, opFlags, arg))
if (parseInstallSourceOptions(globals, i, opFlags, arg)) {
;
else
} else {
throw UsageError(format("unknown flag '%1%'") % arg);
}
}
DrvInfos elems;
@ -716,7 +746,7 @@ static void uninstallDerivations(Globals& globals, Strings& selectors,
for (auto& i : installedElems) {
DrvName drvName(i.queryName());
bool found = false;
for (auto& j : selectors)
for (auto& j : selectors) {
/* !!! the repeated calls to followLinksToStorePath()
are expensive, should pre-compute them. */
if ((isPath(j) &&
@ -727,6 +757,7 @@ static void uninstallDerivations(Globals& globals, Strings& selectors,
found = true;
break;
}
}
if (!found) {
newElems.push_back(i);
}
@ -737,14 +768,16 @@ static void uninstallDerivations(Globals& globals, Strings& selectors,
}
if (createUserEnv(*globals.state, newElems, profile,
settings.envKeepDerivations, lockToken))
settings.envKeepDerivations, lockToken)) {
break;
}
}
}
static void opUninstall(Globals& globals, Strings opFlags, Strings opArgs) {
if (opFlags.size() > 0)
if (opFlags.size() > 0) {
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
}
uninstallDerivations(globals, opArgs, globals.profile);
}
@ -769,10 +802,11 @@ void printTable(Table& table) {
assert(i.size() == nrColumns);
Strings::iterator j;
size_t column;
for (j = i.begin(), column = 0; j != i.end(); ++j, ++column)
for (j = i.begin(), column = 0; j != i.end(); ++j, ++column) {
if (j->size() > widths[column]) {
widths[column] = j->size();
}
}
}
for (auto& i : table) {
@ -782,8 +816,9 @@ void printTable(Table& table) {
string s = *j;
replace(s.begin(), s.end(), '\n', ' ');
cout << s;
if (column < nrColumns - 1)
if (column < nrColumns - 1) {
cout << string(widths[column] - s.size() + 2, ' ');
}
}
cout << std::endl;
}
@ -818,8 +853,9 @@ static VersionDiff compareVersionAgainstSet(const DrvInfo& elem,
version = name2.version;
} else if (diff != cvGreater && diff != cvEqual && d > 0) {
diff = cvLess;
if (version == "" || compareVersions(version, name2.version) < 0)
if (version == "" || compareVersions(version, name2.version) < 0) {
version = name2.version;
}
}
}
}
@ -877,48 +913,51 @@ static void opQuery(Globals& globals, Strings opFlags, Strings opArgs) {
for (Strings::iterator i = opFlags.begin(); i != opFlags.end();) {
string arg = *i++;
if (arg == "--status" || arg == "-s")
if (arg == "--status" || arg == "-s") {
printStatus = true;
else if (arg == "--no-name")
} else if (arg == "--no-name") {
printName = false;
else if (arg == "--system")
} else if (arg == "--system") {
printSystem = true;
else if (arg == "--description")
} else if (arg == "--description") {
printDescription = true;
else if (arg == "--compare-versions" || arg == "-c")
} else if (arg == "--compare-versions" || arg == "-c") {
compareVersions = true;
else if (arg == "--drv-path")
} else if (arg == "--drv-path") {
printDrvPath = true;
else if (arg == "--out-path")
} else if (arg == "--out-path") {
printOutPath = true;
else if (arg == "--meta")
} else if (arg == "--meta") {
printMeta = true;
else if (arg == "--installed")
} else if (arg == "--installed") {
source = sInstalled;
else if (arg == "--available" || arg == "-a")
} else if (arg == "--available" || arg == "-a") {
source = sAvailable;
else if (arg == "--xml")
} else if (arg == "--xml") {
xmlOutput = true;
else if (arg == "--json")
} else if (arg == "--json") {
jsonOutput = true;
else if (arg == "--attr-path" || arg == "-P")
} else if (arg == "--attr-path" || arg == "-P") {
printAttrPath = true;
else if (arg == "--attr" || arg == "-A")
} else if (arg == "--attr" || arg == "-A") {
attrPath = needArg(i, opFlags, arg);
else
} else {
throw UsageError(format("unknown flag '%1%'") % arg);
}
}
/* Obtain derivation information from the specified source. */
DrvInfos availElems, installedElems;
if (source == sInstalled || compareVersions || printStatus)
if (source == sInstalled || compareVersions || printStatus) {
installedElems = queryInstalled(*globals.state, globals.profile);
}
if (source == sAvailable || compareVersions)
if (source == sAvailable || compareVersions) {
loadDerivations(*globals.state, globals.instSource.nixExprPath,
globals.instSource.systemFilter,
*globals.instSource.autoArgs, attrPath, availElems);
}
DrvInfos elems_ = filterBySelector(
*globals.state, source == sInstalled ? installedElems : availElems,
@ -948,13 +987,15 @@ static void opQuery(Globals& globals, Strings opFlags, Strings opArgs) {
PathSet validPaths, substitutablePaths;
if (printStatus || globals.prebuiltOnly) {
PathSet paths;
for (auto& i : elems) try {
for (auto& i : elems) {
try {
paths.insert(i.queryOutPath());
} catch (AssertionError& e) {
DLOG(WARNING) << "skipping derivation named '" << i.queryName()
<< "' which gives an assertion failure";
i.setFailed();
}
}
validPaths = globals.state->store->queryValidPaths(paths);
substitutablePaths = globals.state->store->querySubstitutablePaths(paths);
}
@ -984,8 +1025,10 @@ static void opQuery(Globals& globals, Strings opFlags, Strings opArgs) {
if (globals.prebuiltOnly &&
validPaths.find(i.queryOutPath()) == validPaths.end() &&
substitutablePaths.find(i.queryOutPath()) == substitutablePaths.end())
substitutablePaths.find(i.queryOutPath()) ==
substitutablePaths.end()) {
continue;
}
/* For table output. */
Strings columns;
@ -1003,15 +1046,17 @@ static void opQuery(Globals& globals, Strings opFlags, Strings opArgs) {
attrs["installed"] = isInstalled ? "1" : "0";
attrs["valid"] = isValid ? "1" : "0";
attrs["substitutable"] = hasSubs ? "1" : "0";
} else
} else {
columns.push_back((string)(isInstalled ? "I" : "-") +
(isValid ? "P" : "-") + (hasSubs ? "S" : "-"));
}
}
if (xmlOutput)
if (xmlOutput) {
attrs["attrPath"] = i.attrPath;
else if (printAttrPath)
} else if (printAttrPath) {
columns.push_back(i.attrPath);
}
if (xmlOutput) {
auto drvName = DrvName(i.queryName());
@ -1055,8 +1100,9 @@ static void opQuery(Globals& globals, Strings opFlags, Strings opArgs) {
}
} else {
string column = (string) "" + ch + " " + version;
if (diff == cvGreater && tty)
if (diff == cvGreater && tty) {
column = ANSI_RED + column + ANSI_NORMAL;
}
columns.push_back(column);
}
}
@ -1065,8 +1111,9 @@ static void opQuery(Globals& globals, Strings opFlags, Strings opArgs) {
if (i.querySystem() != "") {
attrs["system"] = i.querySystem();
}
} else if (printSystem)
} else if (printSystem) {
columns.push_back(i.querySystem());
}
if (printDrvPath) {
string drvPath = i.queryDrvPath();
@ -1074,8 +1121,9 @@ static void opQuery(Globals& globals, Strings opFlags, Strings opArgs) {
if (drvPath != "") {
attrs["drvPath"] = drvPath;
}
} else
} else {
columns.push_back(drvPath == "" ? "-" : drvPath);
}
}
if (printOutPath && !xmlOutput) {
@ -1100,8 +1148,9 @@ static void opQuery(Globals& globals, Strings opFlags, Strings opArgs) {
if (descr != "") {
attrs["description"] = descr;
}
} else
} else {
columns.push_back(descr);
}
}
if (xmlOutput) {
@ -1171,10 +1220,12 @@ static void opQuery(Globals& globals, Strings opFlags, Strings opArgs) {
}
}
}
} else
} else {
xml.writeEmptyElement("item", attrs);
} else
}
} else {
table.push_back(columns);
}
cout.flush();
@ -1194,10 +1245,12 @@ static void opQuery(Globals& globals, Strings opFlags, Strings opArgs) {
}
static void opSwitchProfile(Globals& globals, Strings opFlags, Strings opArgs) {
if (opFlags.size() > 0)
if (opFlags.size() > 0) {
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
if (opArgs.size() != 1)
}
if (opArgs.size() != 1) {
throw UsageError(format("exactly one argument expected"));
}
Path profile = absPath(opArgs.front());
Path profileLink = getHome() + "/.nix-profile";
@ -1215,17 +1268,20 @@ static void switchGeneration(Globals& globals, int dstGen) {
Generations gens = findGenerations(globals.profile, curGen);
Generation dst;
for (auto& i : gens)
for (auto& i : gens) {
if ((dstGen == prevGen && i.number < curGen) ||
(dstGen >= 0 && i.number == dstGen))
(dstGen >= 0 && i.number == dstGen)) {
dst = i;
}
}
if (!dst) {
if (dstGen == prevGen)
if (dstGen == prevGen) {
throw Error(format("no generation older than the current (%1%) exists") %
curGen);
else
} else {
throw Error(format("generation %1% does not exist") % dstGen);
}
}
LOG(INFO) << "switching from generation " << curGen << " to " << dst.number;
@ -1239,21 +1295,25 @@ static void switchGeneration(Globals& globals, int dstGen) {
static void opSwitchGeneration(Globals& globals, Strings opFlags,
Strings opArgs) {
if (opFlags.size() > 0)
if (opFlags.size() > 0) {
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
if (opArgs.size() != 1)
}
if (opArgs.size() != 1) {
throw UsageError(format("exactly one argument expected"));
}
int dstGen;
if (!string2Int(opArgs.front(), dstGen))
if (!string2Int(opArgs.front(), dstGen)) {
throw UsageError(format("expected a generation number"));
}
switchGeneration(globals, dstGen);
}
static void opRollback(Globals& globals, Strings opFlags, Strings opArgs) {
if (opFlags.size() > 0)
if (opFlags.size() > 0) {
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
}
if (opArgs.size() != 0) {
throw UsageError(format("no arguments expected"));
}
@ -1263,8 +1323,9 @@ static void opRollback(Globals& globals, Strings opFlags, Strings opArgs) {
static void opListGenerations(Globals& globals, Strings opFlags,
Strings opArgs) {
if (opFlags.size() > 0)
if (opFlags.size() > 0) {
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
}
if (opArgs.size() != 0) {
throw UsageError(format("no arguments expected"));
}
@ -1291,29 +1352,33 @@ static void opListGenerations(Globals& globals, Strings opFlags,
static void opDeleteGenerations(Globals& globals, Strings opFlags,
Strings opArgs) {
if (opFlags.size() > 0)
if (opFlags.size() > 0) {
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
}
if (opArgs.size() == 1 && opArgs.front() == "old") {
deleteOldGenerations(globals.profile, globals.dryRun);
} else if (opArgs.size() == 1 && opArgs.front().find('d') != string::npos) {
deleteGenerationsOlderThan(globals.profile, opArgs.front(), globals.dryRun);
} else if (opArgs.size() == 1 && opArgs.front().find('+') != string::npos) {
if (opArgs.front().size() < 2)
if (opArgs.front().size() < 2) {
throw Error(format("invalid number of generations %1%") %
opArgs.front());
}
string str_max = string(opArgs.front(), 1, opArgs.front().size());
int max;
if (!string2Int(str_max, max) || max == 0)
if (!string2Int(str_max, max) || max == 0) {
throw Error(format("invalid number of generations to keep %1%") %
opArgs.front());
}
deleteGenerationsGreaterThan(globals.profile, max, globals.dryRun);
} else {
std::set<unsigned int> gens;
for (auto& i : opArgs) {
unsigned int n;
if (!string2Int(i, n))
if (!string2Int(i, n)) {
throw UsageError(format("invalid generation number '%1%'") % i);
}
gens.insert(n);
}
deleteGenerations(globals.profile, gens, globals.dryRun);
@ -1343,10 +1408,11 @@ static int _main(int argc, char** argv) {
replaceSymlink(fmt("%s/profiles/per-user/%s/channels",
settings.nixStateDir, getUserName()),
globals.instSource.nixExprPath + "/channels");
if (getuid() != 0)
if (getuid() != 0) {
replaceSymlink(
fmt("%s/profiles/per-user/root/channels", settings.nixStateDir),
globals.instSource.nixExprPath + "/channels_root");
}
} catch (Error&) {
}
}
@ -1364,59 +1430,62 @@ static int _main(int argc, char** argv) {
const Strings::iterator& end) {
Operation oldOp = op;
if (*arg == "--help")
if (*arg == "--help") {
showManPage("nix-env");
else if (*arg == "--version")
} else if (*arg == "--version") {
op = opVersion;
else if (*arg == "--install" || *arg == "-i")
} else if (*arg == "--install" || *arg == "-i") {
op = opInstall;
else if (*arg ==
"--force-name") // undocumented flag for nix-install-package
} else if (*arg ==
"--force-name") { // undocumented flag for nix-install-package
globals.forceName = getArg(*arg, arg, end);
else if (*arg == "--uninstall" || *arg == "-e")
} else if (*arg == "--uninstall" || *arg == "-e") {
op = opUninstall;
else if (*arg == "--upgrade" || *arg == "-u")
} else if (*arg == "--upgrade" || *arg == "-u") {
op = opUpgrade;
else if (*arg == "--set-flag")
} else if (*arg == "--set-flag") {
op = opSetFlag;
else if (*arg == "--set")
} else if (*arg == "--set") {
op = opSet;
else if (*arg == "--query" || *arg == "-q")
} else if (*arg == "--query" || *arg == "-q") {
op = opQuery;
else if (*arg == "--profile" || *arg == "-p")
} else if (*arg == "--profile" || *arg == "-p") {
globals.profile = absPath(getArg(*arg, arg, end));
else if (*arg == "--file" || *arg == "-f")
} else if (*arg == "--file" || *arg == "-f") {
file = getArg(*arg, arg, end);
else if (*arg == "--switch-profile" || *arg == "-S")
} else if (*arg == "--switch-profile" || *arg == "-S") {
op = opSwitchProfile;
else if (*arg == "--switch-generation" || *arg == "-G")
} else if (*arg == "--switch-generation" || *arg == "-G") {
op = opSwitchGeneration;
else if (*arg == "--rollback")
} else if (*arg == "--rollback") {
op = opRollback;
else if (*arg == "--list-generations")
} else if (*arg == "--list-generations") {
op = opListGenerations;
else if (*arg == "--delete-generations")
} else if (*arg == "--delete-generations") {
op = opDeleteGenerations;
else if (*arg == "--dry-run") {
} else if (*arg == "--dry-run") {
LOG(INFO) << "(dry run; not doing anything)";
globals.dryRun = true;
} else if (*arg == "--system-filter")
} else if (*arg == "--system-filter") {
globals.instSource.systemFilter = getArg(*arg, arg, end);
else if (*arg == "--prebuilt-only" || *arg == "-b")
} else if (*arg == "--prebuilt-only" || *arg == "-b") {
globals.prebuiltOnly = true;
else if (*arg == "--repair")
} else if (*arg == "--repair") {
repair = Repair;
else if (*arg != "" && arg->at(0) == '-') {
} else if (*arg != "" && arg->at(0) == '-') {
opFlags.push_back(*arg);
/* FIXME: hacky */
if (*arg == "--from-profile" ||
(op == opQuery && (*arg == "--attr" || *arg == "-A")))
(op == opQuery && (*arg == "--attr" || *arg == "-A"))) {
opFlags.push_back(getArg(*arg, arg, end));
} else
}
} else {
opArgs.push_back(*arg);
}
if (oldOp && oldOp != op)
if (oldOp && oldOp != op) {
throw UsageError("only one operation may be specified");
}
return true;
});
@ -1435,8 +1504,9 @@ static int _main(int argc, char** argv) {
std::shared_ptr<EvalState>(new EvalState(myArgs.searchPath, store));
globals.state->repair = repair;
if (file != "")
if (file != "") {
globals.instSource.nixExprPath = lookupFileArg(*globals.state, file);
}
globals.instSource.autoArgs = myArgs.getAutoArgs(*globals.state);

View file

@ -30,10 +30,11 @@ bool createUserEnv(EvalState& state, DrvInfos& elems, const Path& profile,
/* Build the components in the user environment, if they don't
exist already. */
PathSet drvsToBuild;
for (auto& i : elems)
for (auto& i : elems) {
if (i.queryDrvPath() != "") {
drvsToBuild.insert(i.queryDrvPath());
}
}
DLOG(INFO) << "building user environment dependencies";
state.store->buildPaths(drvsToBuild, state.repair ? bmRepair : bmNormal);
@ -60,8 +61,9 @@ bool createUserEnv(EvalState& state, DrvInfos& elems, const Path& profile,
mkString(*state.allocAttr(v, state.sSystem), system);
}
mkString(*state.allocAttr(v, state.sOutPath), i.queryOutPath());
if (drvPath != "")
if (drvPath != "") {
mkString(*state.allocAttr(v, state.sDrvPath), i.queryDrvPath());
}
// Copy each output meant for installation.
DrvInfo::Outputs outputs = i.queryOutputs(true);

View file

@ -40,15 +40,16 @@ void processExpr(EvalState& state, const Strings& attrPaths, bool parseOnly,
PathSet context;
if (evalOnly) {
Value vRes;
if (autoArgs.empty())
if (autoArgs.empty()) {
vRes = v;
else
} else {
state.autoCallFunction(autoArgs, v, vRes);
if (output == okXML)
}
if (output == okXML) {
printValueAsXML(state, strict, location, vRes, std::cout, context);
else if (output == okJSON)
} else if (output == okJSON) {
printValueAsJSON(state, strict, vRes, std::cout, context);
else {
} else {
if (strict) {
state.forceValueDeep(vRes);
}
@ -62,21 +63,23 @@ void processExpr(EvalState& state, const Strings& attrPaths, bool parseOnly,
/* What output do we want? */
string outputName = i.queryOutputName();
if (outputName == "")
if (outputName == "") {
throw Error(
format("derivation '%1%' lacks an 'outputName' attribute ") %
drvPath);
}
if (gcRoot == "")
if (gcRoot == "") {
printGCWarning();
else {
} else {
Path rootName = indirectRoot ? absPath(gcRoot) : gcRoot;
if (++rootNr > 1) {
rootName += "-" + std::to_string(rootNr);
}
auto store2 = state.store.dynamic_pointer_cast<LocalFSStore>();
if (store2)
if (store2) {
drvPath = store2->addPermRoot(drvPath, rootName, indirectRoot);
}
}
std::cout << format("%1%%2%\n") % drvPath %
(outputName != "out" ? "!" + outputName : "");
@ -106,44 +109,45 @@ static int _main(int argc, char** argv) {
MyArgs myArgs(baseNameOf(argv[0]),
[&](Strings::iterator& arg, const Strings::iterator& end) {
if (*arg == "--help")
if (*arg == "--help") {
showManPage("nix-instantiate");
else if (*arg == "--version")
} else if (*arg == "--version") {
printVersion("nix-instantiate");
else if (*arg == "-")
} else if (*arg == "-") {
readStdin = true;
else if (*arg == "--expr" || *arg == "-E")
} else if (*arg == "--expr" || *arg == "-E") {
fromArgs = true;
else if (*arg == "--eval" || *arg == "--eval-only")
} else if (*arg == "--eval" || *arg == "--eval-only") {
evalOnly = true;
else if (*arg == "--read-write-mode")
} else if (*arg == "--read-write-mode") {
wantsReadWrite = true;
else if (*arg == "--parse" || *arg == "--parse-only")
} else if (*arg == "--parse" || *arg == "--parse-only") {
parseOnly = evalOnly = true;
else if (*arg == "--find-file")
} else if (*arg == "--find-file") {
findFile = true;
else if (*arg == "--attr" || *arg == "-A")
} else if (*arg == "--attr" || *arg == "-A") {
attrPaths.push_back(getArg(*arg, arg, end));
else if (*arg == "--add-root")
} else if (*arg == "--add-root") {
gcRoot = getArg(*arg, arg, end);
else if (*arg == "--indirect")
} else if (*arg == "--indirect") {
indirectRoot = true;
else if (*arg == "--xml")
} else if (*arg == "--xml") {
outputKind = okXML;
else if (*arg == "--json")
} else if (*arg == "--json") {
outputKind = okJSON;
else if (*arg == "--no-location")
} else if (*arg == "--no-location") {
xmlOutputSourceLocation = false;
else if (*arg == "--strict")
} else if (*arg == "--strict") {
strict = true;
else if (*arg == "--repair")
} else if (*arg == "--repair") {
repair = Repair;
else if (*arg == "--dry-run")
} else if (*arg == "--dry-run") {
settings.readOnlyMode = true;
else if (*arg != "" && arg->at(0) == '-')
} else if (*arg != "" && arg->at(0) == '-') {
return false;
else
} else {
files.push_back(*arg);
}
return true;
});

View file

@ -40,12 +40,14 @@ string resolveMirrorUri(EvalState& state, string uri) {
state.forceAttrs(vMirrors);
auto mirrorList = vMirrors.attrs->find(state.symbols.create(mirrorName));
if (mirrorList == vMirrors.attrs->end())
if (mirrorList == vMirrors.attrs->end()) {
throw Error(format("unknown mirror name '%1%'") % mirrorName);
}
state.forceList(*mirrorList->value);
if (mirrorList->value->listSize() < 1)
if (mirrorList->value->listSize() < 1) {
throw Error(format("mirror URI '%1%' did not expand to anything") % uri);
}
string mirror = state.forceString(*mirrorList->value->listElems()[0]);
return mirror + (hasSuffix(mirror, "/") ? "" : "/") + string(s, p + 1);
@ -67,28 +69,30 @@ static int _main(int argc, char** argv) {
MyArgs myArgs(baseNameOf(argv[0]),
[&](Strings::iterator& arg, const Strings::iterator& end) {
if (*arg == "--help")
if (*arg == "--help") {
showManPage("nix-prefetch-url");
else if (*arg == "--version")
} else if (*arg == "--version") {
printVersion("nix-prefetch-url");
else if (*arg == "--type") {
} else if (*arg == "--type") {
string s = getArg(*arg, arg, end);
ht = parseHashType(s);
if (ht == htUnknown)
if (ht == htUnknown) {
throw UsageError(format("unknown hash type '%1%'") % s);
} else if (*arg == "--print-path")
}
} else if (*arg == "--print-path") {
printPath = true;
else if (*arg == "--attr" || *arg == "-A") {
} else if (*arg == "--attr" || *arg == "-A") {
fromExpr = true;
attrPath = getArg(*arg, arg, end);
} else if (*arg == "--unpack")
} else if (*arg == "--unpack") {
unpack = true;
else if (*arg == "--name")
} else if (*arg == "--name") {
name = getArg(*arg, arg, end);
else if (*arg != "" && arg->at(0) == '-')
} else if (*arg != "" && arg->at(0) == '-') {
return false;
else
} else {
args.push_back(*arg);
}
return true;
});
@ -123,8 +127,9 @@ static int _main(int argc, char** argv) {
/* Extract the URI. */
auto attr = v.attrs->find(state->symbols.create("urls"));
if (attr == v.attrs->end())
if (attr == v.attrs->end()) {
throw Error("attribute set does not contain a 'urls' attribute");
}
state->forceList(*attr->value);
if (attr->value->listSize() < 1) {
throw Error("'urls' list is empty");
@ -133,10 +138,11 @@ static int _main(int argc, char** argv) {
/* Extract the hash mode. */
attr = v.attrs->find(state->symbols.create("outputHashMode"));
if (attr == v.attrs->end())
if (attr == v.attrs->end()) {
LOG(WARNING) << "this does not look like a fetchurl call";
else
} else {
unpack = state->forceString(*attr->value) == "recursive";
}
/* Extract the name. */
if (name.empty()) {
@ -151,8 +157,9 @@ static int _main(int argc, char** argv) {
if (name.empty()) {
name = baseNameOf(uri);
}
if (name.empty())
if (name.empty()) {
throw Error(format("cannot figure out file name for '%1%'") % uri);
}
/* If an expected hash is given, the file may already exist in
the store. */
@ -161,10 +168,11 @@ static int _main(int argc, char** argv) {
if (args.size() == 2) {
expectedHash = Hash(args[1], ht);
storePath = store->makeFixedOutputPath(unpack, expectedHash, name);
if (store->isValidPath(storePath))
if (store->isValidPath(storePath)) {
hash = expectedHash;
else
} else {
storePath.clear();
}
}
if (storePath.empty()) {
@ -193,27 +201,30 @@ static int _main(int argc, char** argv) {
LOG(INFO) << "unpacking...";
Path unpacked = (Path)tmpDir + "/unpacked";
createDirs(unpacked);
if (hasSuffix(baseNameOf(uri), ".zip"))
if (hasSuffix(baseNameOf(uri), ".zip")) {
runProgram("unzip", true, {"-qq", tmpFile, "-d", unpacked});
else
} else {
// FIXME: this requires GNU tar for decompression.
runProgram("tar", true, {"xf", tmpFile, "-C", unpacked});
}
/* If the archive unpacks to a single file/directory, then use
that as the top-level. */
auto entries = readDirectory(unpacked);
if (entries.size() == 1)
if (entries.size() == 1) {
tmpFile = unpacked + "/" + entries[0].name;
else
} else {
tmpFile = unpacked;
}
}
/* FIXME: inefficient; addToStore() will also hash
this. */
hash = unpack ? hashPath(ht, tmpFile).first : hashFile(ht, tmpFile);
if (expectedHash != Hash(ht) && expectedHash != hash)
if (expectedHash != Hash(ht) && expectedHash != hash) {
throw Error(format("hash mismatch for '%1%'") % uri);
}
/* Copy the file to the Nix store. FIXME: if RemoteStore
implemented addToStoreFromDump() and downloadFile()

View file

@ -38,8 +38,9 @@ static std::shared_ptr<Store> store;
ref<LocalStore> ensureLocalStore() {
auto store2 = std::dynamic_pointer_cast<LocalStore>(store);
if (!store2)
if (!store2) {
throw Error("you don't have sufficient rights to use this command");
}
return ref<LocalStore>(store2);
}
@ -48,8 +49,9 @@ static Path useDeriver(Path path) {
return path;
}
Path drvPath = store->queryPathInfo(path)->deriver;
if (drvPath == "")
if (drvPath == "") {
throw Error(format("deriver of path '%1%' is not known") % path);
}
return drvPath;
}
@ -67,23 +69,25 @@ static PathSet realisePath(Path path, bool build = true) {
Derivation drv = store->derivationFromPath(p.first);
rootNr++;
if (p.second.empty())
if (p.second.empty()) {
for (auto& i : drv.outputs) {
p.second.insert(i.first);
}
}
PathSet outputs;
for (auto& j : p.second) {
DerivationOutputs::iterator i = drv.outputs.find(j);
if (i == drv.outputs.end())
if (i == drv.outputs.end()) {
throw Error(
format("derivation '%1%' does not have an output named '%2%'") %
p.first % j);
}
Path outPath = i->second.path;
if (store2) {
if (gcRoot == "")
if (gcRoot == "") {
printGCWarning();
else {
} else {
Path rootName = gcRoot;
if (rootNr > 1) {
rootName += "-" + std::to_string(rootNr);
@ -100,15 +104,16 @@ static PathSet realisePath(Path path, bool build = true) {
}
else {
if (build)
if (build) {
store->ensurePath(path);
else if (!store->isValidPath(path))
} else if (!store->isValidPath(path)) {
throw Error(format("path '%1%' does not exist and cannot be created") %
path);
}
if (store2) {
if (gcRoot == "")
if (gcRoot == "") {
printGCWarning();
else {
} else {
Path rootName = gcRoot;
rootNr++;
if (rootNr > 1) {
@ -127,17 +132,19 @@ static void opRealise(Strings opFlags, Strings opArgs) {
BuildMode buildMode = bmNormal;
bool ignoreUnknown = false;
for (auto& i : opFlags)
if (i == "--dry-run")
for (auto& i : opFlags) {
if (i == "--dry-run") {
dryRun = true;
else if (i == "--repair")
} else if (i == "--repair") {
buildMode = bmRepair;
else if (i == "--check")
} else if (i == "--check") {
buildMode = bmCheck;
else if (i == "--ignore-unknown")
} else if (i == "--ignore-unknown") {
ignoreUnknown = true;
else
} else {
throw UsageError(format("unknown flag '%1%'") % i);
}
}
Paths paths;
for (auto& i : opArgs) {
@ -153,17 +160,19 @@ static void opRealise(Strings opFlags, Strings opArgs) {
if (ignoreUnknown) {
Paths paths2;
for (auto& i : paths)
for (auto& i : paths) {
if (unknown.find(i) == unknown.end()) {
paths2.push_back(i);
}
}
paths = paths2;
unknown = PathSet();
}
if (settings.printMissing)
if (settings.printMissing) {
printMissing(ref<Store>(store), willBuild, willSubstitute, unknown,
downloadSize, narSize);
}
if (dryRun) {
return;
@ -172,14 +181,16 @@ static void opRealise(Strings opFlags, Strings opArgs) {
/* Build all paths at the same time to exploit parallelism. */
store->buildPaths(PathSet(paths.begin(), paths.end()), buildMode);
if (!ignoreUnknown)
if (!ignoreUnknown) {
for (auto& i : paths) {
PathSet paths = realisePath(i, false);
if (!noOutput)
if (!noOutput) {
for (auto& j : paths) {
cout << format("%1%\n") % j;
}
}
}
}
}
/* Add files to the Nix store and print the resulting paths. */
@ -188,8 +199,9 @@ static void opAdd(Strings opFlags, Strings opArgs) {
throw UsageError("unknown flag");
}
for (auto& i : opArgs)
for (auto& i : opArgs) {
cout << format("%1%\n") % store->addToStore(baseNameOf(i), i);
}
}
/* Preload the output of a fixed-output derivation into the Nix
@ -197,11 +209,13 @@ static void opAdd(Strings opFlags, Strings opArgs) {
static void opAddFixed(Strings opFlags, Strings opArgs) {
bool recursive = false;
for (auto& i : opFlags)
if (i == "--recursive")
for (auto& i : opFlags) {
if (i == "--recursive") {
recursive = true;
else
} else {
throw UsageError(format("unknown flag '%1%'") % i);
}
}
if (opArgs.empty()) {
throw UsageError("first argument must be hash algorithm");
@ -210,23 +224,27 @@ static void opAddFixed(Strings opFlags, Strings opArgs) {
HashType hashAlgo = parseHashType(opArgs.front());
opArgs.pop_front();
for (auto& i : opArgs)
for (auto& i : opArgs) {
cout << format("%1%\n") %
store->addToStore(baseNameOf(i), i, recursive, hashAlgo);
}
}
/* Hack to support caching in `nix-prefetch-url'. */
static void opPrintFixedPath(Strings opFlags, Strings opArgs) {
bool recursive = false;
for (auto i : opFlags)
if (i == "--recursive")
for (auto i : opFlags) {
if (i == "--recursive") {
recursive = true;
else
} else {
throw UsageError(format("unknown flag '%1%'") % i);
}
}
if (opArgs.size() != 3)
if (opArgs.size() != 3) {
throw UsageError(format("'--print-fixed-path' requires three arguments"));
}
Strings::iterator i = opArgs.begin();
HashType hashAlgo = parseHashType(*i++);
@ -249,8 +267,9 @@ static PathSet maybeUseOutputs(const Path& storePath, bool useOutput,
outputs.insert(i.second.path);
}
return outputs;
} else
} else {
return {storePath};
}
}
/* Some code to print a tree representation of a derivation dependency
@ -316,50 +335,52 @@ static void opQuery(Strings opFlags, Strings opArgs) {
for (auto& i : opFlags) {
QueryType prev = query;
if (i == "--outputs")
if (i == "--outputs") {
query = qOutputs;
else if (i == "--requisites" || i == "-R")
} else if (i == "--requisites" || i == "-R") {
query = qRequisites;
else if (i == "--references")
} else if (i == "--references") {
query = qReferences;
else if (i == "--referrers" || i == "--referers")
} else if (i == "--referrers" || i == "--referers") {
query = qReferrers;
else if (i == "--referrers-closure" || i == "--referers-closure")
} else if (i == "--referrers-closure" || i == "--referers-closure") {
query = qReferrersClosure;
else if (i == "--deriver" || i == "-d")
} else if (i == "--deriver" || i == "-d") {
query = qDeriver;
else if (i == "--binding" || i == "-b") {
} else if (i == "--binding" || i == "-b") {
if (opArgs.size() == 0) {
throw UsageError("expected binding name");
}
bindingName = opArgs.front();
opArgs.pop_front();
query = qBinding;
} else if (i == "--hash")
} else if (i == "--hash") {
query = qHash;
else if (i == "--size")
} else if (i == "--size") {
query = qSize;
else if (i == "--tree")
} else if (i == "--tree") {
query = qTree;
else if (i == "--graph")
} else if (i == "--graph") {
query = qGraph;
else if (i == "--graphml")
} else if (i == "--graphml") {
query = qGraphML;
else if (i == "--resolve")
} else if (i == "--resolve") {
query = qResolve;
else if (i == "--roots")
} else if (i == "--roots") {
query = qRoots;
else if (i == "--use-output" || i == "-u")
} else if (i == "--use-output" || i == "-u") {
useOutput = true;
else if (i == "--force-realise" || i == "--force-realize" || i == "-f")
} else if (i == "--force-realise" || i == "--force-realize" || i == "-f") {
forceRealise = true;
else if (i == "--include-outputs")
} else if (i == "--include-outputs") {
includeOutputs = true;
else
} else {
throw UsageError(format("unknown flag '%1%'") % i);
if (prev != qDefault && prev != query)
}
if (prev != qDefault && prev != query) {
throw UsageError(format("query type '%1%' conflicts with earlier flag") %
i);
}
}
if (query == qDefault) {
@ -392,21 +413,24 @@ static void opQuery(Strings opFlags, Strings opArgs) {
PathSet ps = maybeUseOutputs(store->followLinksToStorePath(i),
useOutput, forceRealise);
for (auto& j : ps) {
if (query == qRequisites)
if (query == qRequisites) {
store->computeFSClosure(j, paths, false, includeOutputs);
else if (query == qReferences) {
} else if (query == qReferences) {
for (auto& p : store->queryPathInfo(j)->references) {
paths.insert(p);
}
} else if (query == qReferrers)
} else if (query == qReferrers) {
store->queryReferrers(j, paths);
else if (query == qReferrersClosure)
} else if (query == qReferrersClosure) {
store->computeFSClosure(j, paths, true);
}
}
}
Paths sorted = store->topoSortPaths(paths);
for (Paths::reverse_iterator i = sorted.rbegin(); i != sorted.rend(); ++i)
for (Paths::reverse_iterator i = sorted.rbegin(); i != sorted.rend();
++i) {
cout << format("%s\n") % *i;
}
break;
}
@ -423,11 +447,12 @@ static void opQuery(Strings opFlags, Strings opArgs) {
Path path = useDeriver(store->followLinksToStorePath(i));
Derivation drv = store->derivationFromPath(path);
StringPairs::iterator j = drv.env.find(bindingName);
if (j == drv.env.end())
if (j == drv.env.end()) {
throw Error(
format(
"derivation '%1%' has no environment binding named '%2%'") %
path % bindingName);
}
cout << format("%1%\n") % j->second;
}
break;
@ -442,16 +467,18 @@ static void opQuery(Strings opFlags, Strings opArgs) {
if (query == qHash) {
assert(info->narHash.type == htSHA256);
cout << fmt("%s\n", info->narHash.to_string(Base32));
} else if (query == qSize)
} else if (query == qSize) {
cout << fmt("%d\n", info->narSize);
}
}
}
break;
case qTree: {
PathSet done;
for (auto& i : opArgs)
for (auto& i : opArgs) {
printTree(store->followLinksToStorePath(i), "", "", done);
}
break;
}
@ -478,8 +505,9 @@ static void opQuery(Strings opFlags, Strings opArgs) {
}
case qResolve: {
for (auto& i : opArgs)
for (auto& i : opArgs) {
cout << format("%1%\n") % store->followLinksToStorePath(i);
}
break;
}
@ -493,10 +521,13 @@ static void opQuery(Strings opFlags, Strings opArgs) {
settings.gcKeepDerivations);
}
Roots roots = store->findRoots(false);
for (auto& [target, links] : roots)
if (referrers.find(target) != referrers.end())
for (auto& link : links)
for (auto& [target, links] : roots) {
if (referrers.find(target) != referrers.end()) {
for (auto& link : links) {
cout << format("%1% -> %2%\n") % link % target;
}
}
}
break;
}
@ -509,16 +540,18 @@ static void opPrintEnv(Strings opFlags, Strings opArgs) {
if (!opFlags.empty()) {
throw UsageError("unknown flag");
}
if (opArgs.size() != 1)
if (opArgs.size() != 1) {
throw UsageError("'--print-env' requires one derivation store path");
}
Path drvPath = opArgs.front();
Derivation drv = store->derivationFromPath(drvPath);
/* Print each environment variable in the derivation in a format
that can be sourced by the shell. */
for (auto& i : drv.env)
for (auto& i : drv.env) {
cout << format("export %1%; %1%=%2%\n") % i.first % shellEscape(i.second);
}
/* Also output the arguments. This doesn't preserve whitespace in
arguments. */
@ -544,8 +577,9 @@ static void opReadLog(Strings opFlags, Strings opArgs) {
for (auto& i : opArgs) {
auto path = store->followLinksToStorePath(i);
auto log = store->getBuildLog(path);
if (!log)
if (!log) {
throw Error("build log of derivation '%s' is not available", path);
}
std::cout << *log;
}
}
@ -558,12 +592,14 @@ static void opDumpDB(Strings opFlags, Strings opArgs) {
for (auto& i : opArgs) {
i = store->followLinksToStorePath(i);
}
for (auto& i : opArgs)
for (auto& i : opArgs) {
cout << store->makeValidityRegistration({i}, true, true);
}
} else {
PathSet validPaths = store->queryAllValidPaths();
for (auto& i : validPaths)
for (auto& i : validPaths) {
cout << store->makeValidityRegistration({i}, true, true);
}
}
}
@ -607,13 +643,15 @@ static void opRegisterValidity(Strings opFlags, Strings opArgs) {
bool reregister = false; // !!! maybe this should be the default
bool hashGiven = false;
for (auto& i : opFlags)
if (i == "--reregister")
for (auto& i : opFlags) {
if (i == "--reregister") {
reregister = true;
else if (i == "--hash-given")
} else if (i == "--hash-given") {
hashGiven = true;
else
} else {
throw UsageError(format("unknown flag '%1%'") % i);
}
}
if (!opArgs.empty()) {
throw UsageError("no arguments expected");
@ -625,19 +663,22 @@ static void opRegisterValidity(Strings opFlags, Strings opArgs) {
static void opCheckValidity(Strings opFlags, Strings opArgs) {
bool printInvalid = false;
for (auto& i : opFlags)
if (i == "--print-invalid")
for (auto& i : opFlags) {
if (i == "--print-invalid") {
printInvalid = true;
else
} else {
throw UsageError(format("unknown flag '%1%'") % i);
}
}
for (auto& i : opArgs) {
Path path = store->followLinksToStorePath(i);
if (!store->isValidPath(path)) {
if (printInvalid)
if (printInvalid) {
cout << format("%1%\n") % path;
else
} else {
throw Error(format("path '%1%' is not valid") % path);
}
}
}
}
@ -650,20 +691,22 @@ static void opGC(Strings opFlags, Strings opArgs) {
GCResults results;
/* Do what? */
for (auto i = opFlags.begin(); i != opFlags.end(); ++i)
if (*i == "--print-roots")
for (auto i = opFlags.begin(); i != opFlags.end(); ++i) {
if (*i == "--print-roots") {
printRoots = true;
else if (*i == "--print-live")
} else if (*i == "--print-live") {
options.action = GCOptions::gcReturnLive;
else if (*i == "--print-dead")
} else if (*i == "--print-dead") {
options.action = GCOptions::gcReturnDead;
else if (*i == "--delete")
} else if (*i == "--delete") {
options.action = GCOptions::gcDeleteDead;
else if (*i == "--max-freed") {
} else if (*i == "--max-freed") {
long long maxFreed = getIntArg<long long>(*i, i, opFlags.end(), true);
options.maxFreed = maxFreed >= 0 ? maxFreed : 0;
} else
} else {
throw UsageError(format("bad sub-operation '%1%' in GC") % *i);
}
}
if (!opArgs.empty()) {
throw UsageError("no arguments expected");
@ -673,22 +716,25 @@ static void opGC(Strings opFlags, Strings opArgs) {
Roots roots = store->findRoots(false);
std::set<std::pair<Path, Path>> roots2;
// Transpose and sort the roots.
for (auto& [target, links] : roots)
for (auto& [target, links] : roots) {
for (auto& link : links) {
roots2.emplace(link, target);
}
for (auto& [link, target] : roots2)
}
for (auto& [link, target] : roots2) {
std::cout << link << " -> " << target << "\n";
}
}
else {
PrintFreed freed(options.action == GCOptions::gcDeleteDead, results);
store->collectGarbage(options, results);
if (options.action != GCOptions::gcDeleteDead)
if (options.action != GCOptions::gcDeleteDead) {
for (auto& i : results.paths) {
cout << i << std::endl;
}
}
}
}
@ -699,14 +745,17 @@ static void opDelete(Strings opFlags, Strings opArgs) {
GCOptions options;
options.action = GCOptions::gcDeleteSpecific;
for (auto& i : opFlags)
if (i == "--ignore-liveness")
for (auto& i : opFlags) {
if (i == "--ignore-liveness") {
options.ignoreLiveness = true;
else
} else {
throw UsageError(format("unknown flag '%1%'") % i);
}
}
for (auto& i : opArgs)
for (auto& i : opArgs) {
options.pathsToDelete.insert(store->followLinksToStorePath(i));
}
GCResults results;
PrintFreed freed(true, results);
@ -795,13 +844,15 @@ static void opVerify(Strings opFlags, Strings opArgs) {
bool checkContents = false;
RepairFlag repair = NoRepair;
for (auto& i : opFlags)
if (i == "--check-contents")
for (auto& i : opFlags) {
if (i == "--check-contents") {
checkContents = true;
else if (i == "--repair")
} else if (i == "--repair") {
repair = Repair;
else
} else {
throw UsageError(format("unknown flag '%1%'") % i);
}
}
if (store->verifyStore(checkContents, repair)) {
LOG(WARNING) << "not all errors were fixed";
@ -851,8 +902,9 @@ static void opRepairPath(Strings opFlags, Strings opArgs) {
/* Optimise the disk space usage of the Nix store by hard-linking
files with the same contents. */
static void opOptimise(Strings opFlags, Strings opArgs) {
if (!opArgs.empty() || !opFlags.empty())
if (!opArgs.empty() || !opFlags.empty()) {
throw UsageError("no arguments expected");
}
store->optimiseStore();
}
@ -860,11 +912,13 @@ static void opOptimise(Strings opFlags, Strings opArgs) {
/* Serve the nix store in a way usable by a restricted ssh user. */
static void opServe(Strings opFlags, Strings opArgs) {
bool writeAllowed = false;
for (auto& i : opFlags)
if (i == "--write")
for (auto& i : opFlags) {
if (i == "--write") {
writeAllowed = true;
else
} else {
throw UsageError(format("unknown flag '%1%'") % i);
}
}
if (!opArgs.empty()) {
throw UsageError("no arguments expected");
@ -889,8 +943,9 @@ static void opServe(Strings opFlags, Strings opArgs) {
settings.useSubstitutes = false;
settings.maxSilentTime = readInt(in);
settings.buildTimeout = readInt(in);
if (GET_PROTOCOL_MINOR(clientVersion) >= 2)
if (GET_PROTOCOL_MINOR(clientVersion) >= 2) {
settings.maxLogSize = readNum<unsigned long>(in);
}
if (GET_PROTOCOL_MINOR(clientVersion) >= 3) {
settings.buildRepeat = readInt(in);
settings.enforceDeterminism = readInt(in);
@ -912,10 +967,11 @@ static void opServe(Strings opFlags, Strings opArgs) {
bool lock = readInt(in);
bool substitute = readInt(in);
PathSet paths = readStorePaths<PathSet>(*store, in);
if (lock && writeAllowed)
if (lock && writeAllowed) {
for (auto& path : paths) {
store->addTempRoot(path);
}
}
/* If requested, substitute missing paths. This
implements nix-copy-closure's --use-substitutes
@ -923,21 +979,24 @@ static void opServe(Strings opFlags, Strings opArgs) {
if (substitute && writeAllowed) {
/* Filter out .drv files (we don't want to build anything). */
PathSet paths2;
for (auto& path : paths)
for (auto& path : paths) {
if (!isDerivation(path)) {
paths2.insert(path);
}
}
unsigned long long downloadSize, narSize;
PathSet willBuild, willSubstitute, unknown;
store->queryMissing(PathSet(paths2.begin(), paths2.end()), willBuild,
willSubstitute, unknown, downloadSize, narSize);
/* FIXME: should use ensurePath(), but it only
does one path at a time. */
if (!willSubstitute.empty()) try {
if (!willSubstitute.empty()) {
try {
store->buildPaths(willSubstitute);
} catch (Error& e) {
LOG(WARNING) << e.msg();
}
}
}
out << store->queryValidPaths(paths);
@ -954,9 +1013,10 @@ static void opServe(Strings opFlags, Strings opArgs) {
// !!! Maybe we want compression?
out << info->narSize // downloadSize
<< info->narSize;
if (GET_PROTOCOL_MINOR(clientVersion) >= 4)
if (GET_PROTOCOL_MINOR(clientVersion) >= 4) {
out << (info->narHash ? info->narHash.to_string() : "")
<< info->ca << info->sigs;
}
} catch (InvalidPath&) {
}
}
@ -1020,9 +1080,10 @@ static void opServe(Strings opFlags, Strings opArgs) {
out << status.status << status.errorMsg;
if (GET_PROTOCOL_MINOR(clientVersion) >= 3)
if (GET_PROTOCOL_MINOR(clientVersion) >= 3) {
out << status.timesBuilt << status.isNonDeterministic
<< status.startTime << status.stopTime;
}
break;
}
@ -1127,81 +1188,85 @@ static int _main(int argc, char** argv) {
Strings opFlags, opArgs;
Operation op = 0;
parseCmdLine(
argc, argv, [&](Strings::iterator& arg, const Strings::iterator& end) {
Operation oldOp = op;
parseCmdLine(argc, argv,
[&](Strings::iterator& arg, const Strings::iterator& end) {
Operation oldOp = op;
if (*arg == "--help")
showManPage("nix-store");
else if (*arg == "--version")
op = opVersion;
else if (*arg == "--realise" || *arg == "--realize" || *arg == "-r")
op = opRealise;
else if (*arg == "--add" || *arg == "-A")
op = opAdd;
else if (*arg == "--add-fixed")
op = opAddFixed;
else if (*arg == "--print-fixed-path")
op = opPrintFixedPath;
else if (*arg == "--delete")
op = opDelete;
else if (*arg == "--query" || *arg == "-q")
op = opQuery;
else if (*arg == "--print-env")
op = opPrintEnv;
else if (*arg == "--read-log" || *arg == "-l")
op = opReadLog;
else if (*arg == "--dump-db")
op = opDumpDB;
else if (*arg == "--load-db")
op = opLoadDB;
else if (*arg == "--register-validity")
op = opRegisterValidity;
else if (*arg == "--check-validity")
op = opCheckValidity;
else if (*arg == "--gc")
op = opGC;
else if (*arg == "--dump")
op = opDump;
else if (*arg == "--restore")
op = opRestore;
else if (*arg == "--export")
op = opExport;
else if (*arg == "--import")
op = opImport;
else if (*arg == "--init")
op = opInit;
else if (*arg == "--verify")
op = opVerify;
else if (*arg == "--verify-path")
op = opVerifyPath;
else if (*arg == "--repair-path")
op = opRepairPath;
else if (*arg == "--optimise" || *arg == "--optimize")
op = opOptimise;
else if (*arg == "--serve")
op = opServe;
else if (*arg == "--generate-binary-cache-key")
op = opGenerateBinaryCacheKey;
else if (*arg == "--add-root")
gcRoot = absPath(getArg(*arg, arg, end));
else if (*arg == "--indirect")
indirectRoot = true;
else if (*arg == "--no-output")
noOutput = true;
else if (*arg != "" && arg->at(0) == '-') {
opFlags.push_back(*arg);
if (*arg == "--max-freed" || *arg == "--max-links" ||
*arg == "--max-atime") /* !!! hack */
opFlags.push_back(getArg(*arg, arg, end));
} else
opArgs.push_back(*arg);
if (*arg == "--help") {
showManPage("nix-store");
} else if (*arg == "--version") {
op = opVersion;
} else if (*arg == "--realise" || *arg == "--realize" ||
*arg == "-r") {
op = opRealise;
} else if (*arg == "--add" || *arg == "-A") {
op = opAdd;
} else if (*arg == "--add-fixed") {
op = opAddFixed;
} else if (*arg == "--print-fixed-path") {
op = opPrintFixedPath;
} else if (*arg == "--delete") {
op = opDelete;
} else if (*arg == "--query" || *arg == "-q") {
op = opQuery;
} else if (*arg == "--print-env") {
op = opPrintEnv;
} else if (*arg == "--read-log" || *arg == "-l") {
op = opReadLog;
} else if (*arg == "--dump-db") {
op = opDumpDB;
} else if (*arg == "--load-db") {
op = opLoadDB;
} else if (*arg == "--register-validity") {
op = opRegisterValidity;
} else if (*arg == "--check-validity") {
op = opCheckValidity;
} else if (*arg == "--gc") {
op = opGC;
} else if (*arg == "--dump") {
op = opDump;
} else if (*arg == "--restore") {
op = opRestore;
} else if (*arg == "--export") {
op = opExport;
} else if (*arg == "--import") {
op = opImport;
} else if (*arg == "--init") {
op = opInit;
} else if (*arg == "--verify") {
op = opVerify;
} else if (*arg == "--verify-path") {
op = opVerifyPath;
} else if (*arg == "--repair-path") {
op = opRepairPath;
} else if (*arg == "--optimise" || *arg == "--optimize") {
op = opOptimise;
} else if (*arg == "--serve") {
op = opServe;
} else if (*arg == "--generate-binary-cache-key") {
op = opGenerateBinaryCacheKey;
} else if (*arg == "--add-root") {
gcRoot = absPath(getArg(*arg, arg, end));
} else if (*arg == "--indirect") {
indirectRoot = true;
} else if (*arg == "--no-output") {
noOutput = true;
} else if (*arg != "" && arg->at(0) == '-') {
opFlags.push_back(*arg);
if (*arg == "--max-freed" || *arg == "--max-links" ||
*arg == "--max-atime") { /* !!! hack */
opFlags.push_back(getArg(*arg, arg, end));
}
} else {
opArgs.push_back(*arg);
}
if (oldOp && oldOp != op)
throw UsageError("only one operation may be specified");
if (oldOp && oldOp != op) {
throw UsageError("only one operation may be specified");
}
return true;
});
return true;
});
initPlugins();
@ -1209,8 +1274,9 @@ static int _main(int argc, char** argv) {
throw UsageError("no operation specified");
}
if (op != opDump && op != opRestore) /* !!! hack */
if (op != opDump && op != opRestore) { /* !!! hack */
store = openStore();
}
op(opFlags, opArgs);

View file

@ -47,8 +47,8 @@ struct CmdBuild : MixDryRun, InstallablesCommand {
for (size_t i = 0; i < buildables.size(); ++i) {
auto& b(buildables[i]);
if (outLink != "")
for (auto& output : b.outputs)
if (outLink != "") {
for (auto& output : b.outputs) {
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>()) {
std::string symlink = outLink;
if (i) {
@ -59,6 +59,8 @@ struct CmdBuild : MixDryRun, InstallablesCommand {
}
store2->addPermRoot(output.second, absPath(symlink), true);
}
}
}
}
}
};

View file

@ -10,10 +10,12 @@ struct MixCat : virtual Args {
void cat(ref<FSAccessor> accessor) {
auto st = accessor->stat(path);
if (st.type == FSAccessor::Type::tMissing)
if (st.type == FSAccessor::Type::tMissing) {
throw Error(format("path '%1%' does not exist") % path);
if (st.type != FSAccessor::Type::tRegular)
}
if (st.type != FSAccessor::Type::tRegular) {
throw Error(format("path '%1%' is not a regular file") % path);
}
std::cout << accessor->readFile(path);
}

View file

@ -14,10 +14,11 @@ void Command::printHelp(const string& programName, std::ostream& out) {
if (!exs.empty()) {
out << "\n";
out << "Examples:\n";
for (auto& ex : exs)
for (auto& ex : exs) {
out << "\n"
<< " " << ex.description << "\n" // FIXME: wrap
<< " $ " << ex.command << "\n";
}
}
}
@ -26,8 +27,9 @@ MultiCommand::MultiCommand(const Commands& _commands) : commands(_commands) {
"command", 1, true, [=](std::vector<std::string> ss) {
assert(!command);
auto i = commands.find(ss[0]);
if (i == commands.end())
if (i == commands.end()) {
throw UsageError("'%s' is not a recognised command", ss[0]);
}
command = i->second;
}});
}
@ -50,8 +52,9 @@ void MultiCommand::printHelp(const string& programName, std::ostream& out) {
Table2 table;
for (auto& command : commands) {
auto descr = command.second->description();
if (!descr.empty())
if (!descr.empty()) {
table.push_back(std::make_pair(command.second->name(), descr));
}
}
printTable(out, table);
@ -72,16 +75,19 @@ bool MultiCommand::processFlag(Strings::iterator& pos, Strings::iterator end) {
}
bool MultiCommand::processArgs(const Strings& args, bool finish) {
if (command)
if (command) {
return command->processArgs(args, finish);
else
} else {
return Args::processArgs(args, finish);
}
}
StoreCommand::StoreCommand() {}
ref<Store> StoreCommand::getStore() {
if (!_store) _store = createStore();
if (!_store) {
_store = createStore();
}
return ref<Store>(_store);
}
@ -90,17 +96,18 @@ ref<Store> StoreCommand::createStore() { return openStore(); }
void StoreCommand::run() { run(getStore()); }
StorePathsCommand::StorePathsCommand(bool recursive) : recursive(recursive) {
if (recursive)
if (recursive) {
mkFlag()
.longName("no-recursive")
.description("apply operation to specified paths only")
.set(&this->recursive, false);
else
} else {
mkFlag()
.longName("recursive")
.shortName('r')
.description("apply operation to closure of the specified paths")
.set(&this->recursive, true);
}
mkFlag(0, "all", "apply operation to the entire store", &all);
}
@ -109,16 +116,18 @@ void StorePathsCommand::run(ref<Store> store) {
Paths storePaths;
if (all) {
if (installables.size())
if (installables.size()) {
throw UsageError("'--all' does not expect arguments");
}
for (auto& p : store->queryAllValidPaths()) {
storePaths.push_back(p);
}
}
else {
for (auto& p : toStorePaths(store, NoBuild, installables))
for (auto& p : toStorePaths(store, NoBuild, installables)) {
storePaths.push_back(p);
}
if (recursive) {
PathSet closure;
@ -134,8 +143,9 @@ void StorePathsCommand::run(ref<Store> store) {
void StorePathCommand::run(ref<Store> store) {
auto storePaths = toStorePaths(store, NoBuild, installables);
if (storePaths.size() != 1)
if (storePaths.size() != 1) {
throw UsageError("this command requires exactly one store path");
}
run(store, *storePaths.begin());
}

View file

@ -72,8 +72,9 @@ struct CmdCopy : StorePathsCommand {
}
void run(ref<Store> srcStore, Paths storePaths) override {
if (srcUri.empty() && dstUri.empty())
if (srcUri.empty() && dstUri.empty()) {
throw UsageError("you must pass '--from' and/or '--to'");
}
ref<Store> dstStore = dstUri.empty() ? openStore() : openStore(dstUri);

View file

@ -44,9 +44,11 @@ struct CmdDoctor : StoreCommand {
bool checkNixInPath() {
PathSet dirs;
for (auto& dir : tokenizeString<Strings>(getEnv("PATH"), ":"))
if (pathExists(dir + "/nix-env"))
for (auto& dir : tokenizeString<Strings>(getEnv("PATH"), ":")) {
if (pathExists(dir + "/nix-env")) {
dirs.insert(dirOf(canonPath(dir + "/nix-env", true)));
}
}
if (dirs.size() != 1) {
std::cout << "Warning: multiple versions of nix found in PATH."
@ -73,11 +75,13 @@ struct CmdDoctor : StoreCommand {
if (store->isStorePath(userEnv) &&
hasSuffix(userEnv, "user-environment")) {
while (profileDir.find("/profiles/") == std::string::npos &&
isLink(profileDir))
isLink(profileDir)) {
profileDir = absPath(readLink(profileDir), dirOf(profileDir));
}
if (profileDir.find("/profiles/") == std::string::npos)
if (profileDir.find("/profiles/") == std::string::npos) {
dirs.insert(dir);
}
}
} catch (SysError&) {
}

View file

@ -40,8 +40,9 @@ struct CmdEdit : InstallableCommand {
DLOG(INFO) << "position is " << pos;
auto colon = pos.rfind(':');
if (colon == std::string::npos)
if (colon == std::string::npos) {
throw Error("cannot parse meta.position attribute '%s'", pos);
}
std::string filename(pos, 0, colon);
int lineno;
@ -57,8 +58,9 @@ struct CmdEdit : InstallableCommand {
if (editor.find("emacs") != std::string::npos ||
editor.find("nano") != std::string::npos ||
editor.find("vim") != std::string::npos)
editor.find("vim") != std::string::npos) {
args.push_back(fmt("+%d", lineno));
}
args.push_back(filename);

View file

@ -32,8 +32,9 @@ struct CmdEval : MixJSON, InstallableCommand {
}
void run(ref<Store> store) override {
if (raw && json)
if (raw && json) {
throw UsageError("--raw and --json are mutually exclusive");
}
auto state = getEvalState();

View file

@ -73,8 +73,9 @@ struct CmdToBase : Command {
}
void run() override {
for (auto s : args)
for (auto s : args) {
std::cout << fmt("%s\n", Hash(s, ht).to_string(base, base == SRI));
}
}
};
@ -94,29 +95,31 @@ static int compatNixHash(int argc, char** argv) {
parseCmdLine(argc, argv,
[&](Strings::iterator& arg, const Strings::iterator& end) {
if (*arg == "--help")
if (*arg == "--help") {
showManPage("nix-hash");
else if (*arg == "--version")
} else if (*arg == "--version") {
printVersion("nix-hash");
else if (*arg == "--flat")
} else if (*arg == "--flat") {
flat = true;
else if (*arg == "--base32")
} else if (*arg == "--base32") {
base32 = true;
else if (*arg == "--truncate")
} else if (*arg == "--truncate") {
truncate = true;
else if (*arg == "--type") {
} else if (*arg == "--type") {
string s = getArg(*arg, arg, end);
ht = parseHashType(s);
if (ht == htUnknown)
if (ht == htUnknown) {
throw UsageError(format("unknown hash type '%1%'") % s);
} else if (*arg == "--to-base16")
}
} else if (*arg == "--to-base16") {
op = opTo16;
else if (*arg == "--to-base32")
} else if (*arg == "--to-base32") {
op = opTo32;
else if (*arg != "" && arg->at(0) == '-')
} else if (*arg != "" && arg->at(0) == '-') {
return false;
else
} else {
ss.push_back(*arg);
}
return true;
});

View file

@ -30,10 +30,10 @@ Value* SourceExprCommand::getSourceExpr(EvalState& state) {
vSourceExpr = state.allocValue();
if (file != "")
if (file != "") {
state.evalFile(lookupFileArg(state, file), *vSourceExpr);
else {
} else {
/* Construct the installation source from $NIX_PATH. */
auto searchPath = state.getSearchPath();
@ -60,14 +60,18 @@ Value* SourceExprCommand::getSourceExpr(EvalState& state) {
state.getBuiltin("import"), *v2);
};
for (auto& i : searchPath) /* Hack to handle channels. */
for (auto& i : searchPath) { /* Hack to handle channels. */
if (i.first.empty() && pathExists(i.second + "/manifest.nix")) {
for (auto& j : readDirectory(i.second))
for (auto& j : readDirectory(i.second)) {
if (j.name != "manifest.nix" &&
pathExists(fmt("%s/%s/default.nix", i.second, j.name)))
pathExists(fmt("%s/%s/default.nix", i.second, j.name))) {
addEntry(j.name);
} else
}
}
} else {
addEntry(i.first);
}
}
vSourceExpr->attrs->sort();
}
@ -76,18 +80,20 @@ Value* SourceExprCommand::getSourceExpr(EvalState& state) {
}
ref<EvalState> SourceExprCommand::getEvalState() {
if (!evalState)
if (!evalState) {
evalState = std::make_shared<EvalState>(searchPath, getStore());
}
return ref<EvalState>(evalState);
}
Buildable Installable::toBuildable() {
auto buildables = toBuildables();
if (buildables.size() != 1)
if (buildables.size() != 1) {
throw Error(
"installable '%s' evaluates to %d derivations, where only one is "
"expected",
what(), buildables.size());
}
return std::move(buildables[0]);
}
@ -127,9 +133,10 @@ struct InstallableValue : Installable {
drvPaths.insert(b.drvPath);
auto outputName = drv.queryOutputName();
if (outputName == "")
if (outputName == "") {
throw Error("derivation '%s' lacks an 'outputName' attribute",
b.drvPath);
}
b.outputs.emplace(outputName, drv.queryOutPath());
@ -140,11 +147,13 @@ struct InstallableValue : Installable {
// merge the buildables.
if (drvPaths.size() == 1) {
Buildable b{*drvPaths.begin()};
for (auto& b2 : res)
for (auto& b2 : res) {
b.outputs.insert(b2.outputs.begin(), b2.outputs.end());
}
return {b};
} else
} else {
return res;
}
}
};
@ -200,21 +209,23 @@ static std::vector<std::shared_ptr<Installable>> parseInstallables(
}
for (auto& s : ss) {
if (s.compare(0, 1, "(") == 0)
if (s.compare(0, 1, "(") == 0) {
result.push_back(std::make_shared<InstallableExpr>(cmd, s));
else if (s.find("/") != std::string::npos) {
} else if (s.find("/") != std::string::npos) {
auto path = store->toStorePath(store->followLinksToStore(s));
if (store->isStorePath(path))
if (store->isStorePath(path)) {
result.push_back(std::make_shared<InstallableStorePath>(path));
}
}
else if (s == "" || std::regex_match(s, attrPathRegex))
else if (s == "" || std::regex_match(s, attrPathRegex)) {
result.push_back(std::make_shared<InstallableAttrPath>(cmd, s));
else
} else {
throw UsageError("don't know what to do with argument '%s'", s);
}
}
return result;
@ -248,10 +259,11 @@ Buildables build(ref<Store> store, RealiseMode mode,
}
pathsToBuild.insert(b.drvPath + "!" +
concatStringsSep(",", outputNames));
} else
} else {
for (auto& output : b.outputs) {
pathsToBuild.insert(output.second);
}
}
buildables.push_back(std::move(b));
}
}
@ -269,10 +281,11 @@ PathSet toStorePaths(ref<Store> store, RealiseMode mode,
std::vector<std::shared_ptr<Installable>> installables) {
PathSet outPaths;
for (auto& b : build(store, mode, installables))
for (auto& b : build(store, mode, installables)) {
for (auto& output : b.outputs) {
outPaths.insert(output.second);
}
}
return outPaths;
}
@ -281,9 +294,10 @@ Path toStorePath(ref<Store> store, RealiseMode mode,
std::shared_ptr<Installable> installable) {
auto paths = toStorePaths(store, mode, {installable});
if (paths.size() != 1)
if (paths.size() != 1) {
throw Error("argument '%s' should evaluate to one store path",
installable->what());
}
return *paths.begin();
}
@ -293,22 +307,26 @@ PathSet toDerivations(ref<Store> store,
bool useDeriver) {
PathSet drvPaths;
for (auto& i : installables)
for (auto& i : installables) {
for (auto& b : i->toBuildables()) {
if (b.drvPath.empty()) {
if (!useDeriver)
if (!useDeriver) {
throw Error("argument '%s' did not evaluate to a derivation",
i->what());
}
for (auto& output : b.outputs) {
auto derivers = store->queryValidDerivers(output.second);
if (derivers.empty())
if (derivers.empty()) {
throw Error("'%s' does not have a known deriver", i->what());
}
// FIXME: use all derivers?
drvPaths.insert(*derivers.begin());
}
} else
} else {
drvPaths.insert(b.drvPath);
}
}
}
return drvPaths;
}

View file

@ -35,17 +35,20 @@ struct MixLs : virtual Args, MixJSON {
? "lrwxrwxrwx"
: "dr-xr-xr-x";
std::cout << (format("%s %20d %s") % tp % st.fileSize % relPath);
if (st.type == FSAccessor::Type::tSymlink)
if (st.type == FSAccessor::Type::tSymlink) {
std::cout << " -> " << accessor->readLink(curPath);
}
std::cout << "\n";
if (recursive && st.type == FSAccessor::Type::tDirectory)
if (recursive && st.type == FSAccessor::Type::tDirectory) {
doPath(st, curPath, relPath, false);
}
} else {
std::cout << relPath << "\n";
if (recursive) {
auto st = accessor->stat(curPath);
if (st.type == FSAccessor::Type::tDirectory)
if (st.type == FSAccessor::Type::tDirectory) {
doPath(st, curPath, relPath, false);
}
}
}
};
@ -57,8 +60,9 @@ struct MixLs : virtual Args, MixJSON {
for (auto& name : names) {
showFile(curPath + "/" + name, relPath + "/" + name);
}
} else
} else {
showFile(curPath, relPath);
}
};
auto st = accessor->stat(path);

View file

@ -44,8 +44,9 @@ static bool haveInternet() {
}
} else if (i->ifa_addr->sa_family == AF_INET6) {
if (!IN6_IS_ADDR_LOOPBACK(&((sockaddr_in6*)i->ifa_addr)->sin6_addr) &&
!IN6_IS_ADDR_LINKLOCAL(&((sockaddr_in6*)i->ifa_addr)->sin6_addr))
!IN6_IS_ADDR_LINKLOCAL(&((sockaddr_in6*)i->ifa_addr)->sin6_addr)) {
return true;
}
}
}
@ -72,8 +73,9 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs {
Table2 tbl;
std::map<std::string, Config::SettingInfo> settings;
globalConfig.getSettings(settings);
for (const auto& s : settings)
for (const auto& s : settings) {
tbl.emplace_back(s.first, s.second.description);
}
printTable(std::cout, tbl);
throw Exit();
});
@ -159,13 +161,15 @@ void mainWrapped(int argc, char** argv) {
if (!settings.useSubstitutes.overriden) {
settings.useSubstitutes = false;
}
if (!settings.tarballTtl.overriden)
if (!settings.tarballTtl.overriden) {
settings.tarballTtl = std::numeric_limits<unsigned int>::max();
}
if (!downloadSettings.tries.overriden) {
downloadSettings.tries = 0;
}
if (!downloadSettings.connectTimeout.overriden)
if (!downloadSettings.connectTimeout.overriden) {
downloadSettings.connectTimeout = 1;
}
}
args.command->prepare();

View file

@ -75,8 +75,9 @@ struct CmdPathInfo : StorePathsCommand, MixJSON {
void run(ref<Store> store, Paths storePaths) override {
size_t pathLen = 0;
for (auto& storePath : storePaths)
for (auto& storePath : storePaths) {
pathLen = std::max(pathLen, storePath.size());
}
if (json) {
JSONPlaceholder jsonRoot(std::cout);
@ -93,9 +94,10 @@ struct CmdPathInfo : StorePathsCommand, MixJSON {
std::cout << storePath;
if (showSize || showClosureSize || showSigs)
if (showSize || showClosureSize || showSigs) {
std::cout << std::string(
std::max(0, (int)pathLen - (int)storePath.size()), ' ');
}
if (showSize) {
printSize(info->narSize);

View file

@ -181,8 +181,9 @@ static char* completionCallback(char* s, int* match) {
static int listPossibleCallback(char* s, char*** avp) {
auto possible = curRepl->completePrefix(s);
if (possible.size() > (INT_MAX / sizeof(char*)))
if (possible.size() > (INT_MAX / sizeof(char*))) {
throw Error("too many completions");
}
int ac = 0;
char** vp = nullptr;
@ -190,7 +191,9 @@ static int listPossibleCallback(char* s, char*** avp) {
auto check = [&](auto* p) {
if (!p) {
if (vp) {
while (--ac >= 0) free(vp[ac]);
while (--ac >= 0) {
free(vp[ac]);
}
free(vp);
}
throw Error("allocation failure");
@ -288,20 +291,24 @@ bool NixRepl::getLine(string& input, const std::string& prompt) {
act.sa_handler = sigintHandler;
sigfillset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(SIGINT, &act, &old))
if (sigaction(SIGINT, &act, &old)) {
throw SysError("installing handler for SIGINT");
}
sigemptyset(&set);
sigaddset(&set, SIGINT);
if (sigprocmask(SIG_UNBLOCK, &set, &savedSignalMask))
if (sigprocmask(SIG_UNBLOCK, &set, &savedSignalMask)) {
throw SysError("unblocking SIGINT");
}
};
auto restoreSignals = [&]() {
if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr))
if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr)) {
throw SysError("restoring signals");
}
if (sigaction(SIGINT, &old, 0))
if (sigaction(SIGINT, &old, 0)) {
throw SysError("restoring handler for SIGINT");
}
};
setupSignals();
@ -343,8 +350,9 @@ StringSet NixRepl::completePrefix(string prefix) {
auto dir = std::string(cur, 0, slash);
auto prefix2 = std::string(cur, slash + 1);
for (auto& entry : readDirectory(dir == "" ? "/" : dir)) {
if (entry.name[0] != '.' && hasPrefix(entry.name, prefix2))
if (entry.name[0] != '.' && hasPrefix(entry.name, prefix2)) {
completions.insert(prev + dir + "/" + entry.name);
}
}
} catch (Error&) {
}
@ -417,21 +425,25 @@ bool isVarName(const string& s) {
if ((c >= '0' && c <= '9') || c == '-' || c == '\'') {
return false;
}
for (auto& i : s)
for (auto& i : s) {
if (!((i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z') ||
(i >= '0' && i <= '9') || i == '_' || i == '-' || i == '\''))
(i >= '0' && i <= '9') || i == '_' || i == '-' || i == '\'')) {
return false;
}
}
return true;
}
Path NixRepl::getDerivationPath(Value& v) {
auto drvInfo = getDerivation(state, v, false);
if (!drvInfo)
if (!drvInfo) {
throw Error(
"expression does not evaluate to a derivation, so I can't build it");
}
Path drvPath = drvInfo->queryDrvPath();
if (drvPath == "" || !state.store->isValidPath(drvPath))
if (drvPath == "" || !state.store->isValidPath(drvPath)) {
throw Error("expression did not evaluate to a valid derivation");
}
return drvPath;
}
@ -520,9 +532,10 @@ bool NixRepl::processLine(string line) {
std::cout << std::endl
<< "this derivation produced the following outputs:"
<< std::endl;
for (auto& i : drv.outputs)
for (auto& i : drv.outputs) {
std::cout << format(" %1% -> %2%") % i.first % i.second.path
<< std::endl;
}
}
} else if (command == ":i") {
runProgram(settings.nixBinDir + "/nix-env", Strings{"-i", drvPath});
@ -537,13 +550,13 @@ bool NixRepl::processLine(string line) {
printValue(std::cout, v, 1000000000) << std::endl;
}
else if (command == ":q" || command == ":quit")
else if (command == ":q" || command == ":quit") {
return false;
else if (command != "")
} else if (command != "") {
throw Error(format("unknown command '%1%'") % command);
else {
} else {
size_t p = line.find('=');
string name;
if (p != string::npos && p < line.size() && line[p + 1] != '=' &&
@ -612,8 +625,9 @@ void NixRepl::addAttrsToScope(Value& attrs) {
}
void NixRepl::addVarToScope(const Symbol& name, Value& v) {
if (displ >= envSize)
if (displ >= envSize) {
throw Error("environment full; cannot add more variables");
}
staticEnv.vars[name] = displ;
env->values[displ++] = &v;
varNames.insert((string)name);
@ -638,17 +652,19 @@ std::ostream& NixRepl::printValue(std::ostream& str, Value& v,
std::ostream& printStringValue(std::ostream& str, const char* string) {
str << "\"";
for (const char* i = string; *i; i++)
if (*i == '\"' || *i == '\\')
for (const char* i = string; *i; i++) {
if (*i == '\"' || *i == '\\') {
str << "\\" << *i;
else if (*i == '\n')
} else if (*i == '\n') {
str << "\\n";
else if (*i == '\r')
} else if (*i == '\r') {
str << "\\r";
else if (*i == '\t')
} else if (*i == '\t') {
str << "\\t";
else
} else {
str << *i;
}
}
str << "\"";
return str;
}
@ -709,19 +725,21 @@ std::ostream& NixRepl::printValue(std::ostream& str, Value& v,
}
for (auto& i : sorted) {
if (isVarName(i.first))
if (isVarName(i.first)) {
str << i.first;
else
} else {
printStringValue(str, i.first.c_str());
}
str << " = ";
if (seen.find(i.second) != seen.end())
if (seen.find(i.second) != seen.end()) {
str << "«repeated»";
else
} else {
try {
printValue(str, *i.second, maxDepth - 1, seen);
} catch (AssertionError& e) {
str << ESC_RED "«error: " << e.msg() << "»" ESC_END;
}
}
str << "; ";
}
@ -741,14 +759,15 @@ std::ostream& NixRepl::printValue(std::ostream& str, Value& v,
str << "[ ";
if (maxDepth > 0) {
for (unsigned int n = 0; n < v.listSize(); ++n) {
if (seen.find(v.listElems()[n]) != seen.end())
if (seen.find(v.listElems()[n]) != seen.end()) {
str << "«repeated»";
else
} else {
try {
printValue(str, *v.listElems()[n], maxDepth - 1, seen);
} catch (AssertionError& e) {
str << ESC_RED "«error: " << e.msg() << "»" ESC_END;
}
}
str << " ";
}
} else {

View file

@ -31,8 +31,9 @@ struct CmdRun : InstallablesCommand {
.labels({"command", "args"})
.arity(ArityAny)
.handler([&](std::vector<std::string> ss) {
if (ss.empty())
if (ss.empty()) {
throw UsageError("--command requires at least one argument");
}
command = ss;
});
@ -87,9 +88,10 @@ struct CmdRun : InstallablesCommand {
auto accessor = store->getFSAccessor();
if (ignoreEnvironment) {
if (!unset.empty())
if (!unset.empty()) {
throw UsageError(
"--unset does not make sense with --ignore-environment");
}
std::map<std::string, std::string> kept;
for (auto& var : keep) {
@ -106,9 +108,10 @@ struct CmdRun : InstallablesCommand {
}
} else {
if (!keep.empty())
if (!keep.empty()) {
throw UsageError(
"--keep does not make sense without --ignore-environment");
}
for (auto& var : unset) {
unsetenv(var.c_str());
@ -191,17 +194,21 @@ void chrootHelper(int argc, char** argv) {
std::string realStoreDir = argv[p++];
std::string cmd = argv[p++];
Strings args;
while (p < argc) args.push_back(argv[p++]);
while (p < argc) {
args.push_back(argv[p++]);
}
#if __linux__
uid_t uid = getuid();
uid_t gid = getgid();
if (unshare(CLONE_NEWUSER | CLONE_NEWNS) == -1)
if (unshare(CLONE_NEWUSER | CLONE_NEWNS) == -1) {
/* Try with just CLONE_NEWNS in case user namespaces are
specifically disabled. */
if (unshare(CLONE_NEWNS) == -1)
if (unshare(CLONE_NEWNS) == -1) {
throw SysError("setting up a private mount namespace");
}
}
/* Bind-mount realStoreDir on /nix/store. If the latter mount
point doesn't already exists, we have to create a chroot
@ -218,8 +225,9 @@ void chrootHelper(int argc, char** argv) {
createDirs(tmpDir + storeDir);
if (mount(realStoreDir.c_str(), (tmpDir + storeDir).c_str(), "", MS_BIND,
0) == -1)
0) == -1) {
throw SysError("mounting '%s' on '%s'", realStoreDir, storeDir);
}
for (auto entry : readDirectory("/")) {
auto src = "/" + entry.name;
@ -231,10 +239,12 @@ void chrootHelper(int argc, char** argv) {
if (pathExists(dst)) {
continue;
}
if (mkdir(dst.c_str(), 0700) == -1)
if (mkdir(dst.c_str(), 0700) == -1) {
throw SysError("creating directory '%s'", dst);
if (mount(src.c_str(), dst.c_str(), "", MS_BIND | MS_REC, 0) == -1)
}
if (mount(src.c_str(), dst.c_str(), "", MS_BIND | MS_REC, 0) == -1) {
throw SysError("mounting '%s' on '%s'", src, dst);
}
}
char* cwd = getcwd(0, 0);
@ -243,14 +253,17 @@ void chrootHelper(int argc, char** argv) {
}
Finally freeCwd([&]() { free(cwd); });
if (chroot(tmpDir.c_str()) == -1)
if (chroot(tmpDir.c_str()) == -1) {
throw SysError(format("chrooting into '%s'") % tmpDir);
}
if (chdir(cwd) == -1)
if (chdir(cwd) == -1) {
throw SysError(format("chdir to '%s' in chroot") % cwd);
}
} else if (mount(realStoreDir.c_str(), storeDir.c_str(), "", MS_BIND, 0) ==
-1)
-1) {
throw SysError("mounting '%s' on '%s'", realStoreDir, storeDir);
}
writeFile("/proc/self/setgroups", "deny");
writeFile("/proc/self/uid_map", fmt("%d %d %d", uid, uid, 1));

View file

@ -251,13 +251,15 @@ struct CmdSearch : SourceExprCommand, MixJSON {
}
if (writeCache &&
rename(tmpFile.c_str(), jsonCacheFileName.c_str()) == -1)
rename(tmpFile.c_str(), jsonCacheFileName.c_str()) == -1) {
throw SysError("cannot rename '%s' to '%s'", tmpFile,
jsonCacheFileName);
}
}
if (results.size() == 0)
if (results.size() == 0) {
throw Error("no results for the given search term(s)!");
}
RunPager pager;
for (auto el : results) {

View file

@ -21,8 +21,9 @@ struct CmdShowConfig : Command, MixJSON {
} else {
std::map<std::string, Config::SettingInfo> settings;
globalConfig.getSettings(settings);
for (auto& s : settings)
for (auto& s : settings) {
std::cout << s.first + " = " + s.second.value + "\n";
}
}
}
};

View file

@ -31,8 +31,9 @@ struct CmdCopySigs : StorePathsCommand {
}
void run(ref<Store> store, Paths storePaths) override {
if (substituterUris.empty())
if (substituterUris.empty()) {
throw UsageError("you must specify at least one substituter using '-s'");
}
// FIXME: factor out commonality with MixVerify.
std::vector<ref<Store>> substituters;
@ -65,13 +66,15 @@ struct CmdCopySigs : StorePathsCommand {
binary. */
if (info->narHash != info2->narHash ||
info->narSize != info2->narSize ||
info->references != info2->references)
info->references != info2->references) {
continue;
}
for (auto& sig : info2->sigs)
for (auto& sig : info2->sigs) {
if (!info->sigs.count(sig)) {
newSigs.insert(sig);
}
}
} catch (InvalidPath&) {
}
}
@ -84,8 +87,9 @@ struct CmdCopySigs : StorePathsCommand {
// logger->incProgress(doneLabel);
};
for (auto& storePath : storePaths)
for (auto& storePath : storePaths) {
pool.enqueue(std::bind(doPath, storePath));
}
pool.process();
@ -112,8 +116,9 @@ struct CmdSignPaths : StorePathsCommand {
std::string description() override { return "sign the specified paths"; }
void run(ref<Store> store, Paths storePaths) override {
if (secretKeyFile.empty())
if (secretKeyFile.empty()) {
throw UsageError("you must specify a secret key file using '-k'");
}
SecretKey secretKey(readFile(secretKeyFile));

View file

@ -80,8 +80,9 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand {
LOG(INFO) << "verifying that '" << storePath << "' works...";
auto program = storePath + "/bin/nix-env";
auto s = runProgram(program, false, {"--version"});
if (s.find("Nix") == std::string::npos)
if (s.find("Nix") == std::string::npos) {
throw Error("could not verify that '%s' works", program);
}
}
{
@ -99,15 +100,17 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand {
Path getProfileDir(ref<Store> store) {
Path where;
for (auto& dir : tokenizeString<Strings>(getEnv("PATH"), ":"))
for (auto& dir : tokenizeString<Strings>(getEnv("PATH"), ":")) {
if (pathExists(dir + "/nix-env")) {
where = dir;
break;
}
}
if (where == "")
if (where == "") {
throw Error(
"couldn't figure out how Nix is installed, so I can't upgrade it");
}
LOG(INFO) << "found Nix in '" << where << "'";
@ -119,19 +122,22 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand {
// Resolve profile to /nix/var/nix/profiles/<name> link.
while (canonPath(profileDir).find("/profiles/") == std::string::npos &&
isLink(profileDir))
isLink(profileDir)) {
profileDir = readLink(profileDir);
}
LOG(INFO) << "found profile '" << profileDir << "'";
Path userEnv = canonPath(profileDir, true);
if (baseNameOf(where) != "bin" || !hasSuffix(userEnv, "user-environment"))
if (baseNameOf(where) != "bin" || !hasSuffix(userEnv, "user-environment")) {
throw Error("directory '%s' does not appear to be part of a Nix profile",
where);
}
if (!store->isValidPath(userEnv))
if (!store->isValidPath(userEnv)) {
throw Error("directory '%s' is not in the Nix store", userEnv);
}
return profileDir;
}

View file

@ -94,10 +94,10 @@ struct CmdVerify : StorePathsCommand {
if (!noTrust) {
bool good = false;
if (info->ultimate && !sigsNeeded)
if (info->ultimate && !sigsNeeded) {
good = true;
else {
} else {
StringSet sigsSeen;
size_t actualSigsNeeded = std::max(sigsNeeded, (size_t)1);
size_t validSigs = 0;
@ -109,13 +109,15 @@ struct CmdVerify : StorePathsCommand {
}
sigsSeen.insert(sig);
if (validSigs < ValidPathInfo::maxSigs &&
info->checkSignature(publicKeys, sig))
info->checkSignature(publicKeys, sig)) {
validSigs++;
}
}
};
if (info->isContentAddressed(*store))
if (info->isContentAddressed(*store)) {
validSigs = ValidPathInfo::maxSigs;
}
doSigs(info->sigs);
@ -125,8 +127,9 @@ struct CmdVerify : StorePathsCommand {
}
try {
auto info2 = store2->queryPathInfo(info->path);
if (info2->isContentAddressed(*store))
if (info2->isContentAddressed(*store)) {
validSigs = ValidPathInfo::maxSigs;
}
doSigs(info2->sigs);
} catch (InvalidPath&) {
} catch (Error& e) {
@ -153,8 +156,9 @@ struct CmdVerify : StorePathsCommand {
}
};
for (auto& storePath : storePaths)
for (auto& storePath : storePaths) {
pool.enqueue(std::bind(doPath, storePath));
}
pool.process();

View file

@ -92,14 +92,16 @@ struct CmdWhyDepends : SourceExprCommand {
std::map<Path, Node> graph;
for (auto& path : closure)
for (auto& path : closure) {
graph.emplace(path, Node{path, store->queryPathInfo(path)->references});
}
// Transpose the graph.
for (auto& node : graph)
for (auto& node : graph) {
for (auto& ref : node.second.refs) {
graph[ref].rrefs.insert(node.first);
}
}
/* Run Dijkstra's shortest path algorithm to get the distance
of every path in the closure to 'dependency'. */
@ -146,8 +148,10 @@ struct CmdWhyDepends : SourceExprCommand {
node.visited ? "\e[38;5;244m" : "",
firstPad != "" ? "=> " : "", node.path);
if (node.path == dependencyPath && !all && packagePath != dependencyPath)
if (node.path == dependencyPath && !all &&
packagePath != dependencyPath) {
throw BailOut();
}
if (node.visited) {
return;
@ -216,10 +220,11 @@ struct CmdWhyDepends : SourceExprCommand {
for (auto& hash : hashes) {
auto pos = target.find(hash);
if (pos != std::string::npos)
if (pos != std::string::npos) {
hits[hash].emplace_back(
fmt("%s -> %s\n", p2,
hilite(target, pos, storePathHashLen, getColour(hash))));
}
}
}
};