forked from lix-project/lix
remove 'format' from Error constructor calls
This commit is contained in:
parent
d3052197fe
commit
e4fb9a3849
52 changed files with 424 additions and 407 deletions
|
@ -19,7 +19,7 @@ static Strings parseAttrPath(const string & s)
|
||||||
++i;
|
++i;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (i == s.end())
|
if (i == s.end())
|
||||||
throw Error(format("missing closing quote in selection path '%1%'") % s);
|
throw Error("missing closing quote in selection path '%1%'", s);
|
||||||
if (*i == '"') break;
|
if (*i == '"') break;
|
||||||
cur.push_back(*i++);
|
cur.push_back(*i++);
|
||||||
}
|
}
|
||||||
|
@ -60,11 +60,11 @@ std::pair<Value *, Pos> findAlongAttrPath(EvalState & state, const string & attr
|
||||||
|
|
||||||
if (v->type != tAttrs)
|
if (v->type != tAttrs)
|
||||||
throw TypeError(
|
throw TypeError(
|
||||||
format("the expression selected by the selection path '%1%' should be a set but is %2%")
|
"the expression selected by the selection path '%1%' should be a set but is %2%",
|
||||||
% attrPath % showType(*v));
|
attrPath,
|
||||||
|
showType(*v));
|
||||||
if (attr.empty())
|
if (attr.empty())
|
||||||
throw Error(format("empty attribute name in selection path '%1%'") % attrPath);
|
throw Error("empty attribute name in selection path '%1%'", attrPath);
|
||||||
|
|
||||||
Bindings::iterator a = v->attrs->find(state.symbols.create(attr));
|
Bindings::iterator a = v->attrs->find(state.symbols.create(attr));
|
||||||
if (a == v->attrs->end())
|
if (a == v->attrs->end())
|
||||||
|
@ -77,9 +77,9 @@ std::pair<Value *, Pos> findAlongAttrPath(EvalState & state, const string & attr
|
||||||
|
|
||||||
if (!v->isList())
|
if (!v->isList())
|
||||||
throw TypeError(
|
throw TypeError(
|
||||||
format("the expression selected by the selection path '%1%' should be a list but is %2%")
|
"the expression selected by the selection path '%1%' should be a list but is %2%",
|
||||||
% attrPath % showType(*v));
|
attrPath,
|
||||||
|
showType(*v));
|
||||||
if (attrIndex >= v->listSize())
|
if (attrIndex >= v->listSize())
|
||||||
throw AttrPathNotFound("list index %1% in selection path '%2%' is out of range", attrIndex, attrPath);
|
throw AttrPathNotFound("list index %1% in selection path '%2%' is out of range", attrIndex, attrPath);
|
||||||
|
|
||||||
|
|
|
@ -9,18 +9,18 @@ namespace nix {
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const char * s, const Pos & pos))
|
LocalNoInlineNoReturn(void throwEvalError(const char * s, const Pos & pos))
|
||||||
{
|
{
|
||||||
throw EvalError(format(s) % pos);
|
throw EvalError(s, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v))
|
LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v))
|
||||||
{
|
{
|
||||||
throw TypeError(format(s) % showType(v));
|
throw TypeError(s, showType(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v, const Pos & pos))
|
LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v, const Pos & pos))
|
||||||
{
|
{
|
||||||
throw TypeError(format(s) % showType(v) % pos);
|
throw TypeError(s, showType(v), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -493,52 +493,52 @@ Value & EvalState::getBuiltin(const string & name)
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2))
|
LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2))
|
||||||
{
|
{
|
||||||
throw EvalError(format(s) % s2);
|
throw EvalError(s, s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const Pos & pos))
|
LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const Pos & pos))
|
||||||
{
|
{
|
||||||
throw EvalError(format(s) % s2 % pos);
|
throw EvalError(s, s2, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3))
|
LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3))
|
||||||
{
|
{
|
||||||
throw EvalError(format(s) % s2 % s3);
|
throw EvalError(s, s2, s3);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, const Pos & pos))
|
LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, const Pos & pos))
|
||||||
{
|
{
|
||||||
throw EvalError(format(s) % s2 % s3 % pos);
|
throw EvalError(s, s2, s3, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, const Pos & p1, const Pos & p2))
|
LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, const Pos & p1, const Pos & p2))
|
||||||
{
|
{
|
||||||
throw EvalError(format(s) % sym % p1 % p2);
|
throw EvalError(s, sym, p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwTypeError(const char * s, const Pos & pos))
|
LocalNoInlineNoReturn(void throwTypeError(const char * s, const Pos & pos))
|
||||||
{
|
{
|
||||||
throw TypeError(format(s) % pos);
|
throw TypeError(s, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1))
|
LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1))
|
||||||
{
|
{
|
||||||
throw TypeError(format(s) % s1);
|
throw TypeError(s, s1);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwTypeError(const char * s, const ExprLambda & fun, const Symbol & s2, const Pos & pos))
|
LocalNoInlineNoReturn(void throwTypeError(const char * s, const ExprLambda & fun, const Symbol & s2, const Pos & pos))
|
||||||
{
|
{
|
||||||
throw TypeError(format(s) % fun.showNamePos() % s2 % pos);
|
throw TypeError(s, fun.showNamePos(), s2, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwAssertionError(const char * s, const string & s1, const Pos & pos))
|
LocalNoInlineNoReturn(void throwAssertionError(const char * s, const string & s1, const Pos & pos))
|
||||||
{
|
{
|
||||||
throw AssertionError(format(s) % s1 % pos);
|
throw AssertionError(s, s1, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwUndefinedVarError(const char * s, const string & s1, const Pos & pos))
|
LocalNoInlineNoReturn(void throwUndefinedVarError(const char * s, const string & s1, const Pos & pos))
|
||||||
{
|
{
|
||||||
throw UndefinedVarError(format(s) % s1 % pos);
|
throw UndefinedVarError(s, s1, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInline(void addErrorPrefix(Error & e, const char * s, const string & s2))
|
LocalNoInline(void addErrorPrefix(Error & e, const char * s, const string & s2))
|
||||||
|
@ -1883,8 +1883,7 @@ void EvalState::printStats()
|
||||||
|
|
||||||
string ExternalValueBase::coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore) const
|
string ExternalValueBase::coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore) const
|
||||||
{
|
{
|
||||||
throw TypeError(format("cannot coerce %1% to a string, at %2%") %
|
throw TypeError("cannot coerce %1% to a string, at %2%", showType(), pos);
|
||||||
showType() % pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -267,7 +267,7 @@ void ExprVar::bindVars(const StaticEnv & env)
|
||||||
/* Otherwise, the variable must be obtained from the nearest
|
/* Otherwise, the variable must be obtained from the nearest
|
||||||
enclosing `with'. If there is no `with', then we can issue an
|
enclosing `with'. If there is no `with', then we can issue an
|
||||||
"undefined variable" error now. */
|
"undefined variable" error now. */
|
||||||
if (withLevel == -1) throw UndefinedVarError(format("undefined variable '%1%' at %2%") % name % pos);
|
if (withLevel == -1) throw UndefinedVarError("undefined variable '%1%' at %2%", name, pos);
|
||||||
|
|
||||||
fromWith = true;
|
fromWith = true;
|
||||||
this->level = withLevel;
|
this->level = withLevel;
|
||||||
|
|
|
@ -234,9 +234,7 @@ struct ExprLambda : Expr
|
||||||
: pos(pos), arg(arg), matchAttrs(matchAttrs), formals(formals), body(body)
|
: pos(pos), arg(arg), matchAttrs(matchAttrs), formals(formals), body(body)
|
||||||
{
|
{
|
||||||
if (!arg.empty() && formals && formals->argNames.find(arg) != formals->argNames.end())
|
if (!arg.empty() && formals && formals->argNames.find(arg) != formals->argNames.end())
|
||||||
throw ParseError(format("duplicate formal function argument '%1%' at %2%")
|
throw ParseError("duplicate formal function argument '%1%' at %2%", arg, pos); };
|
||||||
% arg % pos);
|
|
||||||
};
|
|
||||||
void setName(Symbol & name);
|
void setName(Symbol & name);
|
||||||
string showNamePos() const;
|
string showNamePos() const;
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
|
|
@ -64,15 +64,15 @@ namespace nix {
|
||||||
|
|
||||||
static void dupAttr(const AttrPath & attrPath, const Pos & pos, const Pos & prevPos)
|
static void dupAttr(const AttrPath & attrPath, const Pos & pos, const Pos & prevPos)
|
||||||
{
|
{
|
||||||
throw ParseError(format("attribute '%1%' at %2% already defined at %3%")
|
throw ParseError("attribute '%1%' at %2% already defined at %3%",
|
||||||
% showAttrPath(attrPath) % pos % prevPos);
|
showAttrPath(attrPath), pos, prevPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dupAttr(Symbol attr, const Pos & pos, const Pos & prevPos)
|
static void dupAttr(Symbol attr, const Pos & pos, const Pos & prevPos)
|
||||||
{
|
{
|
||||||
throw ParseError(format("attribute '%1%' at %2% already defined at %3%")
|
throw ParseError("attribute '%1%' at %2% already defined at %3%",
|
||||||
% attr % pos % prevPos);
|
attr, pos, prevPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,8 +140,8 @@ static void addAttr(ExprAttrs * attrs, AttrPath & attrPath,
|
||||||
static void addFormal(const Pos & pos, Formals * formals, const Formal & formal)
|
static void addFormal(const Pos & pos, Formals * formals, const Formal & formal)
|
||||||
{
|
{
|
||||||
if (!formals->argNames.insert(formal.name).second)
|
if (!formals->argNames.insert(formal.name).second)
|
||||||
throw ParseError(format("duplicate formal function argument '%1%' at %2%")
|
throw ParseError("duplicate formal function argument '%1%' at %2%",
|
||||||
% formal.name % pos);
|
formal.name, pos);
|
||||||
formals->formals.push_front(formal);
|
formals->formals.push_front(formal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,8 +327,7 @@ expr_function
|
||||||
{ $$ = new ExprWith(CUR_POS, $2, $4); }
|
{ $$ = new ExprWith(CUR_POS, $2, $4); }
|
||||||
| LET binds IN expr_function
|
| LET binds IN expr_function
|
||||||
{ if (!$2->dynamicAttrs.empty())
|
{ if (!$2->dynamicAttrs.empty())
|
||||||
throw ParseError(format("dynamic attributes not allowed in let at %1%")
|
throw ParseError("dynamic attributes not allowed in let at %1%", CUR_POS);
|
||||||
% CUR_POS);
|
|
||||||
$$ = new ExprLet($2, $4);
|
$$ = new ExprLet($2, $4);
|
||||||
}
|
}
|
||||||
| expr_if
|
| expr_if
|
||||||
|
@ -475,8 +474,8 @@ attrs
|
||||||
$$->push_back(AttrName(str->s));
|
$$->push_back(AttrName(str->s));
|
||||||
delete str;
|
delete str;
|
||||||
} else
|
} else
|
||||||
throw ParseError(format("dynamic attributes not allowed in inherit at %1%")
|
throw ParseError("dynamic attributes not allowed in inherit at %1%",
|
||||||
% makeCurPos(@2, data));
|
makeCurPos(@2, data));
|
||||||
}
|
}
|
||||||
| { $$ = new AttrPath; }
|
| { $$ = new AttrPath; }
|
||||||
;
|
;
|
||||||
|
@ -670,11 +669,10 @@ Path EvalState::findFile(SearchPath & searchPath, const string & path, const Pos
|
||||||
Path res = r.second + suffix;
|
Path res = r.second + suffix;
|
||||||
if (pathExists(res)) return canonPath(res);
|
if (pathExists(res)) return canonPath(res);
|
||||||
}
|
}
|
||||||
format f = format(
|
string f =
|
||||||
"file '%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)"
|
"file '%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)"
|
||||||
+ string(pos ? ", at %2%" : ""));
|
+ string(pos ? ", at %2%" : "");
|
||||||
f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
|
throw ThrownError(f, path, pos);
|
||||||
throw ThrownError(f % path % pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -691,7 +689,8 @@ std::pair<bool, std::string> EvalState::resolveSearchPathElem(const SearchPathEl
|
||||||
request.unpack = true;
|
request.unpack = true;
|
||||||
res = { true, getDownloader()->downloadCached(store, request).path };
|
res = { true, getDownloader()->downloadCached(store, request).path };
|
||||||
} catch (DownloadError & e) {
|
} catch (DownloadError & e) {
|
||||||
printError(format("warning: Nix search path entry '%1%' cannot be downloaded, ignoring") % elem.second);
|
// TODO: change to warn()?
|
||||||
|
printError("warning: Nix search path entry '%1%' cannot be downloaded, ignoring", elem.second);
|
||||||
res = { false, "" };
|
res = { false, "" };
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -699,7 +698,8 @@ std::pair<bool, std::string> EvalState::resolveSearchPathElem(const SearchPathEl
|
||||||
if (pathExists(path))
|
if (pathExists(path))
|
||||||
res = { true, path };
|
res = { true, path };
|
||||||
else {
|
else {
|
||||||
printError(format("warning: Nix search path entry '%1%' does not exist, ignoring") % elem.second);
|
// TODO: change to warn()?
|
||||||
|
printError("warning: Nix search path entry '%1%' does not exist, ignoring", elem.second);
|
||||||
res = { false, "" };
|
res = { false, "" };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,8 +94,8 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
|
||||||
try {
|
try {
|
||||||
state.realiseContext(context);
|
state.realiseContext(context);
|
||||||
} catch (InvalidPathError & e) {
|
} catch (InvalidPathError & e) {
|
||||||
throw EvalError(format("cannot import '%1%', since path '%2%' is not valid, at %3%")
|
throw EvalError("cannot import '%1%', since path '%2%' is not valid, at %3%",
|
||||||
% path % e.path % pos);
|
path, e.path, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
Path realPath = state.checkSourcePath(state.toRealPath(path, context));
|
Path realPath = state.checkSourcePath(state.toRealPath(path, context));
|
||||||
|
@ -171,8 +171,8 @@ void prim_importNative(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
try {
|
try {
|
||||||
state.realiseContext(context);
|
state.realiseContext(context);
|
||||||
} catch (InvalidPathError & e) {
|
} catch (InvalidPathError & e) {
|
||||||
throw EvalError(format("cannot import '%1%', since path '%2%' is not valid, at %3%")
|
throw EvalError("cannot import '%1%', since path '%2%' is not valid, at %3%"
|
||||||
% path % e.path % pos);
|
, path, e.path, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = state.checkSourcePath(path);
|
path = state.checkSourcePath(path);
|
||||||
|
@ -181,17 +181,17 @@ void prim_importNative(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
|
|
||||||
void *handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
void *handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
||||||
if (!handle)
|
if (!handle)
|
||||||
throw EvalError(format("could not open '%1%': %2%") % path % dlerror());
|
throw EvalError("could not open '%1%': %2%", path, dlerror());
|
||||||
|
|
||||||
dlerror();
|
dlerror();
|
||||||
ValueInitializer func = (ValueInitializer) dlsym(handle, sym.c_str());
|
ValueInitializer func = (ValueInitializer) dlsym(handle, sym.c_str());
|
||||||
if(!func) {
|
if(!func) {
|
||||||
char *message = dlerror();
|
char *message = dlerror();
|
||||||
if (message)
|
if (message)
|
||||||
throw EvalError(format("could not load symbol '%1%' from '%2%': %3%") % sym % path % message);
|
throw EvalError("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")
|
throw EvalError("symbol '%1%' from '%2%' resolved to NULL when a function pointer was expected"
|
||||||
% sym % path);
|
, sym, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
(func)(state, v);
|
(func)(state, v);
|
||||||
|
@ -207,7 +207,7 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
auto elems = args[0]->listElems();
|
auto elems = args[0]->listElems();
|
||||||
auto count = args[0]->listSize();
|
auto count = args[0]->listSize();
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
throw EvalError(format("at least one argument to 'exec' required, at %1%") % pos);
|
throw EvalError("at least one argument to 'exec' required, at %1%", pos);
|
||||||
}
|
}
|
||||||
PathSet context;
|
PathSet context;
|
||||||
auto program = state.coerceToString(pos, *elems[0], context, false, false);
|
auto program = state.coerceToString(pos, *elems[0], context, false, false);
|
||||||
|
@ -218,8 +218,8 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
try {
|
try {
|
||||||
state.realiseContext(context);
|
state.realiseContext(context);
|
||||||
} catch (InvalidPathError & e) {
|
} catch (InvalidPathError & e) {
|
||||||
throw EvalError(format("cannot execute '%1%', since path '%2%' is not valid, at %3%")
|
throw EvalError("cannot execute '%1%', since path '%2%' is not valid, at %3%"
|
||||||
% program % e.path % pos);
|
, program, e.path, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto output = runProgram(program, true, commandArgs);
|
auto output = runProgram(program, true, commandArgs);
|
||||||
|
@ -227,13 +227,13 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
try {
|
try {
|
||||||
parsed = state.parseExprFromString(output, pos.file);
|
parsed = state.parseExprFromString(output, pos.file);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addPrefix(format("While parsing the output from '%1%', at %2%\n") % program % pos);
|
e.addPrefix(fmt("While parsing the output from '%1%', at %2%\n", program, pos));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
state.eval(parsed, v);
|
state.eval(parsed, v);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addPrefix(format("While evaluating the output from '%1%', at %2%\n") % program % pos);
|
e.addPrefix(fmt("While evaluating the output from '%1%', at %2%\n", program, pos));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,7 @@ struct CompareValues
|
||||||
if (v1->type == tInt && v2->type == tFloat)
|
if (v1->type == tInt && v2->type == tFloat)
|
||||||
return v1->integer < v2->fpoint;
|
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));
|
throw EvalError("cannot compare %1% with %2%", showType(*v1), showType(*v2));
|
||||||
switch (v1->type) {
|
switch (v1->type) {
|
||||||
case tInt:
|
case tInt:
|
||||||
return v1->integer < v2->integer;
|
return v1->integer < v2->integer;
|
||||||
|
@ -350,7 +350,7 @@ struct CompareValues
|
||||||
case tPath:
|
case tPath:
|
||||||
return strcmp(v1->path, v2->path) < 0;
|
return strcmp(v1->path, v2->path) < 0;
|
||||||
default:
|
default:
|
||||||
throw EvalError(format("cannot compare %1% with %2%") % showType(*v1) % showType(*v2));
|
throw EvalError("cannot compare %1% with %2%", showType(*v1), showType(*v2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -371,7 +371,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
|
||||||
Bindings::iterator startSet =
|
Bindings::iterator startSet =
|
||||||
args[0]->attrs->find(state.symbols.create("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);
|
throw EvalError("attribute 'startSet' required, at %1%", pos);
|
||||||
state.forceList(*startSet->value, pos);
|
state.forceList(*startSet->value, pos);
|
||||||
|
|
||||||
ValueList workSet;
|
ValueList workSet;
|
||||||
|
@ -382,7 +382,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
|
||||||
Bindings::iterator op =
|
Bindings::iterator op =
|
||||||
args[0]->attrs->find(state.symbols.create("operator"));
|
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);
|
throw EvalError("attribute 'operator' required, at %1%", pos);
|
||||||
state.forceValue(*op->value);
|
state.forceValue(*op->value);
|
||||||
|
|
||||||
/* Construct the closure by applying the operator to element of
|
/* Construct the closure by applying the operator to element of
|
||||||
|
@ -401,7 +401,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
|
||||||
Bindings::iterator key =
|
Bindings::iterator key =
|
||||||
e->attrs->find(state.symbols.create("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);
|
throw EvalError("attribute 'key' required, at %1%", pos);
|
||||||
state.forceValue(*key->value);
|
state.forceValue(*key->value);
|
||||||
|
|
||||||
if (!doneKeys.insert(key->value).second) continue;
|
if (!doneKeys.insert(key->value).second) continue;
|
||||||
|
@ -431,7 +431,7 @@ static void prim_abort(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string s = state.coerceToString(pos, *args[0], context);
|
string s = state.coerceToString(pos, *args[0], context);
|
||||||
throw Abort(format("evaluation aborted with the following error message: '%1%'") % s);
|
throw Abort("evaluation aborted with the following error message: '%1%'", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -506,9 +506,9 @@ static void prim_trace(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0]);
|
||||||
if (args[0]->type == tString)
|
if (args[0]->type == tString)
|
||||||
printError(format("trace: %1%") % args[0]->string.s);
|
printError("trace: %1%", args[0]->string.s);
|
||||||
else
|
else
|
||||||
printError(format("trace: %1%") % *args[0]);
|
printError("trace: %1%", *args[0]);
|
||||||
state.forceValue(*args[1]);
|
state.forceValue(*args[1]);
|
||||||
v = *args[1];
|
v = *args[1];
|
||||||
}
|
}
|
||||||
|
@ -533,13 +533,13 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
/* Figure out the name first (for stack backtraces). */
|
/* Figure out the name first (for stack backtraces). */
|
||||||
Bindings::iterator attr = args[0]->attrs->find(state.sName);
|
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);
|
throw EvalError("required attribute 'name' missing, at %1%", pos);
|
||||||
string drvName;
|
string drvName;
|
||||||
Pos & posDrvName(*attr->pos);
|
Pos & posDrvName(*attr->pos);
|
||||||
try {
|
try {
|
||||||
drvName = state.forceStringNoCtx(*attr->value, pos);
|
drvName = state.forceStringNoCtx(*attr->value, pos);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addPrefix(format("while evaluating the derivation attribute 'name' at %1%:\n") % posDrvName);
|
e.addPrefix(fmt("while evaluating the derivation attribute 'name' at %1%:\n", posDrvName));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,18 +583,18 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
outputs.clear();
|
outputs.clear();
|
||||||
for (auto & j : ss) {
|
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);
|
throw EvalError("duplicate derivation output '%1%', at %2%", j, posDrvName);
|
||||||
/* !!! Check whether j is a valid attribute
|
/* !!! Check whether j is a valid attribute
|
||||||
name. */
|
name. */
|
||||||
/* Derivations cannot be named ‘drv’, because
|
/* Derivations cannot be named ‘drv’, because
|
||||||
then we'd have an attribute ‘drvPath’ in
|
then we'd have an attribute ‘drvPath’ in
|
||||||
the resulting set. */
|
the resulting set. */
|
||||||
if (j == "drv")
|
if (j == "drv")
|
||||||
throw EvalError(format("invalid derivation output name 'drv', at %1%") % posDrvName);
|
throw EvalError("invalid derivation output name 'drv', at %1%", posDrvName);
|
||||||
outputs.insert(j);
|
outputs.insert(j);
|
||||||
}
|
}
|
||||||
if (outputs.empty())
|
if (outputs.empty())
|
||||||
throw EvalError(format("derivation cannot have an empty set of outputs, at %1%") % posDrvName);
|
throw EvalError("derivation cannot have an empty set of outputs, at %1%", posDrvName);
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -706,9 +706,9 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
|
|
||||||
/* Do we have all required attributes? */
|
/* Do we have all required attributes? */
|
||||||
if (drv.builder == "")
|
if (drv.builder == "")
|
||||||
throw EvalError(format("required attribute 'builder' missing, at %1%") % posDrvName);
|
throw EvalError("required attribute 'builder' missing, at %1%", posDrvName);
|
||||||
if (drv.platform == "")
|
if (drv.platform == "")
|
||||||
throw EvalError(format("required attribute 'system' missing, at %1%") % posDrvName);
|
throw EvalError("required attribute 'system' missing, at %1%", posDrvName);
|
||||||
|
|
||||||
/* Check whether the derivation name is valid. */
|
/* Check whether the derivation name is valid. */
|
||||||
if (isDerivation(drvName))
|
if (isDerivation(drvName))
|
||||||
|
@ -717,7 +717,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
if (outputHash) {
|
if (outputHash) {
|
||||||
/* Handle fixed-output derivations. */
|
/* 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);
|
throw Error("multiple outputs are not supported in fixed-output derivations, at %1%", posDrvName);
|
||||||
|
|
||||||
HashType ht = outputHashAlgo.empty() ? htUnknown : parseHashType(outputHashAlgo);
|
HashType ht = outputHashAlgo.empty() ? htUnknown : parseHashType(outputHashAlgo);
|
||||||
Hash h(*outputHash, ht);
|
Hash h(*outputHash, ht);
|
||||||
|
@ -818,7 +818,7 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V
|
||||||
e.g. nix-push does the right thing. */
|
e.g. nix-push does the right thing. */
|
||||||
if (!state.store->isStorePath(path)) path = canonPath(path, true);
|
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);
|
throw EvalError("path '%1%' is not in the Nix store, at %2%", path, pos);
|
||||||
Path path2 = state.store->toStorePath(path);
|
Path path2 = state.store->toStorePath(path);
|
||||||
if (!settings.readOnlyMode)
|
if (!settings.readOnlyMode)
|
||||||
state.store->ensurePath(state.store->parseStorePath(path2));
|
state.store->ensurePath(state.store->parseStorePath(path2));
|
||||||
|
@ -834,9 +834,9 @@ static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args,
|
||||||
try {
|
try {
|
||||||
state.realiseContext(context);
|
state.realiseContext(context);
|
||||||
} catch (InvalidPathError & e) {
|
} catch (InvalidPathError & e) {
|
||||||
throw EvalError(format(
|
throw EvalError(
|
||||||
"cannot check the existence of '%1%', since path '%2%' is not valid, at %3%")
|
"cannot check the existence of '%1%', since path '%2%' is not valid, at %3%",
|
||||||
% path % e.path % pos);
|
path, e.path, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -879,12 +879,12 @@ static void prim_readFile(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
try {
|
try {
|
||||||
state.realiseContext(context);
|
state.realiseContext(context);
|
||||||
} catch (InvalidPathError & e) {
|
} catch (InvalidPathError & e) {
|
||||||
throw EvalError(format("cannot read '%1%', since path '%2%' is not valid, at %3%")
|
throw EvalError("cannot read '%1%', since path '%2%' is not valid, at %3%"
|
||||||
% path % e.path % pos);
|
, path, e.path, pos);
|
||||||
}
|
}
|
||||||
string s = readFile(state.checkSourcePath(state.toRealPath(path, context)));
|
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);
|
throw Error("the contents of the file '%1%' cannot be represented as a Nix string", path);
|
||||||
mkString(v, s.c_str());
|
mkString(v, s.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -908,7 +908,7 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
|
|
||||||
i = v2.attrs->find(state.symbols.create("path"));
|
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);
|
throw EvalError("attribute 'path' missing, at %1%", pos);
|
||||||
|
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string path = state.coerceToString(pos, *i->value, context, false, false);
|
string path = state.coerceToString(pos, *i->value, context, false, false);
|
||||||
|
@ -916,8 +916,8 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
try {
|
try {
|
||||||
state.realiseContext(context);
|
state.realiseContext(context);
|
||||||
} catch (InvalidPathError & e) {
|
} catch (InvalidPathError & e) {
|
||||||
throw EvalError(format("cannot find '%1%', since path '%2%' is not valid, at %3%")
|
throw EvalError("cannot find '%1%', since path '%2%' is not valid, at %3%",
|
||||||
% path % e.path % pos);
|
path, e.path, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
searchPath.emplace_back(prefix, path);
|
searchPath.emplace_back(prefix, path);
|
||||||
|
@ -934,7 +934,7 @@ static void prim_hashFile(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
string type = state.forceStringNoCtx(*args[0], pos);
|
string type = state.forceStringNoCtx(*args[0], pos);
|
||||||
HashType ht = parseHashType(type);
|
HashType ht = parseHashType(type);
|
||||||
if (ht == htUnknown)
|
if (ht == htUnknown)
|
||||||
throw Error(format("unknown hash type '%1%', at %2%") % type % pos);
|
throw Error("unknown hash type '%1%', at %2%", type, pos);
|
||||||
|
|
||||||
PathSet context; // discarded
|
PathSet context; // discarded
|
||||||
Path p = state.coerceToPath(pos, *args[1], context);
|
Path p = state.coerceToPath(pos, *args[1], context);
|
||||||
|
@ -950,8 +950,8 @@ static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Val
|
||||||
try {
|
try {
|
||||||
state.realiseContext(ctx);
|
state.realiseContext(ctx);
|
||||||
} catch (InvalidPathError & e) {
|
} catch (InvalidPathError & e) {
|
||||||
throw EvalError(format("cannot read '%1%', since path '%2%' is not valid, at %3%")
|
throw EvalError("cannot read '%1%', since path '%2%' is not valid, at %3%",
|
||||||
% path % e.path % pos);
|
path, e.path, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
DirEntries entries = readDirectory(state.checkSourcePath(path));
|
DirEntries entries = readDirectory(state.checkSourcePath(path));
|
||||||
|
@ -1021,7 +1021,7 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu
|
||||||
|
|
||||||
for (auto path : context) {
|
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);
|
throw EvalError("in 'toFile': the file '%1%' cannot refer to derivation outputs, at %2%", name, pos);
|
||||||
refs.insert(state.store->parseStorePath(path));
|
refs.insert(state.store->parseStorePath(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1089,11 +1089,11 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = state.coerceToPath(pos, *args[1], 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);
|
throw EvalError("string '%1%' cannot refer to other paths, at %2%", path, pos);
|
||||||
|
|
||||||
state.forceValue(*args[0]);
|
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);
|
throw TypeError("first argument in call to 'filterSource' is not a function but %1%, at %2%", showType(*args[0]), pos);
|
||||||
|
|
||||||
addPath(state, pos, std::string(baseNameOf(path)), path, args[0], true, Hash(), v);
|
addPath(state, pos, std::string(baseNameOf(path)), path, args[0], true, Hash(), v);
|
||||||
}
|
}
|
||||||
|
@ -1113,7 +1113,7 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
PathSet context;
|
PathSet context;
|
||||||
path = state.coerceToPath(*attr.pos, *attr.value, 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);
|
throw EvalError("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);
|
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||||
else if (n == "filter") {
|
else if (n == "filter") {
|
||||||
|
@ -1124,10 +1124,10 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
else if (n == "sha256")
|
else if (n == "sha256")
|
||||||
expectedHash = Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256);
|
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);
|
throw EvalError("unsupported argument '%1%' to 'addPath', at %2%", attr.name, *attr.pos);
|
||||||
}
|
}
|
||||||
if (path.empty())
|
if (path.empty())
|
||||||
throw EvalError(format("'path' required, at %1%") % pos);
|
throw EvalError("'path' required, at %1%", pos);
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
name = baseNameOf(path);
|
name = baseNameOf(path);
|
||||||
|
|
||||||
|
@ -1185,7 +1185,7 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
// !!! Should we create a symbol here or just do a lookup?
|
// !!! Should we create a symbol here or just do a lookup?
|
||||||
Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
|
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);
|
throw EvalError("attribute '%1%' missing, at %2%", attr, pos);
|
||||||
// !!! add to stack trace?
|
// !!! add to stack trace?
|
||||||
if (state.countCalls && i->pos) state.attrSelects[*i->pos]++;
|
if (state.countCalls && i->pos) state.attrSelects[*i->pos]++;
|
||||||
state.forceValue(*i->value);
|
state.forceValue(*i->value);
|
||||||
|
@ -1265,14 +1265,14 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args,
|
||||||
|
|
||||||
Bindings::iterator j = v2.attrs->find(state.sName);
|
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);
|
throw TypeError("'name' attribute missing in a call to 'listToAttrs', at %1%", pos);
|
||||||
string name = state.forceStringNoCtx(*j->value, pos);
|
string name = state.forceStringNoCtx(*j->value, pos);
|
||||||
|
|
||||||
Symbol sym = state.symbols.create(name);
|
Symbol sym = state.symbols.create(name);
|
||||||
if (seen.insert(sym).second) {
|
if (seen.insert(sym).second) {
|
||||||
Bindings::iterator j2 = v2.attrs->find(state.symbols.create(state.sValue));
|
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);
|
throw TypeError("'value' attribute missing in a call to 'listToAttrs', at %1%", pos);
|
||||||
|
|
||||||
v.attrs->push_back(Attr(sym, j2->value, j2->pos));
|
v.attrs->push_back(Attr(sym, j2->value, j2->pos));
|
||||||
}
|
}
|
||||||
|
@ -1346,7 +1346,7 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0]);
|
||||||
if (args[0]->type != tLambda)
|
if (args[0]->type != tLambda)
|
||||||
throw TypeError(format("'functionArgs' requires a function, at %1%") % pos);
|
throw TypeError("'functionArgs' requires a function, at %1%", pos);
|
||||||
|
|
||||||
if (!args[0]->lambda.fun->matchAttrs) {
|
if (!args[0]->lambda.fun->matchAttrs) {
|
||||||
state.mkAttrs(v, 0);
|
state.mkAttrs(v, 0);
|
||||||
|
@ -1396,7 +1396,7 @@ static void elemAt(EvalState & state, const Pos & pos, Value & list, int n, Valu
|
||||||
{
|
{
|
||||||
state.forceList(list, pos);
|
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);
|
throw Error("list index %1% is out of bounds, at %2%", n, pos);
|
||||||
state.forceValue(*list.listElems()[n]);
|
state.forceValue(*list.listElems()[n]);
|
||||||
v = *list.listElems()[n];
|
v = *list.listElems()[n];
|
||||||
}
|
}
|
||||||
|
@ -1423,7 +1423,7 @@ static void prim_tail(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
{
|
{
|
||||||
state.forceList(*args[0], pos);
|
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);
|
throw Error("'tail' called on an empty list, at %1%", pos);
|
||||||
state.mkList(v, args[0]->listSize() - 1);
|
state.mkList(v, args[0]->listSize() - 1);
|
||||||
for (unsigned int n = 0; n < v.listSize(); ++n)
|
for (unsigned int n = 0; n < v.listSize(); ++n)
|
||||||
v.listElems()[n] = args[0]->listElems()[n + 1];
|
v.listElems()[n] = args[0]->listElems()[n + 1];
|
||||||
|
@ -1564,7 +1564,7 @@ static void prim_genList(EvalState & state, const Pos & pos, Value * * args, Val
|
||||||
auto len = state.forceInt(*args[1], pos);
|
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);
|
throw EvalError("cannot create list of size %1%, at %2%", len, pos);
|
||||||
|
|
||||||
state.mkList(v, len);
|
state.mkList(v, len);
|
||||||
|
|
||||||
|
@ -1722,7 +1722,7 @@ static void prim_div(EvalState & state, const Pos & pos, Value * * args, Value &
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
|
|
||||||
NixFloat f2 = state.forceFloat(*args[1], pos);
|
NixFloat f2 = state.forceFloat(*args[1], pos);
|
||||||
if (f2 == 0) throw EvalError(format("division by zero, at %1%") % pos);
|
if (f2 == 0) throw EvalError("division by zero, at %1%", pos);
|
||||||
|
|
||||||
if (args[0]->type == tFloat || args[1]->type == tFloat) {
|
if (args[0]->type == tFloat || args[1]->type == tFloat) {
|
||||||
mkFloat(v, state.forceFloat(*args[0], pos) / state.forceFloat(*args[1], pos));
|
mkFloat(v, state.forceFloat(*args[0], pos) / state.forceFloat(*args[1], pos));
|
||||||
|
@ -1731,7 +1731,7 @@ static void prim_div(EvalState & state, const Pos & pos, Value * * args, Value &
|
||||||
NixInt i2 = state.forceInt(*args[1], pos);
|
NixInt i2 = state.forceInt(*args[1], pos);
|
||||||
/* Avoid division overflow as it might raise SIGFPE. */
|
/* 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);
|
throw EvalError("overflow in integer division, at %1%", pos);
|
||||||
mkInt(v, i1 / i2);
|
mkInt(v, i1 / i2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1787,7 +1787,7 @@ static void prim_substring(EvalState & state, const Pos & pos, Value * * args, V
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string s = state.coerceToString(pos, *args[2], context);
|
string s = state.coerceToString(pos, *args[2], context);
|
||||||
|
|
||||||
if (start < 0) throw EvalError(format("negative start position in 'substring', at %1%") % pos);
|
if (start < 0) throw EvalError("negative start position in 'substring', at %1%", pos);
|
||||||
|
|
||||||
mkString(v, (unsigned int) start >= s.size() ? "" : string(s, start, len), context);
|
mkString(v, (unsigned int) start >= s.size() ? "" : string(s, start, len), context);
|
||||||
}
|
}
|
||||||
|
@ -1807,7 +1807,7 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args,
|
||||||
string type = state.forceStringNoCtx(*args[0], pos);
|
string type = state.forceStringNoCtx(*args[0], pos);
|
||||||
HashType ht = parseHashType(type);
|
HashType ht = parseHashType(type);
|
||||||
if (ht == htUnknown)
|
if (ht == htUnknown)
|
||||||
throw Error(format("unknown hash type '%1%', at %2%") % type % pos);
|
throw Error("unknown hash type '%1%', at %2%", type, pos);
|
||||||
|
|
||||||
PathSet context; // discarded
|
PathSet context; // discarded
|
||||||
string s = state.forceString(*args[1], context, pos);
|
string s = state.forceString(*args[1], context, pos);
|
||||||
|
@ -1950,7 +1950,7 @@ static void prim_replaceStrings(EvalState & state, const Pos & pos, Value * * ar
|
||||||
state.forceList(*args[0], pos);
|
state.forceList(*args[0], pos);
|
||||||
state.forceList(*args[1], 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);
|
throw EvalError("'from' and 'to' arguments to 'replaceStrings' have different lengths, at %1%", pos);
|
||||||
|
|
||||||
vector<string> from;
|
vector<string> from;
|
||||||
from.reserve(args[0]->listSize());
|
from.reserve(args[0]->listSize());
|
||||||
|
@ -2072,11 +2072,11 @@ void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
|
||||||
else if (n == "name")
|
else if (n == "name")
|
||||||
request.name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
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);
|
throw EvalError("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);
|
throw EvalError("'url' argument required, at %1%", pos);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
request.uri = state.forceStringNoCtx(*args[0], pos);
|
request.uri = state.forceStringNoCtx(*args[0], pos);
|
||||||
|
|
|
@ -221,7 +221,7 @@ static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.empty())
|
if (url.empty())
|
||||||
throw EvalError(format("'url' argument required, at %1%") % pos);
|
throw EvalError("'url' argument required, at %1%", pos);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
url = state.coerceToString(pos, *args[0], context, false, false);
|
url = state.coerceToString(pos, *args[0], context, false, false);
|
||||||
|
|
|
@ -191,7 +191,7 @@ static void prim_fetchMercurial(EvalState & state, const Pos & pos, Value * * ar
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.empty())
|
if (url.empty())
|
||||||
throw EvalError(format("'url' argument required, at %1%") % pos);
|
throw EvalError("'url' argument required, at %1%", pos);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
url = state.coerceToString(pos, *args[0], context, false, false);
|
url = state.coerceToString(pos, *args[0], context, false, false);
|
||||||
|
|
|
@ -79,7 +79,7 @@ void printValueAsJSON(EvalState & state, bool strict,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw TypeError(format("cannot convert %1% to JSON") % showType(v));
|
throw TypeError("cannot convert %1% to JSON", showType(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ void printValueAsJSON(EvalState & state, bool strict,
|
||||||
void ExternalValueBase::printValueAsJSON(EvalState & state, bool strict,
|
void ExternalValueBase::printValueAsJSON(EvalState & state, bool strict,
|
||||||
JSONPlaceholder & out, PathSet & context) const
|
JSONPlaceholder & out, PathSet & context) const
|
||||||
{
|
{
|
||||||
throw TypeError(format("cannot convert %1% to JSON") % showType());
|
throw TypeError("cannot convert %1% to JSON", showType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ string getArg(const string & opt,
|
||||||
Strings::iterator & i, const Strings::iterator & end)
|
Strings::iterator & i, const Strings::iterator & end)
|
||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
if (i == end) throw UsageError(format("'%1%' requires an argument") % opt);
|
if (i == end) throw UsageError("'%1%' requires an argument", opt);
|
||||||
return *i;
|
return *i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ bool LegacyArgs::processArgs(const Strings & args, bool finish)
|
||||||
Strings ss(args);
|
Strings ss(args);
|
||||||
auto pos = ss.begin();
|
auto pos = ss.begin();
|
||||||
if (!parseArg(pos, ss.end()))
|
if (!parseArg(pos, ss.end()))
|
||||||
throw UsageError(format("unexpected argument '%1%'") % args.front());
|
throw UsageError("unexpected argument '%1%'", args.front());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ void showManPage(const string & name)
|
||||||
restoreSignals();
|
restoreSignals();
|
||||||
setenv("MANPATH", settings.nixManDir.c_str(), 1);
|
setenv("MANPATH", settings.nixManDir.c_str(), 1);
|
||||||
execlp("man", "man", name.c_str(), nullptr);
|
execlp("man", "man", name.c_str(), nullptr);
|
||||||
throw SysError(format("command 'man %1%' failed") % name.c_str());
|
throw SysError("command 'man %1%' failed", name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -301,7 +301,7 @@ int handleExceptions(const string & programName, std::function<void()> fun)
|
||||||
% e.what() % programName);
|
% e.what() % programName);
|
||||||
return 1;
|
return 1;
|
||||||
} catch (BaseError & e) {
|
} catch (BaseError & e) {
|
||||||
printError(format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg());
|
printError(error + "%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg());
|
||||||
if (e.prefix() != "" && !settings.showTrace)
|
if (e.prefix() != "" && !settings.showTrace)
|
||||||
printError("(use '--show-trace' to show detailed location information)");
|
printError("(use '--show-trace' to show detailed location information)");
|
||||||
return e.status;
|
return e.status;
|
||||||
|
@ -338,7 +338,7 @@ RunPager::RunPager()
|
||||||
execlp("pager", "pager", nullptr);
|
execlp("pager", "pager", nullptr);
|
||||||
execlp("less", "less", nullptr);
|
execlp("less", "less", nullptr);
|
||||||
execlp("more", "more", nullptr);
|
execlp("more", "more", nullptr);
|
||||||
throw SysError(format("executing '%1%'") % pager);
|
throw SysError("executing '%1%'", pager);
|
||||||
});
|
});
|
||||||
|
|
||||||
pid.setKillSignal(SIGINT);
|
pid.setKillSignal(SIGINT);
|
||||||
|
|
|
@ -56,7 +56,7 @@ template<class N> N getIntArg(const string & opt,
|
||||||
Strings::iterator & i, const Strings::iterator & end, bool allowUnit)
|
Strings::iterator & i, const Strings::iterator & end, bool allowUnit)
|
||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
if (i == end) throw UsageError(format("'%1%' requires an argument") % opt);
|
if (i == end) throw UsageError("'%1%' requires an argument", opt);
|
||||||
string s = *i;
|
string s = *i;
|
||||||
N multiplier = 1;
|
N multiplier = 1;
|
||||||
if (allowUnit && !s.empty()) {
|
if (allowUnit && !s.empty()) {
|
||||||
|
@ -66,13 +66,13 @@ template<class N> N getIntArg(const string & opt,
|
||||||
else if (u == 'M') multiplier = 1ULL << 20;
|
else if (u == 'M') multiplier = 1ULL << 20;
|
||||||
else if (u == 'G') multiplier = 1ULL << 30;
|
else if (u == 'G') multiplier = 1ULL << 30;
|
||||||
else if (u == 'T') multiplier = 1ULL << 40;
|
else if (u == 'T') multiplier = 1ULL << 40;
|
||||||
else throw UsageError(format("invalid unit specifier '%1%'") % u);
|
else throw UsageError("invalid unit specifier '%1%'", u);
|
||||||
s.resize(s.size() - 1);
|
s.resize(s.size() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
N n;
|
N n;
|
||||||
if (!string2Int(s, n))
|
if (!string2Int(s, n))
|
||||||
throw UsageError(format("'%1%' requires an integer argument") % opt);
|
throw UsageError("'%1%' requires an integer argument", opt);
|
||||||
return n * multiplier;
|
return n * multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,8 @@ void BinaryCacheStore::init()
|
||||||
auto value = trim(line.substr(colon + 1, std::string::npos));
|
auto value = trim(line.substr(colon + 1, std::string::npos));
|
||||||
if (name == "StoreDir") {
|
if (name == "StoreDir") {
|
||||||
if (value != storeDir)
|
if (value != storeDir)
|
||||||
throw Error(format("binary cache '%s' is for Nix stores with prefix '%s', not '%s'")
|
throw Error("binary cache '%s' is for Nix stores with prefix '%s', not '%s'",
|
||||||
% getUri() % value % storeDir);
|
getUri(), value, storeDir);
|
||||||
} else if (name == "WantMassQuery") {
|
} else if (name == "WantMassQuery") {
|
||||||
wantMassQuery.setDefault(value == "1" ? "true" : "false");
|
wantMassQuery.setDefault(value == "1" ? "true" : "false");
|
||||||
} else if (name == "Priority") {
|
} else if (name == "Priority") {
|
||||||
|
|
|
@ -453,7 +453,7 @@ static void commonChildInit(Pipe & logPipe)
|
||||||
that e.g. ssh cannot open /dev/tty) and it doesn't receive
|
that e.g. ssh cannot open /dev/tty) and it doesn't receive
|
||||||
terminal signals. */
|
terminal signals. */
|
||||||
if (setsid() == -1)
|
if (setsid() == -1)
|
||||||
throw SysError(format("creating a new session"));
|
throw SysError("creating a new session");
|
||||||
|
|
||||||
/* Dup the write side of the logger pipe into stderr. */
|
/* Dup the write side of the logger pipe into stderr. */
|
||||||
if (dup2(logPipe.writeSide.get(), STDERR_FILENO) == -1)
|
if (dup2(logPipe.writeSide.get(), STDERR_FILENO) == -1)
|
||||||
|
@ -466,7 +466,7 @@ static void commonChildInit(Pipe & logPipe)
|
||||||
/* Reroute stdin to /dev/null. */
|
/* Reroute stdin to /dev/null. */
|
||||||
int fdDevNull = open(pathNullDevice.c_str(), O_RDWR);
|
int fdDevNull = open(pathNullDevice.c_str(), O_RDWR);
|
||||||
if (fdDevNull == -1)
|
if (fdDevNull == -1)
|
||||||
throw SysError(format("cannot open '%1%'") % pathNullDevice);
|
throw SysError("cannot open '%1%'", pathNullDevice);
|
||||||
if (dup2(fdDevNull, STDIN_FILENO) == -1)
|
if (dup2(fdDevNull, STDIN_FILENO) == -1)
|
||||||
throw SysError("cannot dup null device into stdin");
|
throw SysError("cannot dup null device into stdin");
|
||||||
close(fdDevNull);
|
close(fdDevNull);
|
||||||
|
@ -488,7 +488,7 @@ void handleDiffHook(
|
||||||
|
|
||||||
auto diffRes = runProgram(diffHookOptions);
|
auto diffRes = runProgram(diffHookOptions);
|
||||||
if (!statusOk(diffRes.first))
|
if (!statusOk(diffRes.first))
|
||||||
throw ExecError(diffRes.first, fmt("diff-hook program '%1%' %2%", diffHook, statusToString(diffRes.first)));
|
throw ExecError(diffRes.first, "diff-hook program '%1%' %2%", diffHook, statusToString(diffRes.first));
|
||||||
|
|
||||||
if (diffRes.second != "")
|
if (diffRes.second != "")
|
||||||
printError(chomp(diffRes.second));
|
printError(chomp(diffRes.second));
|
||||||
|
@ -534,8 +534,8 @@ UserLock::UserLock()
|
||||||
/* Get the members of the build-users-group. */
|
/* Get the members of the build-users-group. */
|
||||||
struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str());
|
struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str());
|
||||||
if (!gr)
|
if (!gr)
|
||||||
throw Error(format("the group '%1%' specified in 'build-users-group' does not exist")
|
throw Error("the group '%1%' specified in 'build-users-group' does not exist",
|
||||||
% settings.buildUsersGroup);
|
settings.buildUsersGroup);
|
||||||
gid = gr->gr_gid;
|
gid = gr->gr_gid;
|
||||||
|
|
||||||
/* Copy the result of getgrnam. */
|
/* Copy the result of getgrnam. */
|
||||||
|
@ -546,8 +546,8 @@ UserLock::UserLock()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (users.empty())
|
if (users.empty())
|
||||||
throw Error(format("the build users group '%1%' has no members")
|
throw Error("the build users group '%1%' has no members",
|
||||||
% settings.buildUsersGroup);
|
settings.buildUsersGroup);
|
||||||
|
|
||||||
/* Find a user account that isn't currently in use for another
|
/* Find a user account that isn't currently in use for another
|
||||||
build. */
|
build. */
|
||||||
|
@ -556,8 +556,8 @@ UserLock::UserLock()
|
||||||
|
|
||||||
struct passwd * pw = getpwnam(i.c_str());
|
struct passwd * pw = getpwnam(i.c_str());
|
||||||
if (!pw)
|
if (!pw)
|
||||||
throw Error(format("the user '%1%' in the group '%2%' does not exist")
|
throw Error("the user '%1%' in the group '%2%' does not exist",
|
||||||
% i % settings.buildUsersGroup);
|
i, settings.buildUsersGroup);
|
||||||
|
|
||||||
createDirs(settings.nixStateDir + "/userpool");
|
createDirs(settings.nixStateDir + "/userpool");
|
||||||
|
|
||||||
|
@ -565,7 +565,7 @@ UserLock::UserLock()
|
||||||
|
|
||||||
AutoCloseFD fd = open(fnUserLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
|
AutoCloseFD fd = open(fnUserLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
|
||||||
if (!fd)
|
if (!fd)
|
||||||
throw SysError(format("opening user lock '%1%'") % fnUserLock);
|
throw SysError("opening user lock '%1%'", fnUserLock);
|
||||||
|
|
||||||
if (lockFile(fd.get(), ltWrite, false)) {
|
if (lockFile(fd.get(), ltWrite, false)) {
|
||||||
fdUserLock = std::move(fd);
|
fdUserLock = std::move(fd);
|
||||||
|
@ -574,8 +574,8 @@ UserLock::UserLock()
|
||||||
|
|
||||||
/* Sanity check... */
|
/* Sanity check... */
|
||||||
if (uid == getuid() || uid == geteuid())
|
if (uid == getuid() || uid == geteuid())
|
||||||
throw Error(format("the Nix user should not be a member of '%1%'")
|
throw Error("the Nix user should not be a member of '%1%'",
|
||||||
% settings.buildUsersGroup);
|
settings.buildUsersGroup);
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
/* Get the list of supplementary groups of this build user. This
|
/* Get the list of supplementary groups of this build user. This
|
||||||
|
@ -585,7 +585,7 @@ UserLock::UserLock()
|
||||||
int err = getgrouplist(pw->pw_name, pw->pw_gid,
|
int err = getgrouplist(pw->pw_name, pw->pw_gid,
|
||||||
supplementaryGIDs.data(), &ngroups);
|
supplementaryGIDs.data(), &ngroups);
|
||||||
if (err == -1)
|
if (err == -1)
|
||||||
throw Error(format("failed to get list of supplementary groups for '%1%'") % pw->pw_name);
|
throw Error("failed to get list of supplementary groups for '%1%'", pw->pw_name);
|
||||||
|
|
||||||
supplementaryGIDs.resize(ngroups);
|
supplementaryGIDs.resize(ngroups);
|
||||||
#endif
|
#endif
|
||||||
|
@ -594,9 +594,9 @@ UserLock::UserLock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Error(format("all build users are currently in use; "
|
throw Error("all build users are currently in use; "
|
||||||
"consider creating additional users and adding them to the '%1%' group")
|
"consider creating additional users and adding them to the '%1%' group",
|
||||||
% settings.buildUsersGroup);
|
settings.buildUsersGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1985,7 +1985,7 @@ void DerivationGoal::startBuilder()
|
||||||
string s = get(drv->env, "exportReferencesGraph").value_or("");
|
string s = get(drv->env, "exportReferencesGraph").value_or("");
|
||||||
Strings ss = tokenizeString<Strings>(s);
|
Strings ss = tokenizeString<Strings>(s);
|
||||||
if (ss.size() % 2 != 0)
|
if (ss.size() % 2 != 0)
|
||||||
throw BuildError(format("odd number of tokens in 'exportReferencesGraph': '%1%'") % s);
|
throw BuildError("odd number of tokens in 'exportReferencesGraph': '%1%'", s);
|
||||||
for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
|
for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
|
||||||
string fileName = *i++;
|
string fileName = *i++;
|
||||||
static std::regex regex("[A-Za-z_][A-Za-z0-9_.-]*");
|
static std::regex regex("[A-Za-z_][A-Za-z0-9_.-]*");
|
||||||
|
@ -2034,7 +2034,7 @@ void DerivationGoal::startBuilder()
|
||||||
worker.store.computeFSClosure(worker.store.parseStorePath(worker.store.toStorePath(i.second.source)), closure);
|
worker.store.computeFSClosure(worker.store.parseStorePath(worker.store.toStorePath(i.second.source)), closure);
|
||||||
} catch (InvalidPath & e) {
|
} catch (InvalidPath & e) {
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
throw Error(format("while processing 'sandbox-paths': %s") % e.what());
|
throw Error("while processing 'sandbox-paths': %s", e.what());
|
||||||
}
|
}
|
||||||
for (auto & i : closure) {
|
for (auto & i : closure) {
|
||||||
auto p = worker.store.printStorePath(i);
|
auto p = worker.store.printStorePath(i);
|
||||||
|
@ -2081,10 +2081,10 @@ void DerivationGoal::startBuilder()
|
||||||
printMsg(lvlChatty, format("setting up chroot environment in '%1%'") % chrootRootDir);
|
printMsg(lvlChatty, format("setting up chroot environment in '%1%'") % chrootRootDir);
|
||||||
|
|
||||||
if (mkdir(chrootRootDir.c_str(), 0750) == -1)
|
if (mkdir(chrootRootDir.c_str(), 0750) == -1)
|
||||||
throw SysError(format("cannot create '%1%'") % chrootRootDir);
|
throw SysError("cannot create '%1%'", chrootRootDir);
|
||||||
|
|
||||||
if (buildUser && chown(chrootRootDir.c_str(), 0, buildUser->getGID()) == -1)
|
if (buildUser && chown(chrootRootDir.c_str(), 0, buildUser->getGID()) == -1)
|
||||||
throw SysError(format("cannot change ownership of '%1%'") % chrootRootDir);
|
throw SysError("cannot change ownership of '%1%'", chrootRootDir);
|
||||||
|
|
||||||
/* Create a writable /tmp in the chroot. Many builders need
|
/* Create a writable /tmp in the chroot. Many builders need
|
||||||
this. (Of course they should really respect $TMPDIR
|
this. (Of course they should really respect $TMPDIR
|
||||||
|
@ -2128,7 +2128,7 @@ void DerivationGoal::startBuilder()
|
||||||
chmod_(chrootStoreDir, 01775);
|
chmod_(chrootStoreDir, 01775);
|
||||||
|
|
||||||
if (buildUser && chown(chrootStoreDir.c_str(), 0, buildUser->getGID()) == -1)
|
if (buildUser && chown(chrootStoreDir.c_str(), 0, buildUser->getGID()) == -1)
|
||||||
throw SysError(format("cannot change ownership of '%1%'") % chrootStoreDir);
|
throw SysError("cannot change ownership of '%1%'", chrootStoreDir);
|
||||||
|
|
||||||
for (auto & i : inputPaths) {
|
for (auto & i : inputPaths) {
|
||||||
auto p = worker.store.printStorePath(i);
|
auto p = worker.store.printStorePath(i);
|
||||||
|
@ -2161,7 +2161,7 @@ void DerivationGoal::startBuilder()
|
||||||
if (needsHashRewrite()) {
|
if (needsHashRewrite()) {
|
||||||
|
|
||||||
if (pathExists(homeDir))
|
if (pathExists(homeDir))
|
||||||
throw Error(format("directory '%1%' exists; please remove it") % homeDir);
|
throw Error("directory '%1%' exists; please remove it", homeDir);
|
||||||
|
|
||||||
/* We're not doing a chroot build, but we have some valid
|
/* We're not doing a chroot build, but we have some valid
|
||||||
output paths. Since we can't just overwrite or delete
|
output paths. Since we can't just overwrite or delete
|
||||||
|
@ -2206,8 +2206,7 @@ void DerivationGoal::startBuilder()
|
||||||
if (line == "extra-sandbox-paths" || line == "extra-chroot-dirs") {
|
if (line == "extra-sandbox-paths" || line == "extra-chroot-dirs") {
|
||||||
state = stExtraChrootDirs;
|
state = stExtraChrootDirs;
|
||||||
} else {
|
} else {
|
||||||
throw Error(format("unknown pre-build hook command '%1%'")
|
throw Error("unknown pre-build hook command '%1%'", line);
|
||||||
% line);
|
|
||||||
}
|
}
|
||||||
} else if (state == stExtraChrootDirs) {
|
} else if (state == stExtraChrootDirs) {
|
||||||
if (line == "") {
|
if (line == "") {
|
||||||
|
@ -2967,7 +2966,7 @@ void DerivationGoal::chownToBuilder(const Path & path)
|
||||||
{
|
{
|
||||||
if (!buildUser) return;
|
if (!buildUser) return;
|
||||||
if (chown(path.c_str(), buildUser->getUID(), buildUser->getGID()) == -1)
|
if (chown(path.c_str(), buildUser->getUID(), buildUser->getGID()) == -1)
|
||||||
throw SysError(format("cannot change ownership of '%1%'") % path);
|
throw SysError("cannot change ownership of '%1%'", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3104,7 +3103,7 @@ void DerivationGoal::runChild()
|
||||||
/* Bind-mount chroot directory to itself, to treat it as a
|
/* Bind-mount chroot directory to itself, to treat it as a
|
||||||
different filesystem from /, as needed for pivot_root. */
|
different filesystem from /, as needed for pivot_root. */
|
||||||
if (mount(chrootRootDir.c_str(), chrootRootDir.c_str(), 0, MS_BIND, 0) == -1)
|
if (mount(chrootRootDir.c_str(), chrootRootDir.c_str(), 0, MS_BIND, 0) == -1)
|
||||||
throw SysError(format("unable to bind mount '%1%'") % chrootRootDir);
|
throw SysError("unable to bind mount '%1%'", chrootRootDir);
|
||||||
|
|
||||||
/* Bind-mount the sandbox's Nix store onto itself so that
|
/* Bind-mount the sandbox's Nix store onto itself so that
|
||||||
we can mark it as a "shared" subtree, allowing bind
|
we can mark it as a "shared" subtree, allowing bind
|
||||||
|
@ -3238,16 +3237,16 @@ void DerivationGoal::runChild()
|
||||||
|
|
||||||
/* Do the chroot(). */
|
/* Do the chroot(). */
|
||||||
if (chdir(chrootRootDir.c_str()) == -1)
|
if (chdir(chrootRootDir.c_str()) == -1)
|
||||||
throw SysError(format("cannot change directory to '%1%'") % chrootRootDir);
|
throw SysError("cannot change directory to '%1%'", chrootRootDir);
|
||||||
|
|
||||||
if (mkdir("real-root", 0) == -1)
|
if (mkdir("real-root", 0) == -1)
|
||||||
throw SysError("cannot create real-root directory");
|
throw SysError("cannot create real-root directory");
|
||||||
|
|
||||||
if (pivot_root(".", "real-root") == -1)
|
if (pivot_root(".", "real-root") == -1)
|
||||||
throw SysError(format("cannot pivot old root directory onto '%1%'") % (chrootRootDir + "/real-root"));
|
throw SysError("cannot pivot old root directory onto '%1%'", (chrootRootDir + "/real-root"));
|
||||||
|
|
||||||
if (chroot(".") == -1)
|
if (chroot(".") == -1)
|
||||||
throw SysError(format("cannot change root directory to '%1%'") % chrootRootDir);
|
throw SysError("cannot change root directory to '%1%'", chrootRootDir);
|
||||||
|
|
||||||
if (umount2("real-root", MNT_DETACH) == -1)
|
if (umount2("real-root", MNT_DETACH) == -1)
|
||||||
throw SysError("cannot unmount real root filesystem");
|
throw SysError("cannot unmount real root filesystem");
|
||||||
|
@ -3268,7 +3267,7 @@ void DerivationGoal::runChild()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (chdir(tmpDirInSandbox.c_str()) == -1)
|
if (chdir(tmpDirInSandbox.c_str()) == -1)
|
||||||
throw SysError(format("changing into '%1%'") % tmpDir);
|
throw SysError("changing into '%1%'", tmpDir);
|
||||||
|
|
||||||
/* Close all other file descriptors. */
|
/* Close all other file descriptors. */
|
||||||
closeMostFDs({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO});
|
closeMostFDs({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO});
|
||||||
|
@ -3407,9 +3406,9 @@ void DerivationGoal::runChild()
|
||||||
sandboxProfile += "(allow file-read* file-write* process-exec\n";
|
sandboxProfile += "(allow file-read* file-write* process-exec\n";
|
||||||
for (auto & i : dirsInChroot) {
|
for (auto & i : dirsInChroot) {
|
||||||
if (i.first != i.second.source)
|
if (i.first != i.second.source)
|
||||||
throw Error(format(
|
throw Error(
|
||||||
"can't map '%1%' to '%2%': mismatched impure paths not supported on Darwin")
|
"can't map '%1%' to '%2%': mismatched impure paths not supported on Darwin",
|
||||||
% i.first % i.second.source);
|
i.first, i.second.source);
|
||||||
|
|
||||||
string path = i.first;
|
string path = i.first;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -3500,7 +3499,7 @@ void DerivationGoal::runChild()
|
||||||
else if (drv->builder == "builtin:unpack-channel")
|
else if (drv->builder == "builtin:unpack-channel")
|
||||||
builtinUnpackChannel(drv2);
|
builtinUnpackChannel(drv2);
|
||||||
else
|
else
|
||||||
throw Error(format("unsupported builtin function '%1%'") % string(drv->builder, 8));
|
throw Error("unsupported builtin function '%1%'", string(drv->builder, 8));
|
||||||
_exit(0);
|
_exit(0);
|
||||||
} catch (std::exception & e) {
|
} catch (std::exception & e) {
|
||||||
writeFull(STDERR_FILENO, "error: " + string(e.what()) + "\n");
|
writeFull(STDERR_FILENO, "error: " + string(e.what()) + "\n");
|
||||||
|
@ -3510,7 +3509,7 @@ void DerivationGoal::runChild()
|
||||||
|
|
||||||
execve(builder, stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data());
|
execve(builder, stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data());
|
||||||
|
|
||||||
throw SysError(format("executing '%1%'") % drv->builder);
|
throw SysError("executing '%1%'", drv->builder);
|
||||||
|
|
||||||
} catch (std::exception & e) {
|
} catch (std::exception & e) {
|
||||||
writeFull(STDERR_FILENO, "\1while setting up the build environment: " + string(e.what()) + "\n");
|
writeFull(STDERR_FILENO, "\1while setting up the build environment: " + string(e.what()) + "\n");
|
||||||
|
@ -3595,7 +3594,7 @@ void DerivationGoal::registerOutputs()
|
||||||
replaceValidPath(path, actualPath);
|
replaceValidPath(path, actualPath);
|
||||||
else
|
else
|
||||||
if (buildMode != bmCheck && rename(actualPath.c_str(), worker.store.toRealPath(path).c_str()) == -1)
|
if (buildMode != bmCheck && rename(actualPath.c_str(), worker.store.toRealPath(path).c_str()) == -1)
|
||||||
throw SysError(format("moving build output '%1%' from the sandbox to the Nix store") % path);
|
throw SysError("moving build output '%1%' from the sandbox to the Nix store", path);
|
||||||
}
|
}
|
||||||
if (buildMode != bmCheck) actualPath = worker.store.toRealPath(path);
|
if (buildMode != bmCheck) actualPath = worker.store.toRealPath(path);
|
||||||
}
|
}
|
||||||
|
@ -3616,13 +3615,13 @@ void DerivationGoal::registerOutputs()
|
||||||
user. */
|
user. */
|
||||||
if ((!S_ISLNK(st.st_mode) && (st.st_mode & (S_IWGRP | S_IWOTH))) ||
|
if ((!S_ISLNK(st.st_mode) && (st.st_mode & (S_IWGRP | S_IWOTH))) ||
|
||||||
(buildUser && st.st_uid != buildUser->getUID()))
|
(buildUser && st.st_uid != buildUser->getUID()))
|
||||||
throw BuildError(format("suspicious ownership or permission on '%1%'; rejecting this build output") % path);
|
throw BuildError("suspicious ownership or permission on '%1%'; rejecting this build output", path);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Apply hash rewriting if necessary. */
|
/* Apply hash rewriting if necessary. */
|
||||||
bool rewritten = false;
|
bool rewritten = false;
|
||||||
if (!outputRewrites.empty()) {
|
if (!outputRewrites.empty()) {
|
||||||
printError(format("warning: rewriting hashes in '%1%'; cross fingers") % path);
|
printError("warning: rewriting hashes in '%1%'; cross fingers", path);
|
||||||
|
|
||||||
/* Canonicalise first. This ensures that the path we're
|
/* Canonicalise first. This ensures that the path we're
|
||||||
rewriting doesn't contain a hard link to /etc/shadow or
|
rewriting doesn't contain a hard link to /etc/shadow or
|
||||||
|
@ -3654,7 +3653,8 @@ void DerivationGoal::registerOutputs()
|
||||||
/* The output path should be a regular file without execute permission. */
|
/* The output path should be a regular file without execute permission. */
|
||||||
if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0)
|
if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0)
|
||||||
throw BuildError(
|
throw BuildError(
|
||||||
format("output path '%1%' should be a non-executable regular file") % path);
|
"output path '%1%' should be a non-executable regular file",
|
||||||
|
path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the hash. In hash mode, move the path produced by
|
/* Check the hash. In hash mode, move the path produced by
|
||||||
|
@ -3715,7 +3715,7 @@ void DerivationGoal::registerOutputs()
|
||||||
Path dst = worker.store.toRealPath(path + checkSuffix);
|
Path dst = worker.store.toRealPath(path + checkSuffix);
|
||||||
deletePath(dst);
|
deletePath(dst);
|
||||||
if (rename(actualPath.c_str(), dst.c_str()))
|
if (rename(actualPath.c_str(), dst.c_str()))
|
||||||
throw SysError(format("renaming '%1%' to '%2%'") % actualPath % dst);
|
throw SysError("renaming '%1%' to '%2%'", actualPath, dst);
|
||||||
|
|
||||||
handleDiffHook(
|
handleDiffHook(
|
||||||
buildUser ? buildUser->getUID() : getuid(),
|
buildUser ? buildUser->getUID() : getuid(),
|
||||||
|
@ -4014,7 +4014,7 @@ Path DerivationGoal::openLogFile()
|
||||||
settings.compressLog ? ".bz2" : "");
|
settings.compressLog ? ".bz2" : "");
|
||||||
|
|
||||||
fdLogFile = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0666);
|
fdLogFile = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0666);
|
||||||
if (!fdLogFile) throw SysError(format("creating log file '%1%'") % logFileName);
|
if (!fdLogFile) throw SysError("creating log file '%1%'", logFileName);
|
||||||
|
|
||||||
logFileSink = std::make_shared<FdSink>(fdLogFile.get());
|
logFileSink = std::make_shared<FdSink>(fdLogFile.get());
|
||||||
|
|
||||||
|
@ -4522,7 +4522,6 @@ void SubstitutionGoal::handleEOF(int fd)
|
||||||
if (fd == outPipe.readSide.get()) worker.wakeUp(shared_from_this());
|
if (fd == outPipe.readSide.get()) worker.wakeUp(shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@ -4739,8 +4738,8 @@ void Worker::run(const Goals & _topGoals)
|
||||||
if (!children.empty() || !waitingForAWhile.empty())
|
if (!children.empty() || !waitingForAWhile.empty())
|
||||||
waitForInput();
|
waitForInput();
|
||||||
else {
|
else {
|
||||||
if (awake.empty() && 0 == settings.maxBuildJobs) throw Error(
|
if (awake.empty() && 0 == settings.maxBuildJobs)
|
||||||
"unable to start any build; either increase '--max-jobs' "
|
throw Error("unable to start any build; either increase '--max-jobs' "
|
||||||
"or enable remote builds");
|
"or enable remote builds");
|
||||||
assert(!awake.empty());
|
assert(!awake.empty());
|
||||||
}
|
}
|
||||||
|
@ -4754,7 +4753,6 @@ void Worker::run(const Goals & _topGoals)
|
||||||
assert(!settings.keepGoing || children.empty());
|
assert(!settings.keepGoing || children.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Worker::waitForInput()
|
void Worker::waitForInput()
|
||||||
{
|
{
|
||||||
printMsg(lvlVomit, "waiting for children");
|
printMsg(lvlVomit, "waiting for children");
|
||||||
|
@ -4895,6 +4893,9 @@ void Worker::waitForInput()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int Worker::exitStatus()
|
unsigned int Worker::exitStatus()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -4994,7 +4995,6 @@ void LocalStore::buildPaths(const std::vector<StorePathWithOutputs> & drvPaths,
|
||||||
throw Error(worker.exitStatus(), "build of %s failed", showPaths(failed));
|
throw Error(worker.exitStatus(), "build of %s failed", showPaths(failed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BuildResult LocalStore::buildDerivation(const StorePath & drvPath, const BasicDerivation & drv,
|
BuildResult LocalStore::buildDerivation(const StorePath & drvPath, const BasicDerivation & drv,
|
||||||
BuildMode buildMode)
|
BuildMode buildMode)
|
||||||
{
|
{
|
||||||
|
@ -5055,4 +5055,8 @@ void LocalStore::repairPath(const StorePath & path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -72,15 +72,15 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
|
||||||
if (!S_ISDIR(lstat(target).st_mode))
|
if (!S_ISDIR(lstat(target).st_mode))
|
||||||
throw Error("collision between '%1%' and non-directory '%2%'", srcFile, target);
|
throw Error("collision between '%1%' and non-directory '%2%'", srcFile, target);
|
||||||
if (unlink(dstFile.c_str()) == -1)
|
if (unlink(dstFile.c_str()) == -1)
|
||||||
throw SysError(format("unlinking '%1%'") % dstFile);
|
throw SysError("unlinking '%1%'", dstFile);
|
||||||
if (mkdir(dstFile.c_str(), 0755) == -1)
|
if (mkdir(dstFile.c_str(), 0755) == -1)
|
||||||
throw SysError(format("creating directory '%1%'"));
|
throw SysError("creating directory '%1%'", dstFile);
|
||||||
createLinks(state, target, dstFile, state.priorities[dstFile]);
|
createLinks(state, target, dstFile, state.priorities[dstFile]);
|
||||||
createLinks(state, srcFile, dstFile, priority);
|
createLinks(state, srcFile, dstFile, priority);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (errno != ENOENT)
|
} else if (errno != ENOENT)
|
||||||
throw SysError(format("getting status of '%1%'") % dstFile);
|
throw SysError("getting status of '%1%'", dstFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
@ -99,11 +99,11 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
|
||||||
if (prevPriority < priority)
|
if (prevPriority < priority)
|
||||||
continue;
|
continue;
|
||||||
if (unlink(dstFile.c_str()) == -1)
|
if (unlink(dstFile.c_str()) == -1)
|
||||||
throw SysError(format("unlinking '%1%'") % dstFile);
|
throw SysError("unlinking '%1%'", dstFile);
|
||||||
} else if (S_ISDIR(dstSt.st_mode))
|
} else if (S_ISDIR(dstSt.st_mode))
|
||||||
throw Error("collision between non-directory '%1%' and directory '%2%'", srcFile, dstFile);
|
throw Error("collision between non-directory '%1%' and directory '%2%'", srcFile, dstFile);
|
||||||
} else if (errno != ENOENT)
|
} else if (errno != ENOENT)
|
||||||
throw SysError(format("getting status of '%1%'") % dstFile);
|
throw SysError("getting status of '%1%'", dstFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
createSymlink(srcFile, dstFile);
|
createSymlink(srcFile, dstFile);
|
||||||
|
|
|
@ -18,7 +18,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
|
||||||
|
|
||||||
auto getAttr = [&](const string & name) {
|
auto getAttr = [&](const string & name) {
|
||||||
auto i = drv.env.find(name);
|
auto i = drv.env.find(name);
|
||||||
if (i == drv.env.end()) throw Error(format("attribute '%s' missing") % name);
|
if (i == drv.env.end()) throw Error("attribute '%s' missing", name);
|
||||||
return i->second;
|
return i->second;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
|
||||||
auto executable = drv.env.find("executable");
|
auto executable = drv.env.find("executable");
|
||||||
if (executable != drv.env.end() && executable->second == "1") {
|
if (executable != drv.env.end() && executable->second == "1") {
|
||||||
if (chmod(storePath.c_str(), 0755) == -1)
|
if (chmod(storePath.c_str(), 0755) == -1)
|
||||||
throw SysError(format("making '%1%' executable") % storePath);
|
throw SysError("making '%1%' executable", storePath);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -747,7 +747,7 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw Error(format("invalid operation %1%") % op);
|
throw Error("invalid operation %1%", op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ static void expect(std::istream & str, const string & s)
|
||||||
char s2[s.size()];
|
char s2[s.size()];
|
||||||
str.read(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);
|
throw FormatError("expected string '%1%'", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ static Path parsePath(std::istream & str)
|
||||||
{
|
{
|
||||||
string s = parseString(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);
|
throw FormatError("bad path '%1%' in derivation", s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ Derivation readDerivation(const Store & store, const Path & drvPath)
|
||||||
try {
|
try {
|
||||||
return parseDerivation(store, readFile(drvPath));
|
return parseDerivation(store, readFile(drvPath));
|
||||||
} catch (FormatError & e) {
|
} catch (FormatError & e) {
|
||||||
throw Error(format("error parsing derivation '%1%': %2%") % drvPath % e.msg());
|
throw Error("error parsing derivation '%1%': %2%", drvPath, e.msg());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ struct CurlDownloader : public Downloader
|
||||||
if (requestHeaders) curl_slist_free_all(requestHeaders);
|
if (requestHeaders) curl_slist_free_all(requestHeaders);
|
||||||
try {
|
try {
|
||||||
if (!done)
|
if (!done)
|
||||||
fail(DownloadError(Interrupted, format("download of '%s' was interrupted") % request.uri));
|
fail(DownloadError(Interrupted, "download of '%s' was interrupted", request.uri));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
ignoreException();
|
ignoreException();
|
||||||
}
|
}
|
||||||
|
@ -518,7 +518,7 @@ struct CurlDownloader : public Downloader
|
||||||
int running;
|
int running;
|
||||||
CURLMcode mc = curl_multi_perform(curlm, &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));
|
throw nix::Error("unexpected error from curl_multi_perform(): %s", curl_multi_strerror(mc));
|
||||||
|
|
||||||
/* Set the promises of any finished requests. */
|
/* Set the promises of any finished requests. */
|
||||||
CURLMsg * msg;
|
CURLMsg * msg;
|
||||||
|
@ -548,7 +548,7 @@ struct CurlDownloader : public Downloader
|
||||||
vomit("download thread waiting for %d ms", sleepTimeMs);
|
vomit("download thread waiting for %d ms", sleepTimeMs);
|
||||||
mc = curl_multi_wait(curlm, extraFDs, 1, sleepTimeMs, &numfds);
|
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));
|
throw nix::Error("unexpected error from curl_multi_wait(): %s", curl_multi_strerror(mc));
|
||||||
|
|
||||||
nextWakeup = std::chrono::steady_clock::time_point();
|
nextWakeup = std::chrono::steady_clock::time_point();
|
||||||
|
|
||||||
|
|
|
@ -128,8 +128,10 @@ class DownloadError : public Error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Downloader::Error error;
|
Downloader::Error error;
|
||||||
DownloadError(Downloader::Error error, const FormatOrString & fs)
|
|
||||||
: Error(fs), error(error)
|
template<typename... Args>
|
||||||
|
DownloadError(Downloader::Error error, const Args & ... args)
|
||||||
|
: Error(args...), error(error)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ AutoCloseFD LocalStore::openGCLock(LockType lockType)
|
||||||
|
|
||||||
AutoCloseFD fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
|
AutoCloseFD fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
|
||||||
if (!fdGCLock)
|
if (!fdGCLock)
|
||||||
throw SysError(format("opening global GC lock '%1%'") % fnGCLock);
|
throw SysError("opening global GC lock '%1%'", fnGCLock);
|
||||||
|
|
||||||
if (!lockFile(fdGCLock.get(), lockType, false)) {
|
if (!lockFile(fdGCLock.get(), lockType, false)) {
|
||||||
printError(format("waiting for the big garbage collector lock..."));
|
printError(format("waiting for the big garbage collector lock..."));
|
||||||
|
@ -65,8 +65,8 @@ static void makeSymlink(const Path & link, const Path & target)
|
||||||
|
|
||||||
/* Atomically replace the old one. */
|
/* 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%'")
|
throw SysError("cannot rename '%1%' to '%2%'",
|
||||||
% tempLink % link);
|
tempLink , link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,15 +91,15 @@ Path LocalFSStore::addPermRoot(const StorePath & storePath,
|
||||||
Path gcRoot(canonPath(_gcRoot));
|
Path gcRoot(canonPath(_gcRoot));
|
||||||
|
|
||||||
if (isInStore(gcRoot))
|
if (isInStore(gcRoot))
|
||||||
throw Error(format(
|
throw Error(
|
||||||
"creating a garbage collector root (%1%) in the Nix store is forbidden "
|
"creating a garbage collector root (%1%) in the Nix store is forbidden "
|
||||||
"(are you running nix-build inside the store?)") % gcRoot);
|
"(are you running nix-build inside the store?)", gcRoot);
|
||||||
|
|
||||||
if (indirect) {
|
if (indirect) {
|
||||||
/* Don't clobber the link if it already exists and doesn't
|
/* Don't clobber the link if it already exists and doesn't
|
||||||
point to the Nix store. */
|
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);
|
throw Error("cannot create symlink '%1%'; already exists", gcRoot);
|
||||||
makeSymlink(gcRoot, printStorePath(storePath));
|
makeSymlink(gcRoot, printStorePath(storePath));
|
||||||
addIndirectRoot(gcRoot);
|
addIndirectRoot(gcRoot);
|
||||||
}
|
}
|
||||||
|
@ -109,10 +109,10 @@ Path LocalFSStore::addPermRoot(const StorePath & storePath,
|
||||||
Path rootsDir = canonPath((format("%1%/%2%") % stateDir % gcRootsDir).str());
|
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(
|
throw Error(
|
||||||
"path '%1%' is not a valid garbage collector root; "
|
"path '%1%' is not a valid garbage collector root; "
|
||||||
"it's not in the directory '%2%'")
|
"it's not in the directory '%2%'",
|
||||||
% gcRoot % rootsDir);
|
gcRoot, rootsDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baseNameOf(gcRoot) == std::string(storePath.to_string()))
|
if (baseNameOf(gcRoot) == std::string(storePath.to_string()))
|
||||||
|
@ -170,7 +170,7 @@ void LocalStore::addTempRoot(const StorePath & path)
|
||||||
way. */
|
way. */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat(state->fdTempRoots.get(), &st) == -1)
|
if (fstat(state->fdTempRoots.get(), &st) == -1)
|
||||||
throw SysError(format("statting '%1%'") % fnTempRoots);
|
throw SysError("statting '%1%'", fnTempRoots);
|
||||||
if (st.st_size == 0) break;
|
if (st.st_size == 0) break;
|
||||||
|
|
||||||
/* The garbage collector deleted this file before we could
|
/* The garbage collector deleted this file before we could
|
||||||
|
@ -211,7 +211,7 @@ void LocalStore::findTempRoots(FDs & fds, Roots & tempRoots, bool censor)
|
||||||
if (!*fd) {
|
if (!*fd) {
|
||||||
/* It's okay if the file has disappeared. */
|
/* It's okay if the file has disappeared. */
|
||||||
if (errno == ENOENT) continue;
|
if (errno == ENOENT) continue;
|
||||||
throw SysError(format("opening temporary roots file '%1%'") % path);
|
throw SysError("opening temporary roots file '%1%'", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This should work, but doesn't, for some reason. */
|
/* This should work, but doesn't, for some reason. */
|
||||||
|
@ -222,7 +222,7 @@ void LocalStore::findTempRoots(FDs & fds, Roots & tempRoots, bool censor)
|
||||||
only succeed if the owning process has died. In that case
|
only succeed if the owning process has died. In that case
|
||||||
we don't care about its temporary roots. */
|
we don't care about its temporary roots. */
|
||||||
if (lockFile(fd->get(), ltWrite, false)) {
|
if (lockFile(fd->get(), ltWrite, false)) {
|
||||||
printError(format("removing stale temporary roots file '%1%'") % path);
|
printError("removing stale temporary roots file '%1%'", path);
|
||||||
unlink(path.c_str());
|
unlink(path.c_str());
|
||||||
writeFull(fd->get(), "d");
|
writeFull(fd->get(), "d");
|
||||||
continue;
|
continue;
|
||||||
|
@ -398,7 +398,7 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
|
||||||
if (!fdDir) {
|
if (!fdDir) {
|
||||||
if (errno == ENOENT || errno == EACCES)
|
if (errno == ENOENT || errno == EACCES)
|
||||||
continue;
|
continue;
|
||||||
throw SysError(format("opening %1%") % fdStr);
|
throw SysError("opening %1%", fdStr);
|
||||||
}
|
}
|
||||||
struct dirent * fd_ent;
|
struct dirent * fd_ent;
|
||||||
while (errno = 0, fd_ent = readdir(fdDir.get())) {
|
while (errno = 0, fd_ent = readdir(fdDir.get())) {
|
||||||
|
@ -408,7 +408,7 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
|
||||||
if (errno) {
|
if (errno) {
|
||||||
if (errno == ESRCH)
|
if (errno == ESRCH)
|
||||||
continue;
|
continue;
|
||||||
throw SysError(format("iterating /proc/%1%/fd") % ent->d_name);
|
throw SysError("iterating /proc/%1%/fd", ent->d_name);
|
||||||
}
|
}
|
||||||
fdDir.reset();
|
fdDir.reset();
|
||||||
|
|
||||||
|
@ -536,7 +536,7 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(realPath.c_str(), &st)) {
|
if (lstat(realPath.c_str(), &st)) {
|
||||||
if (errno == ENOENT) return;
|
if (errno == ENOENT) return;
|
||||||
throw SysError(format("getting status of %1%") % realPath);
|
throw SysError("getting status of %1%", realPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
printInfo(format("deleting '%1%'") % path);
|
printInfo(format("deleting '%1%'") % path);
|
||||||
|
@ -554,10 +554,10 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
|
||||||
// size.
|
// size.
|
||||||
try {
|
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);
|
throw SysError("making '%1%' writable", realPath);
|
||||||
Path tmp = trashDir + "/" + std::string(baseNameOf(path));
|
Path tmp = trashDir + "/" + std::string(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);
|
throw SysError("unable to rename '%1%' to '%2%'", realPath, tmp);
|
||||||
state.bytesInvalidated += size;
|
state.bytesInvalidated += size;
|
||||||
} catch (SysError & e) {
|
} catch (SysError & e) {
|
||||||
if (e.errNo == ENOSPC) {
|
if (e.errNo == ENOSPC) {
|
||||||
|
@ -676,7 +676,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
|
||||||
void LocalStore::removeUnusedLinks(const GCState & state)
|
void LocalStore::removeUnusedLinks(const GCState & state)
|
||||||
{
|
{
|
||||||
AutoCloseDir dir(opendir(linksDir.c_str()));
|
AutoCloseDir dir(opendir(linksDir.c_str()));
|
||||||
if (!dir) throw SysError(format("opening directory '%1%'") % linksDir);
|
if (!dir) throw SysError("opening directory '%1%'", linksDir);
|
||||||
|
|
||||||
long long actualSize = 0, unsharedSize = 0;
|
long long actualSize = 0, unsharedSize = 0;
|
||||||
|
|
||||||
|
@ -689,7 +689,7 @@ void LocalStore::removeUnusedLinks(const GCState & state)
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st) == -1)
|
if (lstat(path.c_str(), &st) == -1)
|
||||||
throw SysError(format("statting '%1%'") % path);
|
throw SysError("statting '%1%'", path);
|
||||||
|
|
||||||
if (st.st_nlink != 1) {
|
if (st.st_nlink != 1) {
|
||||||
actualSize += st.st_size;
|
actualSize += st.st_size;
|
||||||
|
@ -700,14 +700,14 @@ void LocalStore::removeUnusedLinks(const GCState & state)
|
||||||
printMsg(lvlTalkative, format("deleting unused link '%1%'") % path);
|
printMsg(lvlTalkative, format("deleting unused link '%1%'") % path);
|
||||||
|
|
||||||
if (unlink(path.c_str()) == -1)
|
if (unlink(path.c_str()) == -1)
|
||||||
throw SysError(format("deleting '%1%'") % path);
|
throw SysError("deleting '%1%'", path);
|
||||||
|
|
||||||
state.results.bytesFreed += st.st_size;
|
state.results.bytesFreed += st.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(linksDir.c_str(), &st) == -1)
|
if (stat(linksDir.c_str(), &st) == -1)
|
||||||
throw SysError(format("statting '%1%'") % linksDir);
|
throw SysError("statting '%1%'", linksDir);
|
||||||
long long overhead = st.st_blocks * 512ULL;
|
long long overhead = st.st_blocks * 512ULL;
|
||||||
|
|
||||||
printInfo(format("note: currently hard linking saves %.2f MiB")
|
printInfo(format("note: currently hard linking saves %.2f MiB")
|
||||||
|
@ -801,7 +801,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
try {
|
try {
|
||||||
|
|
||||||
AutoCloseDir dir(opendir(realStoreDir.c_str()));
|
AutoCloseDir dir(opendir(realStoreDir.c_str()));
|
||||||
if (!dir) throw SysError(format("opening directory '%1%'") % realStoreDir);
|
if (!dir) throw SysError("opening directory '%1%'", realStoreDir);
|
||||||
|
|
||||||
/* Read the store and immediately delete all paths that
|
/* Read the store and immediately delete all paths that
|
||||||
aren't valid. When using --max-freed etc., deleting
|
aren't valid. When using --max-freed etc., deleting
|
||||||
|
|
|
@ -74,7 +74,7 @@ static void atomicWrite(const Path & path, const std::string & s)
|
||||||
AutoDelete del(tmp, false);
|
AutoDelete del(tmp, false);
|
||||||
writeFile(tmp, s);
|
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);
|
throw SysError("renaming '%1%' to '%2%'", tmp, path);
|
||||||
del.cancel();
|
del.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ struct LocalStoreAccessor : public FSAccessor
|
||||||
{
|
{
|
||||||
Path storePath = store->toStorePath(path);
|
Path storePath = store->toStorePath(path);
|
||||||
if (!store->isValidPath(store->parseStorePath(storePath)))
|
if (!store->isValidPath(store->parseStorePath(storePath)))
|
||||||
throw InvalidPath(format("path '%1%' is not a valid store path") % storePath);
|
throw InvalidPath("path '%1%' is not a valid store path", storePath);
|
||||||
return store->getRealStoreDir() + std::string(path, store->storeDir.size());
|
return store->getRealStoreDir() + std::string(path, store->storeDir.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,11 +33,11 @@ struct LocalStoreAccessor : public FSAccessor
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(realPath.c_str(), &st)) {
|
if (lstat(realPath.c_str(), &st)) {
|
||||||
if (errno == ENOENT || errno == ENOTDIR) return {Type::tMissing, 0, false};
|
if (errno == ENOENT || errno == ENOTDIR) return {Type::tMissing, 0, false};
|
||||||
throw SysError(format("getting status of '%1%'") % path);
|
throw SysError("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);
|
throw Error("file '%1%' has unsupported type", path);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
S_ISREG(st.st_mode) ? Type::tRegular :
|
S_ISREG(st.st_mode) ? Type::tRegular :
|
||||||
|
|
|
@ -92,13 +92,13 @@ LocalStore::LocalStore(const Params & params)
|
||||||
else {
|
else {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(realStoreDir.c_str(), &st))
|
if (stat(realStoreDir.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % realStoreDir);
|
throw SysError("getting attributes of path '%1%'", realStoreDir);
|
||||||
|
|
||||||
if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) {
|
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);
|
throw SysError("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);
|
throw SysError("changing permissions on path '%1%'", realStoreDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,12 +109,12 @@ LocalStore::LocalStore(const Params & params)
|
||||||
struct stat st;
|
struct stat st;
|
||||||
while (path != "/") {
|
while (path != "/") {
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting status of '%1%'") % path);
|
throw SysError("getting status of '%1%'", path);
|
||||||
if (S_ISLNK(st.st_mode))
|
if (S_ISLNK(st.st_mode))
|
||||||
throw Error(format(
|
throw Error(
|
||||||
"the path '%1%' is a symlink; "
|
"the path '%1%' is a symlink; "
|
||||||
"this is not allowed for the Nix store and its parent directories")
|
"this is not allowed for the Nix store and its parent directories",
|
||||||
% path);
|
path);
|
||||||
path = dirOf(path);
|
path = dirOf(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,8 +155,8 @@ LocalStore::LocalStore(const Params & params)
|
||||||
upgrade. */
|
upgrade. */
|
||||||
int curSchema = getSchema();
|
int curSchema = getSchema();
|
||||||
if (curSchema > nixSchemaVersion)
|
if (curSchema > nixSchemaVersion)
|
||||||
throw Error(format("current Nix store schema is version %1%, but I only support %2%")
|
throw Error("current Nix store schema is version %1%, but I only support %2%",
|
||||||
% curSchema % nixSchemaVersion);
|
curSchema, nixSchemaVersion);
|
||||||
|
|
||||||
else if (curSchema == 0) { /* new store */
|
else if (curSchema == 0) { /* new store */
|
||||||
curSchema = nixSchemaVersion;
|
curSchema = nixSchemaVersion;
|
||||||
|
@ -284,7 +284,7 @@ int LocalStore::getSchema()
|
||||||
if (pathExists(schemaPath)) {
|
if (pathExists(schemaPath)) {
|
||||||
string s = readFile(schemaPath);
|
string s = readFile(schemaPath);
|
||||||
if (!string2Int(s, curSchema))
|
if (!string2Int(s, curSchema))
|
||||||
throw Error(format("'%1%' is corrupt") % schemaPath);
|
throw Error("'%1%' is corrupt", schemaPath);
|
||||||
}
|
}
|
||||||
return curSchema;
|
return curSchema;
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ int LocalStore::getSchema()
|
||||||
void LocalStore::openDB(State & state, bool create)
|
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);
|
throw SysError("Nix database directory '%1%' is not writable", dbDir);
|
||||||
|
|
||||||
/* Open the Nix database. */
|
/* Open the Nix database. */
|
||||||
string dbPath = dbDir + "/db.sqlite";
|
string dbPath = dbDir + "/db.sqlite";
|
||||||
|
@ -367,7 +367,7 @@ void LocalStore::makeStoreWritable()
|
||||||
throw SysError("setting up a private mount namespace");
|
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);
|
throw SysError("remounting %1% writable", realStoreDir);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -388,7 +388,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
|
||||||
| 0444
|
| 0444
|
||||||
| (st.st_mode & S_IXUSR ? 0111 : 0);
|
| (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);
|
throw SysError("changing mode of '%1%' to %2$o", path, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -406,7 +406,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
|
||||||
#else
|
#else
|
||||||
if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1)
|
if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1)
|
||||||
#endif
|
#endif
|
||||||
throw SysError(format("changing modification time of '%1%'") % path);
|
throw SysError("changing modification time of '%1%'", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +415,7 @@ void canonicaliseTimestampAndPermissions(const Path & path)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError("getting attributes of path '%1%'", path);
|
||||||
canonicaliseTimestampAndPermissions(path, st);
|
canonicaliseTimestampAndPermissions(path, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,17 +430,17 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
|
||||||
setattrlist() to remove other attributes as well. */
|
setattrlist() to remove other attributes as well. */
|
||||||
if (lchflags(path.c_str(), 0)) {
|
if (lchflags(path.c_str(), 0)) {
|
||||||
if (errno != ENOTSUP)
|
if (errno != ENOTSUP)
|
||||||
throw SysError(format("clearing flags of path '%1%'") % path);
|
throw SysError("clearing flags of path '%1%'", path);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError("getting attributes of path '%1%'", path);
|
||||||
|
|
||||||
/* Really make sure that the path is of a supported type. */
|
/* 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);
|
throw Error("file '%1%' has an unsupported type", path);
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
/* Remove extended attributes / ACLs. */
|
/* Remove extended attributes / ACLs. */
|
||||||
|
@ -474,7 +474,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
|
||||||
if (fromUid != (uid_t) -1 && st.st_uid != fromUid) {
|
if (fromUid != (uid_t) -1 && st.st_uid != fromUid) {
|
||||||
assert(!S_ISDIR(st.st_mode));
|
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);
|
throw BuildError("invalid ownership on file '%1%'", path);
|
||||||
mode_t mode = st.st_mode & ~S_IFMT;
|
mode_t mode = st.st_mode & ~S_IFMT;
|
||||||
assert(S_ISLNK(st.st_mode) || (st.st_uid == geteuid() && (mode == 0444 || mode == 0555) && st.st_mtime == mtimeStore));
|
assert(S_ISLNK(st.st_mode) || (st.st_uid == geteuid() && (mode == 0444 || mode == 0555) && st.st_mtime == mtimeStore));
|
||||||
return;
|
return;
|
||||||
|
@ -498,8 +498,8 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
|
||||||
if (!S_ISLNK(st.st_mode) &&
|
if (!S_ISLNK(st.st_mode) &&
|
||||||
chown(path.c_str(), geteuid(), getegid()) == -1)
|
chown(path.c_str(), geteuid(), getegid()) == -1)
|
||||||
#endif
|
#endif
|
||||||
throw SysError(format("changing owner of '%1%' to %2%")
|
throw SysError("changing owner of '%1%' to %2%",
|
||||||
% path % geteuid());
|
path, geteuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
@ -518,11 +518,11 @@ void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & ino
|
||||||
be a symlink, since we can't change its ownership. */
|
be a symlink, since we can't change its ownership. */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError("getting attributes of path '%1%'", path);
|
||||||
|
|
||||||
if (st.st_uid != geteuid()) {
|
if (st.st_uid != geteuid()) {
|
||||||
assert(S_ISLNK(st.st_mode));
|
assert(S_ISLNK(st.st_mode));
|
||||||
throw Error(format("wrong ownership of top-level store path '%1%'") % path);
|
throw Error("wrong ownership of top-level store path '%1%'", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1392,7 +1392,7 @@ static void makeMutable(const Path & path)
|
||||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
|
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
if (errno == ELOOP) return; // it's a symlink
|
if (errno == ELOOP) return; // it's a symlink
|
||||||
throw SysError(format("opening file '%1%'") % path);
|
throw SysError("opening file '%1%'", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int flags = 0, old;
|
unsigned int flags = 0, old;
|
||||||
|
|
|
@ -184,7 +184,7 @@ struct NarAccessor : public FSAccessor
|
||||||
auto i = get(path);
|
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);
|
throw Error("path '%1%' inside NAR file is not a directory", path);
|
||||||
|
|
||||||
StringSet res;
|
StringSet res;
|
||||||
for (auto & child : i.children)
|
for (auto & child : i.children)
|
||||||
|
@ -197,7 +197,7 @@ struct NarAccessor : public FSAccessor
|
||||||
{
|
{
|
||||||
auto i = get(path);
|
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);
|
throw Error("path '%1%' inside NAR file is not a regular file", path);
|
||||||
|
|
||||||
if (getNarBytes) return getNarBytes(i.start, i.size);
|
if (getNarBytes) return getNarBytes(i.start, i.size);
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ struct NarAccessor : public FSAccessor
|
||||||
{
|
{
|
||||||
auto i = get(path);
|
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);
|
throw Error("path '%1%' inside NAR file is not a symlink", path);
|
||||||
return i.target;
|
return i.target;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@ NarInfo::NarInfo(const Store & store, const std::string & s, const std::string &
|
||||||
: ValidPathInfo(StorePath::dummy.clone()) // FIXME: hack
|
: ValidPathInfo(StorePath::dummy.clone()) // FIXME: hack
|
||||||
{
|
{
|
||||||
auto corrupt = [&]() {
|
auto corrupt = [&]() {
|
||||||
throw Error(format("NAR info file '%1%' is corrupt") % whence);
|
throw Error("NAR info file '%1%' is corrupt", whence);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto parseHashField = [&](const string & s) {
|
auto parseHashField = [&](const string & s) {
|
||||||
|
|
|
@ -19,9 +19,9 @@ static void makeWritable(const Path & path)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError("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);
|
throw SysError("changing writability of '%1%'", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
|
||||||
InodeHash inodeHash;
|
InodeHash inodeHash;
|
||||||
|
|
||||||
AutoCloseDir dir(opendir(linksDir.c_str()));
|
AutoCloseDir dir(opendir(linksDir.c_str()));
|
||||||
if (!dir) throw SysError(format("opening directory '%1%'") % linksDir);
|
if (!dir) throw SysError("opening directory '%1%'", linksDir);
|
||||||
|
|
||||||
struct dirent * dirent;
|
struct dirent * dirent;
|
||||||
while (errno = 0, dirent = readdir(dir.get())) { /* sic */
|
while (errno = 0, dirent = readdir(dir.get())) { /* sic */
|
||||||
|
@ -55,7 +55,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
|
||||||
// We don't care if we hit non-hash files, anything goes
|
// We don't care if we hit non-hash files, anything goes
|
||||||
inodeHash.insert(dirent->d_ino);
|
inodeHash.insert(dirent->d_ino);
|
||||||
}
|
}
|
||||||
if (errno) throw SysError(format("reading directory '%1%'") % linksDir);
|
if (errno) throw SysError("reading directory '%1%'", linksDir);
|
||||||
|
|
||||||
printMsg(lvlTalkative, format("loaded %1% hash inodes") % inodeHash.size());
|
printMsg(lvlTalkative, format("loaded %1% hash inodes") % inodeHash.size());
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
|
||||||
Strings names;
|
Strings names;
|
||||||
|
|
||||||
AutoCloseDir dir(opendir(path.c_str()));
|
AutoCloseDir dir(opendir(path.c_str()));
|
||||||
if (!dir) throw SysError(format("opening directory '%1%'") % path);
|
if (!dir) throw SysError("opening directory '%1%'", path);
|
||||||
|
|
||||||
struct dirent * dirent;
|
struct dirent * dirent;
|
||||||
while (errno = 0, dirent = readdir(dir.get())) { /* sic */
|
while (errno = 0, dirent = readdir(dir.get())) { /* sic */
|
||||||
|
@ -83,7 +83,7 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
|
||||||
if (name == "." || name == "..") continue;
|
if (name == "." || name == "..") continue;
|
||||||
names.push_back(name);
|
names.push_back(name);
|
||||||
}
|
}
|
||||||
if (errno) throw SysError(format("reading directory '%1%'") % path);
|
if (errno) throw SysError("reading directory '%1%'", path);
|
||||||
|
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats,
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError("getting attributes of path '%1%'", path);
|
||||||
|
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
/* HFS/macOS has some undocumented security feature disabling hardlinking for
|
/* HFS/macOS has some undocumented security feature disabling hardlinking for
|
||||||
|
@ -130,7 +130,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats,
|
||||||
NixOS (example: $fontconfig/var/cache being modified). Skip
|
NixOS (example: $fontconfig/var/cache being modified). Skip
|
||||||
those files. FIXME: check the modification time. */
|
those files. FIXME: check the modification time. */
|
||||||
if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) {
|
if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) {
|
||||||
printError(format("skipping suspicious writable file '%1%'") % path);
|
printError("skipping suspicious writable file '%1%'", path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats,
|
||||||
current file with a hard link to that file. */
|
current file with a hard link to that file. */
|
||||||
struct stat stLink;
|
struct stat stLink;
|
||||||
if (lstat(linkPath.c_str(), &stLink))
|
if (lstat(linkPath.c_str(), &stLink))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % linkPath);
|
throw SysError("getting attributes of path '%1%'", linkPath);
|
||||||
|
|
||||||
if (st.st_ino == stLink.st_ino) {
|
if (st.st_ino == stLink.st_ino) {
|
||||||
debug(format("'%1%' is already linked to '%2%'") % path % linkPath);
|
debug(format("'%1%' is already linked to '%2%'") % path % linkPath);
|
||||||
|
@ -194,7 +194,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st.st_size != stLink.st_size) {
|
if (st.st_size != stLink.st_size) {
|
||||||
printError(format("removing corrupted link '%1%'") % linkPath);
|
printError("removing corrupted link '%1%'", linkPath);
|
||||||
unlink(linkPath.c_str());
|
unlink(linkPath.c_str());
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats,
|
||||||
/* Atomically replace the old file with the new hard link. */
|
/* Atomically replace the old file with the new hard link. */
|
||||||
if (rename(tempLink.c_str(), path.c_str()) == -1) {
|
if (rename(tempLink.c_str(), path.c_str()) == -1) {
|
||||||
if (unlink(tempLink.c_str()) == -1)
|
if (unlink(tempLink.c_str()) == -1)
|
||||||
printError(format("unable to unlink '%1%'") % tempLink);
|
printError("unable to unlink '%1%'", tempLink);
|
||||||
if (errno == EMLINK) {
|
if (errno == EMLINK) {
|
||||||
/* Some filesystems generate too many links on the rename,
|
/* Some filesystems generate too many links on the rename,
|
||||||
rather than on the original link. (Probably it
|
rather than on the original link. (Probably it
|
||||||
|
@ -238,7 +238,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats,
|
||||||
debug("'%s' has reached maximum number of links", linkPath);
|
debug("'%s' has reached maximum number of links", linkPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw SysError(format("cannot rename '%1%' to '%2%'") % tempLink % path);
|
throw SysError("cannot rename '%1%' to '%2%'", tempLink, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
stats.filesLinked++;
|
stats.filesLinked++;
|
||||||
|
|
|
@ -20,7 +20,7 @@ AutoCloseFD openLockFile(const Path & path, bool create)
|
||||||
|
|
||||||
fd = open(path.c_str(), O_CLOEXEC | O_RDWR | (create ? O_CREAT : 0), 0600);
|
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);
|
throw SysError("opening lock file '%1%'", path);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ bool lockFile(int fd, LockType lockType, bool wait)
|
||||||
while (flock(fd, type) != 0) {
|
while (flock(fd, type) != 0) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
throw SysError(format("acquiring/releasing lock"));
|
throw SysError("acquiring/releasing lock");
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ bool lockFile(int fd, LockType lockType, bool wait)
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
if (errno == EWOULDBLOCK) return false;
|
if (errno == EWOULDBLOCK) return false;
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
throw SysError(format("acquiring/releasing lock"));
|
throw SysError("acquiring/releasing lock");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ bool PathLocks::lockPaths(const PathSet & paths,
|
||||||
hasn't been unlinked). */
|
hasn't been unlinked). */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat(fd.get(), &st) == -1)
|
if (fstat(fd.get(), &st) == -1)
|
||||||
throw SysError(format("statting lock file '%1%'") % lockPath);
|
throw SysError("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
|
/* This lock file has been unlinked, so we're holding
|
||||||
a lock on a deleted file. This means that other
|
a lock on a deleted file. This means that other
|
||||||
|
|
|
@ -50,7 +50,7 @@ Generations findGenerations(Path profile, int & curGen)
|
||||||
gen.number = n;
|
gen.number = n;
|
||||||
struct stat st;
|
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);
|
throw SysError("statting '%1%'", gen.path);
|
||||||
gen.creationTime = st.st_mtime;
|
gen.creationTime = st.st_mtime;
|
||||||
gens.push_back(gen);
|
gens.push_back(gen);
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ Path createGeneration(ref<LocalFSStore> store, Path profile, Path outPath)
|
||||||
static void removeFile(const Path & path)
|
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);
|
throw SysError("cannot unlink '%1%'", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ void deleteGenerations(const Path & profile, const std::set<unsigned int> & gens
|
||||||
Generations gens = findGenerations(profile, 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);
|
throw Error("cannot delete current generation of profile %1%'", profile);
|
||||||
|
|
||||||
for (auto & i : gens) {
|
for (auto & i : gens) {
|
||||||
if (gensToDelete.find(i.number) == gensToDelete.end()) continue;
|
if (gensToDelete.find(i.number) == gensToDelete.end()) continue;
|
||||||
|
@ -226,7 +226,7 @@ void deleteGenerationsOlderThan(const Path & profile, const string & timeSpec, b
|
||||||
int days;
|
int days;
|
||||||
|
|
||||||
if (!string2Int(strDays, days) || days < 1)
|
if (!string2Int(strDays, days) || days < 1)
|
||||||
throw Error(format("invalid number of days specifier '%1%'") % timeSpec);
|
throw Error("invalid number of days specifier '%1%'", timeSpec);
|
||||||
|
|
||||||
time_t oldTime = curTime - days * 24 * 3600;
|
time_t oldTime = curTime - days * 24 * 3600;
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ PathSet scanForReferences(const string & path,
|
||||||
auto baseName = std::string(baseNameOf(i));
|
auto baseName = std::string(baseNameOf(i));
|
||||||
string::size_type pos = baseName.find('-');
|
string::size_type pos = baseName.find('-');
|
||||||
if (pos == string::npos)
|
if (pos == string::npos)
|
||||||
throw Error(format("bad reference '%1%'") % i);
|
throw Error("bad reference '%1%'", i);
|
||||||
string s = string(baseName, 0, pos);
|
string s = string(baseName, 0, pos);
|
||||||
assert(s.size() == refLength);
|
assert(s.size() == refLength);
|
||||||
assert(backMap.find(s) == backMap.end());
|
assert(backMap.find(s) == backMap.end());
|
||||||
|
|
|
@ -51,7 +51,7 @@ std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path & path_)
|
||||||
std::string restPath = std::string(path, storePath.size());
|
std::string restPath = std::string(path, storePath.size());
|
||||||
|
|
||||||
if (!store->isValidPath(store->parseStorePath(storePath)))
|
if (!store->isValidPath(store->parseStorePath(storePath)))
|
||||||
throw InvalidPath(format("path '%1%' is not a valid store path") % storePath);
|
throw InvalidPath("path '%1%' is not a valid store path", storePath);
|
||||||
|
|
||||||
auto i = nars.find(storePath);
|
auto i = nars.find(storePath);
|
||||||
if (i != nars.end()) return {i->second, restPath};
|
if (i != nars.end()) return {i->second, restPath};
|
||||||
|
|
|
@ -116,11 +116,11 @@ ref<RemoteStore::Connection> UDSRemoteStore::openConnection()
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
addr.sun_family = AF_UNIX;
|
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);
|
throw Error("socket path '%1%' is too long", socketPath);
|
||||||
strcpy(addr.sun_path, socketPath.c_str());
|
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);
|
throw SysError("cannot connect to daemon at '%1%'", socketPath);
|
||||||
|
|
||||||
conn->from.fd = conn->fd.get();
|
conn->from.fd = conn->fd.get();
|
||||||
conn->to.fd = conn->fd.get();
|
conn->to.fd = conn->fd.get();
|
||||||
|
|
|
@ -32,8 +32,10 @@ namespace nix {
|
||||||
struct S3Error : public Error
|
struct S3Error : public Error
|
||||||
{
|
{
|
||||||
Aws::S3::S3Errors err;
|
Aws::S3::S3Errors err;
|
||||||
S3Error(Aws::S3::S3Errors err, const FormatOrString & fs)
|
|
||||||
: Error(fs), err(err) { };
|
template<typename... Args>
|
||||||
|
S3Error(Aws::S3::S3Errors err, const Args & ... args)
|
||||||
|
: Error(args...), err(err) { };
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Helper: given an Outcome<R, E>, return R in case of success, or
|
/* Helper: given an Outcome<R, E>, return R in case of success, or
|
||||||
|
@ -249,7 +251,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
// If bucket listing is disabled, 404s turn into 403s
|
// If bucket listing is disabled, 404s turn into 403s
|
||||||
|| error.GetErrorType() == Aws::S3::S3Errors::ACCESS_DENIED)
|
|| error.GetErrorType() == Aws::S3::S3Errors::ACCESS_DENIED)
|
||||||
return false;
|
return false;
|
||||||
throw Error(format("AWS error fetching '%s': %s") % path % error.GetMessage());
|
throw Error("AWS error fetching '%s': %s", path, error.GetMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -29,7 +29,7 @@ SQLite::SQLite(const Path & path, bool create)
|
||||||
{
|
{
|
||||||
if (sqlite3_open_v2(path.c_str(), &db,
|
if (sqlite3_open_v2(path.c_str(), &db,
|
||||||
SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
|
SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
|
||||||
throw Error(format("cannot open SQLite database '%s'") % path);
|
throw Error("cannot open SQLite database '%s'", path);
|
||||||
|
|
||||||
if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK)
|
if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK)
|
||||||
throwSQLiteError(db, "setting timeout");
|
throwSQLiteError(db, "setting timeout");
|
||||||
|
|
|
@ -22,7 +22,7 @@ bool Store::isInStore(const Path & path) const
|
||||||
Path Store::toStorePath(const Path & path) const
|
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);
|
throw Error("path '%1%' is not in the Nix store", path);
|
||||||
Path::size_type slash = path.find('/', storeDir.size() + 1);
|
Path::size_type slash = path.find('/', storeDir.size() + 1);
|
||||||
if (slash == Path::npos)
|
if (slash == Path::npos)
|
||||||
return path;
|
return path;
|
||||||
|
@ -40,7 +40,7 @@ Path Store::followLinksToStore(std::string_view _path) const
|
||||||
path = absPath(target, dirOf(path));
|
path = absPath(target, dirOf(path));
|
||||||
}
|
}
|
||||||
if (!isInStore(path))
|
if (!isInStore(path))
|
||||||
throw Error(format("path '%1%' is not in the Nix store") % path);
|
throw Error("path '%1%' is not in the Nix store", path);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ static void dumpContents(const Path & path, size_t size,
|
||||||
sink << "contents" << size;
|
sink << "contents" << size;
|
||||||
|
|
||||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
||||||
if (!fd) throw SysError(format("opening file '%1%'") % path);
|
if (!fd) throw SysError("opening file '%1%'", path);
|
||||||
|
|
||||||
std::vector<unsigned char> buf(65536);
|
std::vector<unsigned char> buf(65536);
|
||||||
size_t left = size;
|
size_t left = size;
|
||||||
|
@ -68,7 +68,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError("getting attributes of path '%1%'", path);
|
||||||
|
|
||||||
sink << "(";
|
sink << "(";
|
||||||
|
|
||||||
|
@ -94,8 +94,9 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
|
||||||
name.erase(pos);
|
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%'")
|
throw Error("file name collision in between '%1%' and '%2%'",
|
||||||
% (path + "/" + unhacked[name]) % (path + "/" + i.name));
|
(path + "/" + unhacked[name]),
|
||||||
|
(path + "/" + i.name));
|
||||||
unhacked[name] = i.name;
|
unhacked[name] = i.name;
|
||||||
} else
|
} else
|
||||||
unhacked[i.name] = i.name;
|
unhacked[i.name] = i.name;
|
||||||
|
@ -111,7 +112,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
|
||||||
else if (S_ISLNK(st.st_mode))
|
else if (S_ISLNK(st.st_mode))
|
||||||
sink << "type" << "symlink" << "target" << readLink(path);
|
sink << "type" << "symlink" << "target" << readLink(path);
|
||||||
|
|
||||||
else throw Error(format("file '%1%' has an unsupported type") % path);
|
else throw Error("file '%1%' has an unsupported type", path);
|
||||||
|
|
||||||
sink << ")";
|
sink << ")";
|
||||||
}
|
}
|
||||||
|
@ -247,7 +248,7 @@ static void parse(ParseSink & sink, Source & source, const Path & path)
|
||||||
} else if (s == "name") {
|
} else if (s == "name") {
|
||||||
name = readString(source);
|
name = readString(source);
|
||||||
if (name.empty() || name == "." || name == ".." || name.find('/') != string::npos || name.find((char) 0) != string::npos)
|
if (name.empty() || name == "." || name == ".." || name.find('/') != string::npos || name.find((char) 0) != string::npos)
|
||||||
throw Error(format("NAR contains invalid file name '%1%'") % name);
|
throw Error("NAR contains invalid file name '%1%'", name);
|
||||||
if (name <= prevName)
|
if (name <= prevName)
|
||||||
throw Error("NAR directory is not sorted");
|
throw Error("NAR directory is not sorted");
|
||||||
prevName = name;
|
prevName = name;
|
||||||
|
@ -303,14 +304,14 @@ struct RestoreSink : ParseSink
|
||||||
{
|
{
|
||||||
Path p = dstPath + 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);
|
throw SysError("creating directory '%1%'", p);
|
||||||
};
|
};
|
||||||
|
|
||||||
void createRegularFile(const Path & path)
|
void createRegularFile(const Path & path)
|
||||||
{
|
{
|
||||||
Path p = dstPath + path;
|
Path p = dstPath + path;
|
||||||
fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666);
|
fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666);
|
||||||
if (!fd) throw SysError(format("creating file '%1%'") % p);
|
if (!fd) throw SysError("creating file '%1%'", p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void isExecutable()
|
void isExecutable()
|
||||||
|
@ -332,7 +333,7 @@ struct RestoreSink : ParseSink
|
||||||
OpenSolaris). Since preallocation is just an
|
OpenSolaris). Since preallocation is just an
|
||||||
optimisation, ignore it. */
|
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);
|
throw SysError("preallocating file of %1% bytes", len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ void Args::parseCmdline(const Strings & _cmdline)
|
||||||
}
|
}
|
||||||
else if (!dashDash && std::string(arg, 0, 1) == "-") {
|
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);
|
throw UsageError("unrecognised flag '%1%'", arg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pendingArgs.push_back(*pos++);
|
pendingArgs.push_back(*pos++);
|
||||||
|
@ -104,8 +104,9 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
|
||||||
for (size_t n = 0 ; n < flag.arity; ++n) {
|
for (size_t n = 0 ; n < flag.arity; ++n) {
|
||||||
if (pos == end) {
|
if (pos == end) {
|
||||||
if (flag.arity == ArityAny) break;
|
if (flag.arity == ArityAny) break;
|
||||||
throw UsageError(format("flag '%1%' requires %2% argument(s)")
|
throw UsageError("flag '%1%' requires %2% argument(s)",
|
||||||
% name % flag.arity);
|
name,
|
||||||
|
flag.arity);
|
||||||
}
|
}
|
||||||
args.push_back(*pos++);
|
args.push_back(*pos++);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +134,7 @@ bool Args::processArgs(const Strings & args, bool finish)
|
||||||
{
|
{
|
||||||
if (expectedArgs.empty()) {
|
if (expectedArgs.empty()) {
|
||||||
if (!args.empty())
|
if (!args.empty())
|
||||||
throw UsageError(format("unexpected argument '%1%'") % args.front());
|
throw UsageError("unexpected argument '%1%'", args.front());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -481,7 +481,7 @@ ref<CompressionSink> makeCompressionSink(const std::string & method, Sink & next
|
||||||
else if (method == "br")
|
else if (method == "br")
|
||||||
return make_ref<BrotliCompressionSink>(nextSink);
|
return make_ref<BrotliCompressionSink>(nextSink);
|
||||||
else
|
else
|
||||||
throw UnknownCompressionMethod(format("unknown compression method '%s'") % method);
|
throw UnknownCompressionMethod("unknown compression method '%s'", method);
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<std::string> compress(const std::string & method, const std::string & in, const bool parallel)
|
ref<std::string> compress(const std::string & method, const std::string & in, const bool parallel)
|
||||||
|
|
|
@ -92,15 +92,15 @@ public:
|
||||||
{
|
{
|
||||||
fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
|
fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
|
||||||
}
|
}
|
||||||
|
hintformat(const hintformat &hf)
|
||||||
|
: fmt(hf.fmt)
|
||||||
|
{}
|
||||||
template<class T>
|
template<class T>
|
||||||
hintformat& operator%(const T &value)
|
hintformat& operator%(const T &value)
|
||||||
{
|
{
|
||||||
fmt % yellowify(value);
|
fmt % yellowify(value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
hintformat(const hintformat &hf)
|
|
||||||
: fmt(hf.fmt)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
std::string str() const
|
std::string str() const
|
||||||
|
|
|
@ -93,7 +93,9 @@ public:
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
BaseError(unsigned int status, const Args & ... args)
|
BaseError(unsigned int status, const Args & ... args)
|
||||||
: err(hintfmt(args...))
|
: err { .level = lvlError,
|
||||||
|
.hint = hintfmt(args...)
|
||||||
|
}
|
||||||
, status(status)
|
, status(status)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ Path canonPath(const Path & path, bool resolveSymlinks)
|
||||||
string s;
|
string s;
|
||||||
|
|
||||||
if (path[0] != '/')
|
if (path[0] != '/')
|
||||||
throw Error(format("not an absolute path: '%1%'") % path);
|
throw Error("not an absolute path: '%1%'", path);
|
||||||
|
|
||||||
string::const_iterator i = path.begin(), end = path.end();
|
string::const_iterator i = path.begin(), end = path.end();
|
||||||
string temp;
|
string temp;
|
||||||
|
@ -165,7 +165,7 @@ Path canonPath(const Path & path, bool resolveSymlinks)
|
||||||
the symlink target might contain new symlinks). */
|
the symlink target might contain new symlinks). */
|
||||||
if (resolveSymlinks && isLink(s)) {
|
if (resolveSymlinks && isLink(s)) {
|
||||||
if (++followCount >= maxFollow)
|
if (++followCount >= maxFollow)
|
||||||
throw Error(format("infinite symlink recursion in path '%1%'") % path);
|
throw Error("infinite symlink recursion in path '%1%'", path);
|
||||||
temp = absPath(readLink(s), dirOf(s))
|
temp = absPath(readLink(s), dirOf(s))
|
||||||
+ string(i, end);
|
+ string(i, end);
|
||||||
i = temp.begin(); /* restart */
|
i = temp.begin(); /* restart */
|
||||||
|
@ -226,7 +226,7 @@ struct stat lstat(const Path & path)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting status of '%1%'") % path);
|
throw SysError("getting status of '%1%'", path);
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ bool pathExists(const Path & path)
|
||||||
res = lstat(path.c_str(), &st);
|
res = lstat(path.c_str(), &st);
|
||||||
if (!res) return true;
|
if (!res) return true;
|
||||||
if (errno != ENOENT && errno != ENOTDIR)
|
if (errno != ENOENT && errno != ENOTDIR)
|
||||||
throw SysError(format("getting status of %1%") % path);
|
throw SysError("getting status of %1%", path);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ DirEntries readDirectory(const Path & path)
|
||||||
entries.reserve(64);
|
entries.reserve(64);
|
||||||
|
|
||||||
AutoCloseDir dir(opendir(path.c_str()));
|
AutoCloseDir dir(opendir(path.c_str()));
|
||||||
if (!dir) throw SysError(format("opening directory '%1%'") % path);
|
if (!dir) throw SysError("opening directory '%1%'", path);
|
||||||
|
|
||||||
struct dirent * dirent;
|
struct dirent * dirent;
|
||||||
while (errno = 0, dirent = readdir(dir.get())) { /* sic */
|
while (errno = 0, dirent = readdir(dir.get())) { /* sic */
|
||||||
|
@ -289,7 +289,7 @@ DirEntries readDirectory(const Path & path)
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (errno) throw SysError(format("reading directory '%1%'") % path);
|
if (errno) throw SysError("reading directory '%1%'", path);
|
||||||
|
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,7 @@ string readFile(const Path & path, bool drain)
|
||||||
{
|
{
|
||||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
||||||
if (!fd)
|
if (!fd)
|
||||||
throw SysError(format("opening file '%1%'") % path);
|
throw SysError("opening file '%1%'", path);
|
||||||
return drain ? drainFD(fd.get()) : readFile(fd.get());
|
return drain ? drainFD(fd.get()) : readFile(fd.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ void writeFile(const Path & path, const string & s, mode_t mode)
|
||||||
{
|
{
|
||||||
AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode);
|
AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode);
|
||||||
if (!fd)
|
if (!fd)
|
||||||
throw SysError(format("opening file '%1%'") % path);
|
throw SysError("opening file '%1%'", path);
|
||||||
writeFull(fd.get(), s);
|
writeFull(fd.get(), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ void writeFile(const Path & path, Source & source, mode_t mode)
|
||||||
{
|
{
|
||||||
AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode);
|
AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode);
|
||||||
if (!fd)
|
if (!fd)
|
||||||
throw SysError(format("opening file '%1%'") % path);
|
throw SysError("opening file '%1%'", path);
|
||||||
|
|
||||||
std::vector<unsigned char> buf(64 * 1024);
|
std::vector<unsigned char> buf(64 * 1024);
|
||||||
|
|
||||||
|
@ -396,7 +396,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st) == -1) {
|
if (lstat(path.c_str(), &st) == -1) {
|
||||||
if (errno == ENOENT) return;
|
if (errno == ENOENT) return;
|
||||||
throw SysError(format("getting status of '%1%'") % path);
|
throw SysError("getting status of '%1%'", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_ISDIR(st.st_mode) && st.st_nlink == 1)
|
if (!S_ISDIR(st.st_mode) && st.st_nlink == 1)
|
||||||
|
@ -407,7 +407,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
|
||||||
const auto PERM_MASK = S_IRUSR | S_IWUSR | S_IXUSR;
|
const auto PERM_MASK = S_IRUSR | S_IWUSR | S_IXUSR;
|
||||||
if ((st.st_mode & PERM_MASK) != PERM_MASK) {
|
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);
|
throw SysError("chmod '%1%'", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto & i : readDirectory(path))
|
for (auto & i : readDirectory(path))
|
||||||
|
@ -416,7 +416,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
|
||||||
|
|
||||||
if (remove(path.c_str()) == -1) {
|
if (remove(path.c_str()) == -1) {
|
||||||
if (errno == ENOENT) return;
|
if (errno == ENOENT) return;
|
||||||
throw SysError(format("cannot unlink '%1%'") % path);
|
throw SysError("cannot unlink '%1%'", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,12 +468,12 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix,
|
||||||
"wheel", then "tar" will fail to unpack archives that
|
"wheel", then "tar" will fail to unpack archives that
|
||||||
have the setgid bit set on directories. */
|
have the setgid bit set on directories. */
|
||||||
if (chown(tmpDir.c_str(), (uid_t) -1, getegid()) != 0)
|
if (chown(tmpDir.c_str(), (uid_t) -1, getegid()) != 0)
|
||||||
throw SysError(format("setting group of directory '%1%'") % tmpDir);
|
throw SysError("setting group of directory '%1%'", tmpDir);
|
||||||
#endif
|
#endif
|
||||||
return tmpDir;
|
return tmpDir;
|
||||||
}
|
}
|
||||||
if (errno != EEXIST)
|
if (errno != EEXIST)
|
||||||
throw SysError(format("creating directory '%1%'") % tmpDir);
|
throw SysError("creating directory '%1%'", tmpDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,15 +555,15 @@ Paths createDirs(const Path & path)
|
||||||
if (lstat(path.c_str(), &st) == -1) {
|
if (lstat(path.c_str(), &st) == -1) {
|
||||||
created = createDirs(dirOf(path));
|
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);
|
throw SysError("creating directory '%1%'", path);
|
||||||
st = lstat(path);
|
st = lstat(path);
|
||||||
created.push_back(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);
|
throw SysError("statting symlink '%1%'", path);
|
||||||
|
|
||||||
if (!S_ISDIR(st.st_mode)) throw Error(format("'%1%' is not a directory") % path);
|
if (!S_ISDIR(st.st_mode)) throw Error("'%1%' is not a directory", path);
|
||||||
|
|
||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
@ -572,7 +572,7 @@ Paths createDirs(const Path & path)
|
||||||
void createSymlink(const Path & target, const Path & link)
|
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);
|
throw SysError("creating symlink from '%1%' to '%2%'", link, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -589,7 +589,7 @@ void replaceSymlink(const Path & target, const Path & link)
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
throw SysError("renaming '%1%' to '%2%'", tmp, link);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -694,7 +694,7 @@ AutoDelete::~AutoDelete()
|
||||||
deletePath(path);
|
deletePath(path);
|
||||||
else {
|
else {
|
||||||
if (remove(path.c_str()) == -1)
|
if (remove(path.c_str()) == -1)
|
||||||
throw SysError(format("cannot unlink '%1%'") % path);
|
throw SysError("cannot unlink '%1%'", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
@ -760,7 +760,7 @@ void AutoCloseFD::close()
|
||||||
if (fd != -1) {
|
if (fd != -1) {
|
||||||
if (::close(fd) == -1)
|
if (::close(fd) == -1)
|
||||||
/* This should never happen. */
|
/* This should never happen. */
|
||||||
throw SysError(format("closing file descriptor %1%") % fd);
|
throw SysError("closing file descriptor %1%", fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -920,7 +920,7 @@ void killUser(uid_t uid)
|
||||||
#endif
|
#endif
|
||||||
if (errno == ESRCH) break; /* no more processes */
|
if (errno == ESRCH) break; /* no more processes */
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
throw SysError(format("cannot kill processes for uid '%1%'") % uid);
|
throw SysError("cannot kill processes for uid '%1%'", uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
_exit(0);
|
_exit(0);
|
||||||
|
@ -928,7 +928,7 @@ void killUser(uid_t uid)
|
||||||
|
|
||||||
int status = pid.wait();
|
int status = pid.wait();
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
throw Error(format("cannot kill processes for uid '%1%': %2%") % uid % statusToString(status));
|
throw Error("cannot kill processes for uid '%1%': %2%", uid, statusToString(status));
|
||||||
|
|
||||||
/* !!! We should really do some check to make sure that there are
|
/* !!! We should really do some check to make sure that there are
|
||||||
no processes left running under `uid', but there is no portable
|
no processes left running under `uid', but there is no portable
|
||||||
|
@ -1322,7 +1322,7 @@ void ignoreException()
|
||||||
try {
|
try {
|
||||||
throw;
|
throw;
|
||||||
} catch (std::exception & e) {
|
} catch (std::exception & e) {
|
||||||
printError(format("error (ignored): %1%") % e.what());
|
printError("error (ignored): %1%", e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1440,7 +1440,7 @@ void callFailure(const std::function<void(std::exception_ptr exc)> & failure, st
|
||||||
try {
|
try {
|
||||||
failure(exc);
|
failure(exc);
|
||||||
} catch (std::exception & e) {
|
} catch (std::exception & e) {
|
||||||
printError(format("uncaught exception: %s") % e.what());
|
printError("uncaught exception: %s", e.what());
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,8 @@ static void writeChannels()
|
||||||
{
|
{
|
||||||
auto channelsFD = AutoCloseFD{open(channelsList.c_str(), O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC, 0644)};
|
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);
|
throw Error("");
|
||||||
|
// throw SysError("opening '%1%' for writing", channelsList);
|
||||||
for (const auto & channel : channels)
|
for (const auto & channel : channels)
|
||||||
writeFull(channelsFD.get(), channel.second + " " + channel.first + "\n");
|
writeFull(channelsFD.get(), channel.second + " " + channel.first + "\n");
|
||||||
}
|
}
|
||||||
|
@ -46,9 +47,11 @@ static void writeChannels()
|
||||||
static void addChannel(const string & url, const string & name)
|
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);
|
throw Error("");
|
||||||
|
// throw Error("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);
|
throw Error("");
|
||||||
|
// throw Error("invalid channel identifier '%1%'", name);
|
||||||
readChannels();
|
readChannels();
|
||||||
channels[name] = url;
|
channels[name] = url;
|
||||||
writeChannels();
|
writeChannels();
|
||||||
|
@ -140,9 +143,11 @@ static void update(const StringSet & channelNames)
|
||||||
if (S_ISLNK(st.st_mode))
|
if (S_ISLNK(st.st_mode))
|
||||||
// old-skool ~/.nix-defexpr
|
// old-skool ~/.nix-defexpr
|
||||||
if (unlink(nixDefExpr.c_str()) == -1)
|
if (unlink(nixDefExpr.c_str()) == -1)
|
||||||
throw SysError(format("unlinking %1%") % nixDefExpr);
|
throw Error("");
|
||||||
|
// throw SysError("unlinking %1%", nixDefExpr);
|
||||||
} else if (errno != ENOENT) {
|
} else if (errno != ENOENT) {
|
||||||
throw SysError(format("getting status of %1%") % nixDefExpr);
|
throw Error("");
|
||||||
|
// throw SysError("getting status of %1%", nixDefExpr);
|
||||||
}
|
}
|
||||||
createDirs(nixDefExpr);
|
createDirs(nixDefExpr);
|
||||||
auto channelLink = nixDefExpr + "/channels";
|
auto channelLink = nixDefExpr + "/channels";
|
||||||
|
@ -194,10 +199,12 @@ static int _main(int argc, char ** argv)
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case cNone:
|
case cNone:
|
||||||
throw UsageError("no command specified");
|
throw Error("");
|
||||||
|
// throw UsageError("no command specified");
|
||||||
case cAdd:
|
case cAdd:
|
||||||
if (args.size() < 1 || args.size() > 2)
|
if (args.size() < 1 || args.size() > 2)
|
||||||
throw UsageError("'--add' requires one or two arguments");
|
throw Error("");
|
||||||
|
// throw UsageError("'--add' requires one or two arguments");
|
||||||
{
|
{
|
||||||
auto url = args[0];
|
auto url = args[0];
|
||||||
std::string name;
|
std::string name;
|
||||||
|
@ -213,12 +220,14 @@ static int _main(int argc, char ** argv)
|
||||||
break;
|
break;
|
||||||
case cRemove:
|
case cRemove:
|
||||||
if (args.size() != 1)
|
if (args.size() != 1)
|
||||||
throw UsageError("'--remove' requires one argument");
|
throw Error("");
|
||||||
|
// throw UsageError("'--remove' requires one argument");
|
||||||
removeChannel(args[0]);
|
removeChannel(args[0]);
|
||||||
break;
|
break;
|
||||||
case cList:
|
case cList:
|
||||||
if (!args.empty())
|
if (!args.empty())
|
||||||
throw UsageError("'--list' expects no arguments");
|
throw Error("");
|
||||||
|
// throw UsageError("'--list' expects no arguments");
|
||||||
readChannels();
|
readChannels();
|
||||||
for (const auto & channel : channels)
|
for (const auto & channel : channels)
|
||||||
std::cout << channel.first << ' ' << channel.second << '\n';
|
std::cout << channel.first << ' ' << channel.second << '\n';
|
||||||
|
@ -228,7 +237,8 @@ static int _main(int argc, char ** argv)
|
||||||
break;
|
break;
|
||||||
case cRollback:
|
case cRollback:
|
||||||
if (args.size() > 1)
|
if (args.size() > 1)
|
||||||
throw UsageError("'--rollback' has at most one argument");
|
throw Error("");
|
||||||
|
// throw UsageError("'--rollback' has at most one argument");
|
||||||
Strings envArgs{"--profile", profile};
|
Strings envArgs{"--profile", profile};
|
||||||
if (args.size() == 1) {
|
if (args.size() == 1) {
|
||||||
envArgs.push_back("--switch-generation");
|
envArgs.push_back("--switch-generation");
|
||||||
|
|
|
@ -36,7 +36,7 @@ using namespace nix::daemon;
|
||||||
#define SPLICE_F_MOVE 0
|
#define SPLICE_F_MOVE 0
|
||||||
static ssize_t splice(int fd_in, void *off_in, int fd_out, void *off_out, size_t len, unsigned int flags)
|
static ssize_t splice(int fd_in, void *off_in, int fd_out, void *off_out, size_t len, unsigned int flags)
|
||||||
{
|
{
|
||||||
/* We ignore most parameters, we just have them for conformance with the linux syscall */
|
// We ignore most parameters, we just have them for conformance with the linux syscall
|
||||||
std::vector<char> buf(8192);
|
std::vector<char> buf(8192);
|
||||||
auto read_count = read(fd_in, buf.data(), buf.size());
|
auto read_count = read(fd_in, buf.data(), buf.size());
|
||||||
if (read_count == -1)
|
if (read_count == -1)
|
||||||
|
@ -57,7 +57,7 @@ static void sigChldHandler(int sigNo)
|
||||||
{
|
{
|
||||||
// Ensure we don't modify errno of whatever we've interrupted
|
// Ensure we don't modify errno of whatever we've interrupted
|
||||||
auto saved_errno = errno;
|
auto saved_errno = errno;
|
||||||
/* Reap all dead children. */
|
// Reap all dead children.
|
||||||
while (waitpid(-1, 0, WNOHANG) > 0) ;
|
while (waitpid(-1, 0, WNOHANG) > 0) ;
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ struct PeerInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Get the identity of the caller, if possible. */
|
// Get the identity of the caller, if possible.
|
||||||
static PeerInfo getPeerInfo(int remote)
|
static PeerInfo getPeerInfo(int remote)
|
||||||
{
|
{
|
||||||
PeerInfo peer = { false, 0, false, 0, false, 0 };
|
PeerInfo peer = { false, 0, false, 0, false, 0 };
|
||||||
|
@ -154,13 +154,12 @@ static void daemonLoop(char * * argv)
|
||||||
if (chdir("/") == -1)
|
if (chdir("/") == -1)
|
||||||
throw SysError("cannot change current directory");
|
throw SysError("cannot change current directory");
|
||||||
|
|
||||||
/* Get rid of children automatically; don't let them become
|
// Get rid of children automatically; don't let them become zombies.
|
||||||
zombies. */
|
|
||||||
setSigChldAction(true);
|
setSigChldAction(true);
|
||||||
|
|
||||||
AutoCloseFD fdSocket;
|
AutoCloseFD fdSocket;
|
||||||
|
|
||||||
/* Handle socket-based activation by systemd. */
|
// Handle socket-based activation by systemd.
|
||||||
auto listenFds = getEnv("LISTEN_FDS");
|
auto listenFds = getEnv("LISTEN_FDS");
|
||||||
if (listenFds) {
|
if (listenFds) {
|
||||||
if (getEnv("LISTEN_PID") != std::to_string(getpid()) || listenFds != "1")
|
if (getEnv("LISTEN_PID") != std::to_string(getpid()) || listenFds != "1")
|
||||||
|
@ -169,17 +168,17 @@ static void daemonLoop(char * * argv)
|
||||||
closeOnExec(fdSocket.get());
|
closeOnExec(fdSocket.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, create and bind to a Unix domain socket. */
|
// Otherwise, create and bind to a Unix domain socket.
|
||||||
else {
|
else {
|
||||||
createDirs(dirOf(settings.nixDaemonSocketFile));
|
createDirs(dirOf(settings.nixDaemonSocketFile));
|
||||||
fdSocket = createUnixDomainSocket(settings.nixDaemonSocketFile, 0666);
|
fdSocket = createUnixDomainSocket(settings.nixDaemonSocketFile, 0666);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop accepting connections. */
|
// Loop accepting connections.
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/* Accept a connection. */
|
// Accept a connection.
|
||||||
struct sockaddr_un remoteAddr;
|
struct sockaddr_un remoteAddr;
|
||||||
socklen_t remoteAddrLen = sizeof(remoteAddr);
|
socklen_t remoteAddrLen = sizeof(remoteAddr);
|
||||||
|
|
||||||
|
@ -209,13 +208,13 @@ static void daemonLoop(char * * argv)
|
||||||
trusted = Trusted;
|
trusted = Trusted;
|
||||||
|
|
||||||
if ((!trusted && !matchUser(user, group, allowedUsers)) || group == settings.buildUsersGroup)
|
if ((!trusted && !matchUser(user, group, allowedUsers)) || group == settings.buildUsersGroup)
|
||||||
throw Error(format("user '%1%' is not allowed to connect to the Nix daemon") % user);
|
throw Error("user '%1%' is not allowed to connect to the Nix daemon", user);
|
||||||
|
|
||||||
printInfo(format((string) "accepted connection from pid %1%, user %2%" + (trusted ? " (trusted)" : ""))
|
printInfo(format((string) "accepted connection from pid %1%, user %2%" + (trusted ? " (trusted)" : ""))
|
||||||
% (peer.pidKnown ? std::to_string(peer.pid) : "<unknown>")
|
% (peer.pidKnown ? std::to_string(peer.pid) : "<unknown>")
|
||||||
% (peer.uidKnown ? user : "<unknown>"));
|
% (peer.uidKnown ? user : "<unknown>"));
|
||||||
|
|
||||||
/* Fork a child to handle the connection. */
|
// Fork a child to handle the connection.
|
||||||
ProcessOptions options;
|
ProcessOptions options;
|
||||||
options.errorPrefix = "unexpected Nix daemon error: ";
|
options.errorPrefix = "unexpected Nix daemon error: ";
|
||||||
options.dieWithParent = false;
|
options.dieWithParent = false;
|
||||||
|
@ -224,20 +223,20 @@ static void daemonLoop(char * * argv)
|
||||||
startProcess([&]() {
|
startProcess([&]() {
|
||||||
fdSocket = -1;
|
fdSocket = -1;
|
||||||
|
|
||||||
/* Background the daemon. */
|
// Background the daemon.
|
||||||
if (setsid() == -1)
|
if (setsid() == -1)
|
||||||
throw SysError(format("creating a new session"));
|
throw SysError("creating a new session");
|
||||||
|
|
||||||
/* Restore normal handling of SIGCHLD. */
|
// Restore normal handling of SIGCHLD.
|
||||||
setSigChldAction(false);
|
setSigChldAction(false);
|
||||||
|
|
||||||
/* For debugging, stuff the pid into argv[1]. */
|
// For debugging, stuff the pid into argv[1].
|
||||||
if (peer.pidKnown && argv[1]) {
|
if (peer.pidKnown && argv[1]) {
|
||||||
string processName = std::to_string(peer.pid);
|
string processName = std::to_string(peer.pid);
|
||||||
strncpy(argv[1], processName.c_str(), strlen(argv[1]));
|
strncpy(argv[1], processName.c_str(), strlen(argv[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the connection. */
|
// Handle the connection.
|
||||||
FdSource from(remote.get());
|
FdSource from(remote.get());
|
||||||
FdSink to(remote.get());
|
FdSink to(remote.get());
|
||||||
processConnection(openUncachedStore(), from, to, trusted, NotRecursive, user, peer.uid);
|
processConnection(openUncachedStore(), from, to, trusted, NotRecursive, user, peer.uid);
|
||||||
|
@ -248,7 +247,7 @@ static void daemonLoop(char * * argv)
|
||||||
} catch (Interrupted & e) {
|
} catch (Interrupted & e) {
|
||||||
return;
|
return;
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
printError(format("error processing connection: %1%") % e.msg());
|
printError("error processing connection: %1%", e.msg());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,7 +260,7 @@ static int _main(int argc, char * * argv)
|
||||||
|
|
||||||
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||||
if (*arg == "--daemon")
|
if (*arg == "--daemon")
|
||||||
; /* ignored for backwards compatibility */
|
; // ignored for backwards compatibility
|
||||||
else if (*arg == "--help")
|
else if (*arg == "--help")
|
||||||
showManPage("nix-daemon");
|
showManPage("nix-daemon");
|
||||||
else if (*arg == "--version")
|
else if (*arg == "--version")
|
||||||
|
@ -276,7 +275,7 @@ static int _main(int argc, char * * argv)
|
||||||
|
|
||||||
if (stdio) {
|
if (stdio) {
|
||||||
if (getStoreType() == tDaemon) {
|
if (getStoreType() == tDaemon) {
|
||||||
/* Forward on this connection to the real daemon */
|
// Forward on this connection to the real daemon
|
||||||
auto socketPath = settings.nixDaemonSocketFile;
|
auto socketPath = settings.nixDaemonSocketFile;
|
||||||
auto s = socket(PF_UNIX, SOCK_STREAM, 0);
|
auto s = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||||
if (s == -1)
|
if (s == -1)
|
||||||
|
@ -284,17 +283,17 @@ static int _main(int argc, char * * argv)
|
||||||
|
|
||||||
auto socketDir = dirOf(socketPath);
|
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);
|
throw SysError("changing to socket directory '%1%'", socketDir);
|
||||||
|
|
||||||
auto socketName = std::string(baseNameOf(socketPath));
|
auto socketName = std::string(baseNameOf(socketPath));
|
||||||
auto addr = sockaddr_un{};
|
auto addr = sockaddr_un{};
|
||||||
addr.sun_family = AF_UNIX;
|
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);
|
throw Error("socket name %1% is too long", socketName);
|
||||||
strcpy(addr.sun_path, socketName.c_str());
|
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);
|
throw SysError("cannot connect to daemon at %1%", socketPath);
|
||||||
|
|
||||||
auto nfds = (s > STDIN_FILENO ? s : STDIN_FILENO) + 1;
|
auto nfds = (s > STDIN_FILENO ? s : STDIN_FILENO) + 1;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
using std::cout;
|
using std::cout;
|
||||||
|
|
||||||
|
@ -70,8 +69,7 @@ typedef void (* Operation) (Globals & globals,
|
||||||
static string needArg(Strings::iterator & i,
|
static string needArg(Strings::iterator & i,
|
||||||
Strings & args, const string & arg)
|
Strings & args, const string & arg)
|
||||||
{
|
{
|
||||||
if (i == args.end()) throw UsageError(
|
if (i == args.end()) throw UsageError( "'%1%' requires an argument", arg);
|
||||||
format("'%1%' requires an argument") % arg);
|
|
||||||
return *i++;
|
return *i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +131,7 @@ static void getAllExprs(EvalState & state,
|
||||||
Value & vArg(*state.allocValue());
|
Value & vArg(*state.allocValue());
|
||||||
mkString(vArg, path2);
|
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);
|
throw Error("too many Nix expressions in directory '%1%'", path);
|
||||||
mkApp(*state.allocAttr(v, state.symbols.create(attrName)), vFun, vArg);
|
mkApp(*state.allocAttr(v, state.symbols.create(attrName)), vFun, vArg);
|
||||||
}
|
}
|
||||||
else if (S_ISDIR(st.st_mode))
|
else if (S_ISDIR(st.st_mode))
|
||||||
|
@ -144,11 +142,12 @@ static void getAllExprs(EvalState & state,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void loadSourceExpr(EvalState & state, const Path & path, Value & v)
|
static void loadSourceExpr(EvalState & state, const Path & path, Value & v)
|
||||||
{
|
{
|
||||||
struct stat st;
|
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);
|
throw SysError("getting inon about '%1%'", path);
|
||||||
|
|
||||||
if (isNixExpr(path, st))
|
if (isNixExpr(path, st))
|
||||||
state.evalFile(path, v);
|
state.evalFile(path, v);
|
||||||
|
@ -221,7 +220,7 @@ static void checkSelectorUse(DrvNames & selectors)
|
||||||
/* Check that all selectors have been used. */
|
/* Check that all selectors have been used. */
|
||||||
for (auto & i : selectors)
|
for (auto & i : selectors)
|
||||||
if (i.hits == 0 && i.fullName != "*")
|
if (i.hits == 0 && i.fullName != "*")
|
||||||
throw Error(format("selector '%1%' matches no derivations") % i.fullName);
|
throw Error("selector '%1%' matches no derivations", i.fullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -507,7 +506,7 @@ static void opInstall(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
globals.preserveInstalled = true;
|
globals.preserveInstalled = true;
|
||||||
else if (arg == "--remove-all" || arg == "-r")
|
else if (arg == "--remove-all" || arg == "-r")
|
||||||
globals.removeAll = true;
|
globals.removeAll = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % arg);
|
else throw UsageError("unknown flag '%1%'", arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
installDerivations(globals, opArgs, globals.profile);
|
installDerivations(globals, opArgs, globals.profile);
|
||||||
|
@ -618,7 +617,7 @@ static void opUpgrade(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
else if (arg == "--leq") upgradeType = utLeq;
|
else if (arg == "--leq") upgradeType = utLeq;
|
||||||
else if (arg == "--eq") upgradeType = utEq;
|
else if (arg == "--eq") upgradeType = utEq;
|
||||||
else if (arg == "--always") upgradeType = utAlways;
|
else if (arg == "--always") upgradeType = utAlways;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % arg);
|
else throw UsageError("unknown flag '%1%'", arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
upgradeDerivations(globals, opArgs, upgradeType);
|
upgradeDerivations(globals, opArgs, upgradeType);
|
||||||
|
@ -637,7 +636,7 @@ static void setMetaFlag(EvalState & state, DrvInfo & drv,
|
||||||
static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs)
|
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());
|
throw UsageError("unknown flag '%1%'", opFlags.front());
|
||||||
if (opArgs.size() < 2)
|
if (opArgs.size() < 2)
|
||||||
throw UsageError("not enough arguments to '--set-flag'");
|
throw UsageError("not enough arguments to '--set-flag'");
|
||||||
|
|
||||||
|
@ -680,7 +679,7 @@ static void opSet(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
|
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
|
||||||
string arg = *i++;
|
string arg = *i++;
|
||||||
if (parseInstallSourceOptions(globals, i, opFlags, arg)) ;
|
if (parseInstallSourceOptions(globals, i, opFlags, arg)) ;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % arg);
|
else throw UsageError("unknown flag '%1%'", arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrvInfos elems;
|
DrvInfos elems;
|
||||||
|
@ -748,7 +747,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
|
||||||
static void opUninstall(Globals & globals, Strings opFlags, Strings opArgs)
|
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());
|
throw UsageError("unknown flag '%1%'", opFlags.front());
|
||||||
uninstallDerivations(globals, opArgs, globals.profile);
|
uninstallDerivations(globals, opArgs, globals.profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -911,7 +910,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
else if (arg == "--attr" || arg == "-A")
|
else if (arg == "--attr" || arg == "-A")
|
||||||
attrPath = needArg(i, opFlags, arg);
|
attrPath = needArg(i, opFlags, arg);
|
||||||
else
|
else
|
||||||
throw UsageError(format("unknown flag '%1%'") % arg);
|
throw UsageError("unknown flag '%1%'", arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (printAttrPath && source != sAvailable)
|
if (printAttrPath && source != sAvailable)
|
||||||
|
@ -1177,9 +1176,9 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
static void opSwitchProfile(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());
|
throw UsageError("unknown flag '%1%'", opFlags.front());
|
||||||
if (opArgs.size() != 1)
|
if (opArgs.size() != 1)
|
||||||
throw UsageError(format("exactly one argument expected"));
|
throw UsageError("exactly one argument expected");
|
||||||
|
|
||||||
Path profile = absPath(opArgs.front());
|
Path profile = absPath(opArgs.front());
|
||||||
Path profileLink = getHome() + "/.nix-profile";
|
Path profileLink = getHome() + "/.nix-profile";
|
||||||
|
@ -1207,10 +1206,10 @@ static void switchGeneration(Globals & globals, int dstGen)
|
||||||
|
|
||||||
if (!dst) {
|
if (!dst) {
|
||||||
if (dstGen == prevGen)
|
if (dstGen == prevGen)
|
||||||
throw Error(format("no generation older than the current (%1%) exists")
|
throw Error("no generation older than the current (%1%) exists",
|
||||||
% curGen);
|
curGen);
|
||||||
else
|
else
|
||||||
throw Error(format("generation %1% does not exist") % dstGen);
|
throw Error("generation %1% does not exist", dstGen);
|
||||||
}
|
}
|
||||||
|
|
||||||
printInfo(format("switching from generation %1% to %2%")
|
printInfo(format("switching from generation %1% to %2%")
|
||||||
|
@ -1225,13 +1224,13 @@ static void switchGeneration(Globals & globals, int dstGen)
|
||||||
static void opSwitchGeneration(Globals & globals, Strings opFlags, Strings opArgs)
|
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());
|
throw UsageError("unknown flag '%1%'", opFlags.front());
|
||||||
if (opArgs.size() != 1)
|
if (opArgs.size() != 1)
|
||||||
throw UsageError(format("exactly one argument expected"));
|
throw UsageError("exactly one argument expected");
|
||||||
|
|
||||||
int dstGen;
|
int dstGen;
|
||||||
if (!string2Int(opArgs.front(), dstGen))
|
if (!string2Int(opArgs.front(), dstGen))
|
||||||
throw UsageError(format("expected a generation number"));
|
throw UsageError("expected a generation number");
|
||||||
|
|
||||||
switchGeneration(globals, dstGen);
|
switchGeneration(globals, dstGen);
|
||||||
}
|
}
|
||||||
|
@ -1240,9 +1239,9 @@ static void opSwitchGeneration(Globals & globals, Strings opFlags, Strings opArg
|
||||||
static void opRollback(Globals & globals, Strings opFlags, Strings opArgs)
|
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());
|
throw UsageError("unknown flag '%1%'", opFlags.front());
|
||||||
if (opArgs.size() != 0)
|
if (opArgs.size() != 0)
|
||||||
throw UsageError(format("no arguments expected"));
|
throw UsageError("no arguments expected");
|
||||||
|
|
||||||
switchGeneration(globals, prevGen);
|
switchGeneration(globals, prevGen);
|
||||||
}
|
}
|
||||||
|
@ -1251,9 +1250,9 @@ static void opRollback(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
static void opListGenerations(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());
|
throw UsageError("unknown flag '%1%'", opFlags.front());
|
||||||
if (opArgs.size() != 0)
|
if (opArgs.size() != 0)
|
||||||
throw UsageError(format("no arguments expected"));
|
throw UsageError("no arguments expected");
|
||||||
|
|
||||||
PathLocks lock;
|
PathLocks lock;
|
||||||
lockProfile(lock, globals.profile);
|
lockProfile(lock, globals.profile);
|
||||||
|
@ -1278,7 +1277,7 @@ static void opListGenerations(Globals & globals, Strings opFlags, Strings opArgs
|
||||||
static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opArgs)
|
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());
|
throw UsageError("unknown flag '%1%'", opFlags.front());
|
||||||
|
|
||||||
if (opArgs.size() == 1 && opArgs.front() == "old") {
|
if (opArgs.size() == 1 && opArgs.front() == "old") {
|
||||||
deleteOldGenerations(globals.profile, globals.dryRun);
|
deleteOldGenerations(globals.profile, globals.dryRun);
|
||||||
|
@ -1286,18 +1285,18 @@ static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opAr
|
||||||
deleteGenerationsOlderThan(globals.profile, opArgs.front(), globals.dryRun);
|
deleteGenerationsOlderThan(globals.profile, opArgs.front(), globals.dryRun);
|
||||||
} else if (opArgs.size() == 1 && opArgs.front().find('+') != string::npos) {
|
} 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());
|
throw Error("invalid number of generations ‘%1%’", opArgs.front());
|
||||||
string str_max = string(opArgs.front(), 1, opArgs.front().size());
|
string str_max = string(opArgs.front(), 1, opArgs.front().size());
|
||||||
int max;
|
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());
|
throw Error("invalid number of generations to keep ‘%1%’", opArgs.front());
|
||||||
deleteGenerationsGreaterThan(globals.profile, max, globals.dryRun);
|
deleteGenerationsGreaterThan(globals.profile, max, globals.dryRun);
|
||||||
} else {
|
} else {
|
||||||
std::set<unsigned int> gens;
|
std::set<unsigned int> gens;
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
if (!string2Int(i, n))
|
if (!string2Int(i, n))
|
||||||
throw UsageError(format("invalid generation number '%1%'") % i);
|
throw UsageError("invalid generation number '%1%'", i);
|
||||||
gens.insert(n);
|
gens.insert(n);
|
||||||
}
|
}
|
||||||
deleteGenerations(globals.profile, gens, globals.dryRun);
|
deleteGenerations(globals.profile, gens, globals.dryRun);
|
||||||
|
|
|
@ -66,7 +66,7 @@ void processExpr(EvalState & state, const Strings & attrPaths,
|
||||||
/* What output do we want? */
|
/* What output do we want? */
|
||||||
string outputName = i.queryOutputName();
|
string outputName = i.queryOutputName();
|
||||||
if (outputName == "")
|
if (outputName == "")
|
||||||
throw Error(format("derivation '%1%' lacks an 'outputName' attribute ") % drvPath);
|
throw Error("derivation '%1%' lacks an 'outputName' attribute ", drvPath);
|
||||||
|
|
||||||
if (gcRoot == "")
|
if (gcRoot == "")
|
||||||
printGCWarning();
|
printGCWarning();
|
||||||
|
@ -166,7 +166,7 @@ static int _main(int argc, char * * argv)
|
||||||
if (findFile) {
|
if (findFile) {
|
||||||
for (auto & i : files) {
|
for (auto & i : files) {
|
||||||
Path p = state->findFile(i);
|
Path p = state->findFile(i);
|
||||||
if (p == "") throw Error(format("unable to find '%1%'") % i);
|
if (p == "") throw Error("unable to find '%1%'", i);
|
||||||
std::cout << p << std::endl;
|
std::cout << p << std::endl;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -37,11 +37,11 @@ string resolveMirrorUri(EvalState & state, string uri)
|
||||||
|
|
||||||
auto mirrorList = vMirrors.attrs->find(state.symbols.create(mirrorName));
|
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);
|
throw Error("unknown mirror name '%1%'", mirrorName);
|
||||||
state.forceList(*mirrorList->value);
|
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);
|
throw Error("mirror URI '%1%' did not expand to anything", uri);
|
||||||
|
|
||||||
string mirror = state.forceString(*mirrorList->value->listElems()[0]);
|
string mirror = state.forceString(*mirrorList->value->listElems()[0]);
|
||||||
return mirror + (hasSuffix(mirror, "/") ? "" : "/") + string(s, p + 1);
|
return mirror + (hasSuffix(mirror, "/") ? "" : "/") + string(s, p + 1);
|
||||||
|
@ -73,7 +73,7 @@ static int _main(int argc, char * * argv)
|
||||||
string s = getArg(*arg, arg, end);
|
string s = getArg(*arg, arg, end);
|
||||||
ht = parseHashType(s);
|
ht = parseHashType(s);
|
||||||
if (ht == htUnknown)
|
if (ht == htUnknown)
|
||||||
throw UsageError(format("unknown hash type '%1%'") % s);
|
throw UsageError("unknown hash type '%1%'", s);
|
||||||
}
|
}
|
||||||
else if (*arg == "--print-path")
|
else if (*arg == "--print-path")
|
||||||
printPath = true;
|
printPath = true;
|
||||||
|
@ -151,7 +151,7 @@ static int _main(int argc, char * * argv)
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
name = baseNameOf(uri);
|
name = baseNameOf(uri);
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
throw Error(format("cannot figure out file name for '%1%'") % uri);
|
throw Error("cannot figure out file name for '%1%'", uri);
|
||||||
|
|
||||||
/* If an expected hash is given, the file may already exist in
|
/* If an expected hash is given, the file may already exist in
|
||||||
the store. */
|
the store. */
|
||||||
|
@ -206,7 +206,7 @@ static int _main(int argc, char * * argv)
|
||||||
hash = unpack ? hashPath(ht, tmpFile).first : hashFile(ht, tmpFile);
|
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);
|
throw Error("hash mismatch for '%1%'", uri);
|
||||||
|
|
||||||
/* Copy the file to the Nix store. FIXME: if RemoteStore
|
/* Copy the file to the Nix store. FIXME: if RemoteStore
|
||||||
implemented addToStoreFromDump() and downloadFile()
|
implemented addToStoreFromDump() and downloadFile()
|
||||||
|
|
|
@ -124,7 +124,7 @@ static void opRealise(Strings opFlags, Strings opArgs)
|
||||||
else if (i == "--repair") buildMode = bmRepair;
|
else if (i == "--repair") buildMode = bmRepair;
|
||||||
else if (i == "--check") buildMode = bmCheck;
|
else if (i == "--check") buildMode = bmCheck;
|
||||||
else if (i == "--ignore-unknown") ignoreUnknown = true;
|
else if (i == "--ignore-unknown") ignoreUnknown = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError("unknown flag '%1%'", i);
|
||||||
|
|
||||||
std::vector<StorePathWithOutputs> paths;
|
std::vector<StorePathWithOutputs> paths;
|
||||||
for (auto & i : opArgs)
|
for (auto & i : opArgs)
|
||||||
|
@ -178,7 +178,7 @@ static void opAddFixed(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--recursive") recursive = true;
|
if (i == "--recursive") recursive = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError("unknown flag '%1%'", i);
|
||||||
|
|
||||||
if (opArgs.empty())
|
if (opArgs.empty())
|
||||||
throw UsageError("first argument must be hash algorithm");
|
throw UsageError("first argument must be hash algorithm");
|
||||||
|
@ -198,10 +198,10 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
for (auto i : opFlags)
|
for (auto i : opFlags)
|
||||||
if (i == "--recursive") recursive = true;
|
if (i == "--recursive") recursive = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError("unknown flag '%1%'", i);
|
||||||
|
|
||||||
if (opArgs.size() != 3)
|
if (opArgs.size() != 3)
|
||||||
throw UsageError(format("'--print-fixed-path' requires three arguments"));
|
throw UsageError("'--print-fixed-path' requires three arguments");
|
||||||
|
|
||||||
Strings::iterator i = opArgs.begin();
|
Strings::iterator i = opArgs.begin();
|
||||||
HashType hashAlgo = parseHashType(*i++);
|
HashType hashAlgo = parseHashType(*i++);
|
||||||
|
@ -296,9 +296,9 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
else if (i == "--use-output" || i == "-u") useOutput = true;
|
else if (i == "--use-output" || i == "-u") useOutput = true;
|
||||||
else if (i == "--force-realise" || i == "--force-realize" || i == "-f") forceRealise = true;
|
else if (i == "--force-realise" || i == "--force-realize" || i == "-f") forceRealise = true;
|
||||||
else if (i == "--include-outputs") includeOutputs = true;
|
else if (i == "--include-outputs") includeOutputs = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError("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);
|
throw UsageError("query type '%1%' conflicts with earlier flag", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query == qDefault) query = qOutputs;
|
if (query == qDefault) query = qOutputs;
|
||||||
|
@ -444,7 +444,7 @@ static void opPrintEnv(Strings opFlags, Strings opArgs)
|
||||||
Derivation drv = store->derivationFromPath(store->parseStorePath(drvPath));
|
Derivation drv = store->derivationFromPath(store->parseStorePath(drvPath));
|
||||||
|
|
||||||
/* Print each environment variable in the derivation in a format
|
/* Print each environment variable in the derivation in a format
|
||||||
that can be sourced by the shell. */
|
* 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);
|
cout << format("export %1%; %1%=%2%\n") % i.first % shellEscape(i.second);
|
||||||
|
|
||||||
|
@ -531,7 +531,7 @@ static void opRegisterValidity(Strings opFlags, Strings opArgs)
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--reregister") reregister = true;
|
if (i == "--reregister") reregister = true;
|
||||||
else if (i == "--hash-given") hashGiven = true;
|
else if (i == "--hash-given") hashGiven = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError("unknown flag '%1%'", i);
|
||||||
|
|
||||||
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
||||||
|
|
||||||
|
@ -545,7 +545,7 @@ static void opCheckValidity(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--print-invalid") printInvalid = true;
|
if (i == "--print-invalid") printInvalid = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError("unknown flag '%1%'", i);
|
||||||
|
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
auto path = store->followLinksToStorePath(i);
|
auto path = store->followLinksToStorePath(i);
|
||||||
|
@ -576,7 +576,7 @@ static void opGC(Strings opFlags, Strings opArgs)
|
||||||
long long maxFreed = getIntArg<long long>(*i, i, opFlags.end(), true);
|
long long maxFreed = getIntArg<long long>(*i, i, opFlags.end(), true);
|
||||||
options.maxFreed = maxFreed >= 0 ? maxFreed : 0;
|
options.maxFreed = maxFreed >= 0 ? maxFreed : 0;
|
||||||
}
|
}
|
||||||
else throw UsageError(format("bad sub-operation '%1%' in GC") % *i);
|
else throw UsageError("bad sub-operation '%1%' in GC", *i);
|
||||||
|
|
||||||
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
||||||
|
|
||||||
|
@ -612,7 +612,7 @@ static void opDelete(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--ignore-liveness") options.ignoreLiveness = true;
|
if (i == "--ignore-liveness") options.ignoreLiveness = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError("unknown flag '%1%'", i);
|
||||||
|
|
||||||
for (auto & i : opArgs)
|
for (auto & i : opArgs)
|
||||||
options.pathsToDelete.insert(store->followLinksToStorePath(i));
|
options.pathsToDelete.insert(store->followLinksToStorePath(i));
|
||||||
|
@ -650,7 +650,7 @@ static void opRestore(Strings opFlags, Strings opArgs)
|
||||||
static void opExport(Strings opFlags, Strings opArgs)
|
static void opExport(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
throw UsageError(format("unknown flag '%1%'") % i);
|
throw UsageError("unknown flag '%1%'", i);
|
||||||
|
|
||||||
StorePathSet paths;
|
StorePathSet paths;
|
||||||
|
|
||||||
|
@ -666,7 +666,7 @@ static void opExport(Strings opFlags, Strings opArgs)
|
||||||
static void opImport(Strings opFlags, Strings opArgs)
|
static void opImport(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
throw UsageError(format("unknown flag '%1%'") % i);
|
throw UsageError("unknown flag '%1%'", i);
|
||||||
|
|
||||||
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
||||||
|
|
||||||
|
@ -701,7 +701,7 @@ static void opVerify(Strings opFlags, Strings opArgs)
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--check-contents") checkContents = true;
|
if (i == "--check-contents") checkContents = true;
|
||||||
else if (i == "--repair") repair = Repair;
|
else if (i == "--repair") repair = Repair;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError("unknown flag '%1%'", i);
|
||||||
|
|
||||||
if (store->verifyStore(checkContents, repair)) {
|
if (store->verifyStore(checkContents, repair)) {
|
||||||
printError("warning: not all errors were fixed");
|
printError("warning: not all errors were fixed");
|
||||||
|
@ -764,7 +764,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
bool writeAllowed = false;
|
bool writeAllowed = false;
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--write") writeAllowed = true;
|
if (i == "--write") writeAllowed = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError("unknown flag '%1%'", i);
|
||||||
|
|
||||||
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
||||||
|
|
||||||
|
@ -835,7 +835,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
for (auto & p : willSubstitute) subs.emplace_back(p.clone());
|
for (auto & p : willSubstitute) subs.emplace_back(p.clone());
|
||||||
store->buildPaths(subs);
|
store->buildPaths(subs);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
printError(format("warning: %1%") % e.msg());
|
printError("warning: %1%", e.msg());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,7 +906,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
if (!writeAllowed) throw Error("building paths is not allowed");
|
if (!writeAllowed) throw Error("building paths is not allowed");
|
||||||
|
|
||||||
auto drvPath = store->parseStorePath(readString(in)); // informational only
|
auto drvPath = store->parseStorePath(readString(in)); // inonal ony
|
||||||
BasicDerivation drv;
|
BasicDerivation drv;
|
||||||
readDerivation(in, *store, drv);
|
readDerivation(in, *store, drv);
|
||||||
|
|
||||||
|
@ -962,7 +962,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw Error(format("unknown serve command %1%") % cmd);
|
throw Error("unknown serve command %1%", cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.flush();
|
out.flush();
|
||||||
|
@ -973,7 +973,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs)
|
static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
throw UsageError(format("unknown flag '%1%'") % i);
|
throw UsageError("unknown flag '%1%'", i);
|
||||||
|
|
||||||
if (opArgs.size() != 3) throw UsageError("three arguments expected");
|
if (opArgs.size() != 3) throw UsageError("three arguments expected");
|
||||||
auto i = opArgs.begin();
|
auto i = opArgs.begin();
|
||||||
|
|
|
@ -13,9 +13,9 @@ struct MixCat : virtual Args
|
||||||
{
|
{
|
||||||
auto st = accessor->stat(path);
|
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);
|
throw Error("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);
|
throw Error("path '%1%' is not a regular file", path);
|
||||||
|
|
||||||
std::cout << accessor->readFile(path);
|
std::cout << accessor->readFile(path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ static int compatNixHash(int argc, char * * argv)
|
||||||
string s = getArg(*arg, arg, end);
|
string s = getArg(*arg, arg, end);
|
||||||
ht = parseHashType(s);
|
ht = parseHashType(s);
|
||||||
if (ht == htUnknown)
|
if (ht == htUnknown)
|
||||||
throw UsageError(format("unknown hash type '%1%'") % s);
|
throw UsageError("unknown hash type '%1%'", s);
|
||||||
}
|
}
|
||||||
else if (*arg == "--to-base16") op = opTo16;
|
else if (*arg == "--to-base16") op = opTo16;
|
||||||
else if (*arg == "--to-base32") op = opTo32;
|
else if (*arg == "--to-base32") op = opTo32;
|
||||||
|
|
|
@ -65,7 +65,7 @@ struct MixLs : virtual Args, MixJSON
|
||||||
|
|
||||||
auto st = accessor->stat(path);
|
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);
|
throw Error("path '%1%' does not exist", path);
|
||||||
doPath(st, path,
|
doPath(st, path,
|
||||||
st.type == FSAccessor::Type::tDirectory ? "." : std::string(baseNameOf(path)),
|
st.type == FSAccessor::Type::tDirectory ? "." : std::string(baseNameOf(path)),
|
||||||
showDirectory);
|
showDirectory);
|
||||||
|
|
|
@ -252,12 +252,12 @@ void NixRepl::mainLoop(const std::vector<std::string> & files)
|
||||||
// input without clearing the input so far.
|
// input without clearing the input so far.
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
printMsg(lvlError, format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg());
|
printMsg(lvlError, error + "%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg());
|
||||||
}
|
}
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
printMsg(lvlError, format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg());
|
printMsg(lvlError, error + "%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg());
|
||||||
} catch (Interrupted & e) {
|
} catch (Interrupted & e) {
|
||||||
printMsg(lvlError, format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg());
|
printMsg(lvlError, error + "%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg());
|
||||||
}
|
}
|
||||||
|
|
||||||
// We handled the current input fully, so we should clear it
|
// We handled the current input fully, so we should clear it
|
||||||
|
@ -546,7 +546,7 @@ bool NixRepl::processLine(string line)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
else if (command != "")
|
else if (command != "")
|
||||||
throw Error(format("unknown command '%1%'") % command);
|
throw Error("unknown command '%1%'", command);
|
||||||
|
|
||||||
else {
|
else {
|
||||||
size_t p = line.find('=');
|
size_t p = line.find('=');
|
||||||
|
|
|
@ -197,10 +197,10 @@ void chrootHelper(int argc, char * * argv)
|
||||||
Finally freeCwd([&]() { free(cwd); });
|
Finally freeCwd([&]() { free(cwd); });
|
||||||
|
|
||||||
if (chroot(tmpDir.c_str()) == -1)
|
if (chroot(tmpDir.c_str()) == -1)
|
||||||
throw SysError(format("chrooting into '%s'") % tmpDir);
|
throw SysError("chrooting into '%s'", tmpDir);
|
||||||
|
|
||||||
if (chdir(cwd) == -1)
|
if (chdir(cwd) == -1)
|
||||||
throw SysError(format("chdir to '%s' in chroot") % cwd);
|
throw SysError("chdir to '%s' in chroot", cwd);
|
||||||
} else
|
} else
|
||||||
if (mount(realStoreDir.c_str(), storeDir.c_str(), "", MS_BIND, 0) == -1)
|
if (mount(realStoreDir.c_str(), storeDir.c_str(), "", MS_BIND, 0) == -1)
|
||||||
throw SysError("mounting '%s' on '%s'", realStoreDir, storeDir);
|
throw SysError("mounting '%s' on '%s'", realStoreDir, storeDir);
|
||||||
|
|
Loading…
Reference in a new issue