SourceAccessor: Change the main interface from lstat() to maybeLstat()

This commit is contained in:
Eelco Dolstra 2023-11-01 15:26:07 +01:00
parent 8ffd1695ce
commit cdb27c1519
9 changed files with 22 additions and 20 deletions

View file

@ -1548,10 +1548,8 @@ static void prim_pathExists(EvalState & state, const PosIdx pos, Value * * args,
try { try {
auto checked = state.checkSourcePath(path); auto checked = state.checkSourcePath(path);
auto exists = checked.pathExists(); auto st = checked.maybeLstat();
if (exists && mustBeDir) { auto exists = st && (!mustBeDir || st->type == SourceAccessor::tDirectory);
exists = checked.lstat().type == InputAccessor::tDirectory;
}
v.mkBool(exists); v.mkBool(exists);
} catch (SysError & e) { } catch (SysError & e) {
/* Don't give away info from errors while canonicalising /* Don't give away info from errors while canonicalising

View file

@ -36,11 +36,11 @@ struct FSInputAccessorImpl : FSInputAccessor, PosixSourceAccessor
return isAllowed(absPath) && PosixSourceAccessor::pathExists(absPath); return isAllowed(absPath) && PosixSourceAccessor::pathExists(absPath);
} }
Stat lstat(const CanonPath & path) override std::optional<Stat> maybeLstat(const CanonPath & path) override
{ {
auto absPath = makeAbsPath(path); auto absPath = makeAbsPath(path);
checkAllowed(absPath); checkAllowed(absPath);
return PosixSourceAccessor::lstat(absPath); return PosixSourceAccessor::maybeLstat(absPath);
} }
DirEntries readDirectory(const CanonPath & path) override DirEntries readDirectory(const CanonPath & path) override

View file

@ -20,12 +20,12 @@ struct MemoryInputAccessorImpl : MemoryInputAccessor
return i != files.end(); return i != files.end();
} }
Stat lstat(const CanonPath & path) override std::optional<Stat> maybeLstat(const CanonPath & path) override
{ {
auto i = files.find(path); auto i = files.find(path);
if (i != files.end()) if (i != files.end())
return Stat { .type = tRegular, .isExecutable = false }; return Stat { .type = tRegular, .isExecutable = false };
throw Error("file '%s' does not exist", path); return std::nullopt;
} }
DirEntries readDirectory(const CanonPath & path) override DirEntries readDirectory(const CanonPath & path) override

View file

@ -44,9 +44,13 @@ bool PosixSourceAccessor::pathExists(const CanonPath & path)
return nix::pathExists(path.abs()); return nix::pathExists(path.abs());
} }
SourceAccessor::Stat PosixSourceAccessor::lstat(const CanonPath & path) std::optional<SourceAccessor::Stat> PosixSourceAccessor::maybeLstat(const CanonPath & path)
{ {
auto st = nix::lstat(path.abs()); struct stat st;
if (::lstat(path.c_str(), &st)) {
if (errno == ENOENT) return std::nullopt;
throw SysError("getting status of '%s'", showPath(path));
}
mtime = std::max(mtime, st.st_mtime); mtime = std::max(mtime, st.st_mtime);
return Stat { return Stat {
.type = .type =

View file

@ -22,7 +22,7 @@ struct PosixSourceAccessor : SourceAccessor
bool pathExists(const CanonPath & path) override; bool pathExists(const CanonPath & path) override;
Stat lstat(const CanonPath & path) override; std::optional<Stat> maybeLstat(const CanonPath & path) override;
DirEntries readDirectory(const CanonPath & path) override; DirEntries readDirectory(const CanonPath & path) override;

View file

@ -42,12 +42,12 @@ Hash SourceAccessor::hashPath(
return sink.finish().first; return sink.finish().first;
} }
std::optional<SourceAccessor::Stat> SourceAccessor::maybeLstat(const CanonPath & path) SourceAccessor::Stat SourceAccessor::lstat(const CanonPath & path)
{ {
// FIXME: merge these into one operation. if (auto st = maybeLstat(path))
if (!pathExists(path)) return *st;
return {}; else
return lstat(path); throw Error("path '%s' does not exist", showPath(path));
} }
std::string SourceAccessor::showPath(const CanonPath & path) std::string SourceAccessor::showPath(const CanonPath & path)

View file

@ -61,9 +61,9 @@ struct SourceAccessor
bool isExecutable = false; // regular files only bool isExecutable = false; // regular files only
}; };
virtual Stat lstat(const CanonPath & path) = 0; Stat lstat(const CanonPath & path);
std::optional<Stat> maybeLstat(const CanonPath & path); virtual std::optional<Stat> maybeLstat(const CanonPath & path) = 0;
typedef std::optional<Type> DirEntry; typedef std::optional<Type> DirEntry;

View file

@ -1 +1 @@
error: getting status of '/pwd/lang/fnord': No such file or directory error: path '/pwd/lang/fnord' does not exist

View file

@ -1 +1 @@
error: getting status of '/pwd/lang/fnord': No such file or directory error: path '/pwd/lang/fnord' does not exist