mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-10 08:16:15 +02:00
Factor out nix::maybeLstat
This function is nice for more than `PosixSourceAccessor`. We can make a few things simpler with it. Note that the error logic slightly changes in some of the call sites, in that we also count `ENOTDIR` and not just `ENOENT` as not having the file, but that should be fine.
This commit is contained in:
parent
eeecbb9c36
commit
8be347afca
5 changed files with 36 additions and 37 deletions
|
@ -2053,13 +2053,13 @@ void LocalDerivationGoal::runChild()
|
||||||
i.first, i.second.source);
|
i.first, i.second.source);
|
||||||
|
|
||||||
std::string path = i.first;
|
std::string path = i.first;
|
||||||
struct stat st;
|
auto optSt = maybeLstat(path.c_str());
|
||||||
if (lstat(path.c_str(), &st)) {
|
if (!optSt) {
|
||||||
if (i.second.optional && errno == ENOENT)
|
if (i.second.optional)
|
||||||
continue;
|
continue;
|
||||||
throw SysError("getting attributes of path '%s", path);
|
throw SysError("getting attributes of required path '%s", path);
|
||||||
}
|
}
|
||||||
if (S_ISDIR(st.st_mode))
|
if (S_ISDIR(optSt->st_mode))
|
||||||
sandboxProfile += fmt("\t(subpath \"%s\")\n", path);
|
sandboxProfile += fmt("\t(subpath \"%s\")\n", path);
|
||||||
else
|
else
|
||||||
sandboxProfile += fmt("\t(literal \"%s\")\n", path);
|
sandboxProfile += fmt("\t(literal \"%s\")\n", path);
|
||||||
|
@ -2271,14 +2271,12 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat st;
|
auto optSt = maybeLstat(actualPath.c_str());
|
||||||
if (lstat(actualPath.c_str(), &st) == -1) {
|
if (!optSt)
|
||||||
if (errno == ENOENT)
|
throw BuildError(
|
||||||
throw BuildError(
|
"builder for '%s' failed to produce output path for output '%s' at '%s'",
|
||||||
"builder for '%s' failed to produce output path for output '%s' at '%s'",
|
worker.store.printStorePath(drvPath), outputName, actualPath);
|
||||||
worker.store.printStorePath(drvPath), outputName, actualPath);
|
struct stat & st = *optSt;
|
||||||
throw SysError("getting attributes of path '%s'", actualPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef __CYGWIN__
|
#ifndef __CYGWIN__
|
||||||
/* Check that the output is not group or world writable, as
|
/* Check that the output is not group or world writable, as
|
||||||
|
|
|
@ -64,9 +64,9 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
else if (S_ISDIR(srcSt.st_mode)) {
|
else if (S_ISDIR(srcSt.st_mode)) {
|
||||||
struct stat dstSt;
|
auto dstStOpt = maybeLstat(dstFile.c_str());
|
||||||
auto res = lstat(dstFile.c_str(), &dstSt);
|
if (dstStOpt) {
|
||||||
if (res == 0) {
|
auto & dstSt = *dstStOpt;
|
||||||
if (S_ISDIR(dstSt.st_mode)) {
|
if (S_ISDIR(dstSt.st_mode)) {
|
||||||
createLinks(state, srcFile, dstFile, priority);
|
createLinks(state, srcFile, dstFile, priority);
|
||||||
continue;
|
continue;
|
||||||
|
@ -82,14 +82,13 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
|
||||||
createLinks(state, srcFile, dstFile, priority);
|
createLinks(state, srcFile, dstFile, priority);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (errno != ENOENT)
|
}
|
||||||
throw SysError("getting status of '%1%'", dstFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
struct stat dstSt;
|
auto dstStOpt = maybeLstat(dstFile.c_str());
|
||||||
auto res = lstat(dstFile.c_str(), &dstSt);
|
if (dstStOpt) {
|
||||||
if (res == 0) {
|
auto & dstSt = *dstStOpt;
|
||||||
if (S_ISLNK(dstSt.st_mode)) {
|
if (S_ISLNK(dstSt.st_mode)) {
|
||||||
auto prevPriority = state.priorities[dstFile];
|
auto prevPriority = state.priorities[dstFile];
|
||||||
if (prevPriority == priority)
|
if (prevPriority == priority)
|
||||||
|
@ -104,8 +103,7 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
|
||||||
throw SysError("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)
|
}
|
||||||
throw SysError("getting status of '%1%'", dstFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createSymlink(srcFile, dstFile);
|
createSymlink(srcFile, dstFile);
|
||||||
|
|
|
@ -174,15 +174,23 @@ struct stat lstat(const Path & path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::optional<struct stat> maybeLstat(const Path & path)
|
||||||
|
{
|
||||||
|
std::optional<struct stat> st{std::in_place};
|
||||||
|
if (lstat(path.c_str(), &*st))
|
||||||
|
{
|
||||||
|
if (errno == ENOENT || errno == ENOTDIR)
|
||||||
|
st.reset();
|
||||||
|
else
|
||||||
|
throw SysError("getting status of '%s'", path);
|
||||||
|
}
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool pathExists(const Path & path)
|
bool pathExists(const Path & path)
|
||||||
{
|
{
|
||||||
int res;
|
return maybeLstat(path).has_value();
|
||||||
struct stat st;
|
|
||||||
res = lstat(path.c_str(), &st);
|
|
||||||
if (!res) return true;
|
|
||||||
if (errno != ENOENT && errno != ENOTDIR)
|
|
||||||
throw SysError("getting status of %1%", path);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pathAccessible(const Path & path)
|
bool pathAccessible(const Path & path)
|
||||||
|
|
|
@ -84,6 +84,7 @@ bool isDirOrInDir(std::string_view path, std::string_view dir);
|
||||||
*/
|
*/
|
||||||
struct stat stat(const Path & path);
|
struct stat stat(const Path & path);
|
||||||
struct stat lstat(const Path & path);
|
struct stat lstat(const Path & path);
|
||||||
|
std::optional<struct stat> maybeLstat(const Path & path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true iff the given path exists.
|
* @return true iff the given path exists.
|
||||||
|
|
|
@ -97,13 +97,7 @@ std::optional<struct stat> PosixSourceAccessor::cachedLstat(const CanonPath & pa
|
||||||
if (i != cache->end()) return i->second;
|
if (i != cache->end()) return i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<struct stat> st{std::in_place};
|
auto st = nix::maybeLstat(absPath.c_str());
|
||||||
if (::lstat(absPath.c_str(), &*st)) {
|
|
||||||
if (errno == ENOENT || errno == ENOTDIR)
|
|
||||||
st.reset();
|
|
||||||
else
|
|
||||||
throw SysError("getting status of '%s'", showPath(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cache(_cache.lock());
|
auto cache(_cache.lock());
|
||||||
if (cache->size() >= 16384) cache->clear();
|
if (cache->size() >= 16384) cache->clear();
|
||||||
|
|
Loading…
Reference in a new issue