diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh index 5f70a6c81..3116ca742 100644 --- a/src/libutil/serialise.hh +++ b/src/libutil/serialise.hh @@ -377,7 +377,8 @@ std::unique_ptr sinkToSource( struct SerializingTransform; using WireFormatGenerator = Generator, SerializingTransform>; -inline void drainGenerator(WireFormatGenerator g, std::derived_from auto & into) +template +void drainGenerator(Generator, T> g, std::derived_from auto & into) { while (g) { auto bit = g(); @@ -459,7 +460,8 @@ struct SerializingTransform WireFormatGenerator operator()(const Error & s); }; -inline Sink & operator<<(Sink & sink, WireFormatGenerator && g) +template +inline Sink & operator<<(Sink & sink, Generator, Transform> && g) { while (g) { auto bit = g(); diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 9b65bd77f..b46716511 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -371,7 +371,7 @@ void readFile(const Path & path, Sink & sink) AutoCloseFD fd{open(path.c_str(), O_RDONLY | O_CLOEXEC)}; if (!fd) throw SysError("opening file '%s'", path); - drainFD(fd.get(), sink); + drainGenerator(drainFDSource(fd.get()), sink); } @@ -722,12 +722,12 @@ std::string drainFD(int fd, bool block, const size_t reserveSize) // the parser needs two extra bytes to append terminating characters, other users will // not care very much about the extra memory. StringSink sink(reserveSize + 2); - drainFD(fd, sink, block); + sink << drainFDSource(fd, block); return std::move(sink.s); } -void drainFD(int fd, Sink & sink, bool block) +Generator> drainFDSource(int fd, bool block) { // silence GCC maybe-uninitialized warning in finally int saved = 0; @@ -756,7 +756,7 @@ void drainFD(int fd, Sink & sink, bool block) throw SysError("reading from file"); } else if (rd == 0) break; - else sink({(char *) buf.data(), (size_t) rd}); + else co_yield std::span{(char *) buf.data(), (size_t) rd}; } } @@ -1281,7 +1281,7 @@ void runProgram2(const RunOptions & options) } if (options.standardOut) - drainFD(out.readSide.get(), *options.standardOut); + *options.standardOut << drainFDSource(out.readSide.get()); /* Wait for the child to finish. */ int status = pid.wait(); diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 0216fc019..a7db52421 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -1,6 +1,7 @@ #pragma once ///@file +#include "generator.hh" #include "types.hh" #include "error.hh" #include "logging.hh" @@ -296,7 +297,7 @@ MakeError(EndOfFile, Error); */ std::string drainFD(int fd, bool block = true, const size_t reserveSize=0); -void drainFD(int fd, Sink & sink, bool block = true); +Generator> drainFDSource(int fd, bool block = true); /** * If cgroups are active, attempt to calculate the number of CPUs available.