Deduplicate FSSourceAccessor and FSInputAccessor

This commit is contained in:
Eelco Dolstra 2023-10-19 15:20:10 +02:00
parent 9f572eb0e3
commit 50156302c0
4 changed files with 82 additions and 74 deletions

View file

@ -3,7 +3,7 @@
namespace nix { namespace nix {
struct FSInputAccessorImpl : FSInputAccessor struct FSInputAccessorImpl : FSInputAccessor, PosixSourceAccessor
{ {
CanonPath root; CanonPath root;
std::optional<std::set<CanonPath>> allowedPaths; std::optional<std::set<CanonPath>> allowedPaths;
@ -23,28 +23,20 @@ struct FSInputAccessorImpl : FSInputAccessor
{ {
auto absPath = makeAbsPath(path); auto absPath = makeAbsPath(path);
checkAllowed(absPath); checkAllowed(absPath);
return nix::readFile(absPath.abs()); return PosixSourceAccessor::readFile(absPath);
} }
bool pathExists(const CanonPath & path) override bool pathExists(const CanonPath & path) override
{ {
auto absPath = makeAbsPath(path); auto absPath = makeAbsPath(path);
return isAllowed(absPath) && nix::pathExists(absPath.abs()); return isAllowed(absPath) && PosixSourceAccessor::pathExists(absPath);
} }
Stat lstat(const CanonPath & path) override Stat lstat(const CanonPath & path) override
{ {
auto absPath = makeAbsPath(path); auto absPath = makeAbsPath(path);
checkAllowed(absPath); checkAllowed(absPath);
auto st = nix::lstat(absPath.abs()); return PosixSourceAccessor::lstat(absPath);
return Stat {
.type =
S_ISREG(st.st_mode) ? tRegular :
S_ISDIR(st.st_mode) ? tDirectory :
S_ISLNK(st.st_mode) ? tSymlink :
tMisc,
.isExecutable = S_ISREG(st.st_mode) && st.st_mode & S_IXUSR
};
} }
DirEntries readDirectory(const CanonPath & path) override DirEntries readDirectory(const CanonPath & path) override
@ -52,16 +44,9 @@ struct FSInputAccessorImpl : FSInputAccessor
auto absPath = makeAbsPath(path); auto absPath = makeAbsPath(path);
checkAllowed(absPath); checkAllowed(absPath);
DirEntries res; DirEntries res;
for (auto & entry : nix::readDirectory(absPath.abs())) { for (auto & entry : PosixSourceAccessor::readDirectory(absPath))
std::optional<Type> type; if (isAllowed(absPath + entry.first))
switch (entry.type) { res.emplace(entry);
case DT_REG: type = Type::tRegular; break;
case DT_LNK: type = Type::tSymlink; break;
case DT_DIR: type = Type::tDirectory; break;
}
if (isAllowed(absPath + entry.name))
res.emplace(entry.name, type);
}
return res; return res;
} }
@ -69,7 +54,7 @@ struct FSInputAccessorImpl : FSInputAccessor
{ {
auto absPath = makeAbsPath(path); auto absPath = makeAbsPath(path);
checkAllowed(absPath); checkAllowed(absPath);
return nix::readLink(absPath.abs()); return PosixSourceAccessor::readLink(absPath);
} }
CanonPath makeAbsPath(const CanonPath & path) CanonPath makeAbsPath(const CanonPath & path)

View file

@ -110,59 +110,9 @@ void SourceAccessor::dumpPath(
} }
struct FSSourceAccessor : SourceAccessor
{
time_t mtime = 0; // most recent mtime seen
std::string readFile(const CanonPath & path) override
{
return nix::readFile(path.abs());
}
bool pathExists(const CanonPath & path) override
{
return nix::pathExists(path.abs());
}
Stat lstat(const CanonPath & path) override
{
auto st = nix::lstat(path.abs());
mtime = std::max(mtime, st.st_mtime);
return Stat {
.type =
S_ISREG(st.st_mode) ? tRegular :
S_ISDIR(st.st_mode) ? tDirectory :
S_ISLNK(st.st_mode) ? tSymlink :
tMisc,
.isExecutable = S_ISREG(st.st_mode) && st.st_mode & S_IXUSR
};
}
DirEntries readDirectory(const CanonPath & path) override
{
DirEntries res;
for (auto & entry : nix::readDirectory(path.abs())) {
std::optional<Type> type;
switch (entry.type) {
case DT_REG: type = Type::tRegular; break;
case DT_LNK: type = Type::tSymlink; break;
case DT_DIR: type = Type::tDirectory; break;
}
res.emplace(entry.name, type);
}
return res;
}
std::string readLink(const CanonPath & path) override
{
return nix::readLink(path.abs());
}
};
time_t dumpPathAndGetMtime(const Path & path, Sink & sink, PathFilter & filter) time_t dumpPathAndGetMtime(const Path & path, Sink & sink, PathFilter & filter)
{ {
FSSourceAccessor accessor; PosixSourceAccessor accessor;
accessor.dumpPath(CanonPath::fromCwd(path), sink, filter); accessor.dumpPath(CanonPath::fromCwd(path), sink, filter);
return accessor.mtime; return accessor.mtime;
} }

View file

@ -33,4 +33,53 @@ std::string SourceAccessor::showPath(const CanonPath & path)
return path.abs(); return path.abs();
} }
std::string PosixSourceAccessor::readFile(const CanonPath & path)
{
return nix::readFile(path.abs());
}
bool PosixSourceAccessor::pathExists(const CanonPath & path)
{
return nix::pathExists(path.abs());
}
SourceAccessor::Stat PosixSourceAccessor::lstat(const CanonPath & path)
{
auto st = nix::lstat(path.abs());
mtime = std::max(mtime, st.st_mtime);
return Stat {
.type =
S_ISREG(st.st_mode) ? tRegular :
S_ISDIR(st.st_mode) ? tDirectory :
S_ISLNK(st.st_mode) ? tSymlink :
tMisc,
.isExecutable = S_ISREG(st.st_mode) && st.st_mode & S_IXUSR
};
}
SourceAccessor::DirEntries PosixSourceAccessor::readDirectory(const CanonPath & path)
{
DirEntries res;
for (auto & entry : nix::readDirectory(path.abs())) {
std::optional<Type> type;
switch (entry.type) {
case DT_REG: type = Type::tRegular; break;
case DT_LNK: type = Type::tSymlink; break;
case DT_DIR: type = Type::tDirectory; break;
}
res.emplace(entry.name, type);
}
return res;
}
std::string PosixSourceAccessor::readLink(const CanonPath & path)
{
return nix::readLink(path.abs());
}
std::optional<CanonPath> PosixSourceAccessor::getPhysicalPath(const CanonPath & path)
{
return path;
}
} }

View file

@ -93,4 +93,28 @@ struct SourceAccessor
} }
}; };
/**
* A source accessor that uses the Unix filesystem.
*/
struct PosixSourceAccessor : SourceAccessor
{
/**
* The most recent mtime seen by lstat(). This is a hack to
* support dumpPathAndGetMtime(). Should remove this eventually.
*/
time_t mtime = 0;
std::string readFile(const CanonPath & path) override;
bool pathExists(const CanonPath & path) override;
Stat lstat(const CanonPath & path) override;
DirEntries readDirectory(const CanonPath & path) override;
std::string readLink(const CanonPath & path) override;
std::optional<CanonPath> getPhysicalPath(const CanonPath & path) override;
};
} }