aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-03-23 00:47:16 +0100
committereldritch horrors <pennae@lix.systems>2024-07-05 22:28:16 +0000
commit06220a71c1430c97bfcd8012b00530a987e40e97 (patch)
tree69f230d669db2804379a33fc1ec6e3d3fc908c67 /src/libutil
parentb51ea465de48e4c5516ba0182cc642b4e644be10 (diff)
libstore: convert dumpPath to a generator
Change-Id: Ic4cf5562504aa29130304469936f958c0426e5ef
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/archive.cc78
-rw-r--r--src/libutil/archive.hh6
-rw-r--r--src/libutil/hash.cc2
-rw-r--r--src/libutil/source-path.hh2
4 files changed, 53 insertions, 35 deletions
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc
index 1b42ee4b5..2ac9f3dcd 100644
--- a/src/libutil/archive.cc
+++ b/src/libutil/archive.cc
@@ -40,10 +40,10 @@ static GlobalConfig::Register rArchiveSettings(&archiveSettings);
PathFilter defaultPathFilter = [](const Path &) { return true; };
-static void dumpContents(const Path & path, off_t size,
- Sink & sink)
+static WireFormatGenerator dumpContents(const Path & path, off_t size)
{
- sink << "contents" << size;
+ co_yield "contents";
+ co_yield size;
AutoCloseFD fd{open(path.c_str(), O_RDONLY | O_CLOEXEC)};
if (!fd) throw SysError("opening file '%1%'", path);
@@ -55,31 +55,35 @@ static void dumpContents(const Path & path, off_t size,
auto n = std::min(left, buf.size());
readFull(fd.get(), buf.data(), n);
left -= n;
- sink({buf.data(), n});
+ co_yield std::span{buf.data(), n};
}
- writePadding(size, sink);
+ co_yield SerializingTransform::padding(size);
}
-static time_t dump(const Path & path, Sink & sink, PathFilter & filter)
+static WireFormatGenerator dump(const Path & path, time_t & mtime, PathFilter & filter)
{
checkInterrupt();
auto st = lstat(path);
- time_t result = st.st_mtime;
+ mtime = st.st_mtime;
- sink << "(";
+ co_yield "(";
if (S_ISREG(st.st_mode)) {
- sink << "type" << "regular";
- if (st.st_mode & S_IXUSR)
- sink << "executable" << "";
- dumpContents(path, st.st_size, sink);
+ co_yield "type";
+ co_yield "regular";
+ if (st.st_mode & S_IXUSR) {
+ co_yield "executable";
+ co_yield "";
+ }
+ co_yield dumpContents(path, st.st_size);
}
else if (S_ISDIR(st.st_mode)) {
- sink << "type" << "directory";
+ co_yield "type";
+ co_yield "directory";
/* If we're on a case-insensitive system like macOS, undo
the case hack applied by restorePath(). */
@@ -101,41 +105,55 @@ static time_t dump(const Path & path, Sink & sink, PathFilter & filter)
for (auto & i : unhacked)
if (filter(path + "/" + i.first)) {
- sink << "entry" << "(" << "name" << i.first << "node";
- auto tmp_mtime = dump(path + "/" + i.second, sink, filter);
- if (tmp_mtime > result) {
- result = tmp_mtime;
+ co_yield "entry";
+ co_yield "(";
+ co_yield "name";
+ co_yield i.first;
+ co_yield "node";
+ time_t tmp_mtime;
+ co_yield dump(path + "/" + i.second, tmp_mtime, filter);
+ if (tmp_mtime > mtime) {
+ mtime = tmp_mtime;
}
- sink << ")";
+ co_yield ")";
}
}
- else if (S_ISLNK(st.st_mode))
- sink << "type" << "symlink" << "target" << readLink(path);
+ else if (S_ISLNK(st.st_mode)) {
+ co_yield "type";
+ co_yield "symlink";
+ co_yield "target";
+ co_yield readLink(path);
+ }
else throw Error("file '%1%' has an unsupported type", path);
- sink << ")";
-
- return result;
+ co_yield ")";
}
-time_t dumpPathAndGetMtime(const Path & path, Sink & sink, PathFilter & filter)
+WireFormatGenerator dumpPathAndGetMtime(Path path, time_t & mtime, PathFilter & filter)
{
- sink << narVersionMagic1;
- return dump(path, sink, filter);
+ co_yield narVersionMagic1;
+ co_yield dump(path, mtime, filter);
}
-void dumpPath(const Path & path, Sink & sink, PathFilter & filter)
+WireFormatGenerator dumpPath(Path path, PathFilter & filter)
{
- dumpPathAndGetMtime(path, sink, filter);
+ time_t ignored;
+ co_yield dumpPathAndGetMtime(path, ignored, filter);
}
-void dumpString(std::string_view s, Sink & sink)
+WireFormatGenerator dumpString(std::string_view s)
{
- sink << narVersionMagic1 << "(" << "type" << "regular" << "contents" << s << ")";
+ co_yield narVersionMagic1;
+ co_yield "(";
+ co_yield "type";
+ co_yield "regular";
+ co_yield "contents";
+ co_yield s;
+ co_yield ")";
}
diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh
index f163a1947..7fc9b1b73 100644
--- a/src/libutil/archive.hh
+++ b/src/libutil/archive.hh
@@ -57,13 +57,13 @@ namespace nix {
* `+` denotes string concatenation.
* ```
*/
-void dumpPath(const Path & path, Sink & sink,
+WireFormatGenerator dumpPath(Path path,
PathFilter & filter = defaultPathFilter);
/**
* Same as dumpPath(), but returns the last modified date of the path.
*/
-time_t dumpPathAndGetMtime(const Path & path, Sink & sink,
+WireFormatGenerator dumpPathAndGetMtime(Path path, time_t & mtime,
PathFilter & filter = defaultPathFilter);
/**
@@ -71,7 +71,7 @@ time_t dumpPathAndGetMtime(const Path & path, Sink & sink,
*
* @param s Contents of the file.
*/
-void dumpString(std::string_view s, Sink & sink);
+WireFormatGenerator dumpString(std::string_view s);
/**
* \todo Fix this API, it sucks.
diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc
index 822fa150e..c0ad7f5fa 100644
--- a/src/libutil/hash.cc
+++ b/src/libutil/hash.cc
@@ -370,7 +370,7 @@ HashResult hashPath(
HashType ht, const Path & path, PathFilter & filter)
{
HashSink sink(ht);
- dumpPath(path, sink, filter);
+ sink << dumpPath(path, filter);
return sink.finish();
}
diff --git a/src/libutil/source-path.hh b/src/libutil/source-path.hh
index 311e9f7a6..fe5b9b777 100644
--- a/src/libutil/source-path.hh
+++ b/src/libutil/source-path.hh
@@ -101,7 +101,7 @@ struct SourcePath
void dumpPath(
Sink & sink,
PathFilter & filter = defaultPathFilter) const
- { return nix::dumpPath(path.abs(), sink, filter); }
+ { sink << nix::dumpPath(path.abs(), filter); }
/**
* Return the location of this path in the "real" filesystem, if