Add a GetParameterBuilder function to cvd::Command
A parameter builder object allows to add any number of components to a
single parameter, event when that number is not known at build
time (this is impossible to do with AddParameter). This is especially
useful when adding a variable number of file descriptor to a command.
Bug: 131929344
Test: run locally
Change-Id: Ib17bfed73abd217182a5d3c40015c780a27389bd
diff --git a/common/libs/utils/subprocess.cpp b/common/libs/utils/subprocess.cpp
index 773a56c..18dbbeb 100644
--- a/common/libs/utils/subprocess.cpp
+++ b/common/libs/utils/subprocess.cpp
@@ -188,6 +188,17 @@
return retval;
}
+Command::ParameterBuilder::~ParameterBuilder() {
+ Build();
+}
+void Command::ParameterBuilder::Build() {
+ auto param = stream_.str();
+ stream_ = std::stringstream();
+ if (param.size()) {
+ cmd_->AddParameter(param);
+ }
+}
+
Command::~Command() {
// Close all inherited file descriptors
for(const auto& entry: inherited_fds_) {
diff --git a/common/libs/utils/subprocess.h b/common/libs/utils/subprocess.h
index a7485c2..a299798 100644
--- a/common/libs/utils/subprocess.h
+++ b/common/libs/utils/subprocess.h
@@ -85,6 +85,24 @@
BuildParameter(stream, args...);
}
public:
+ class ParameterBuilder {
+ public:
+ ParameterBuilder(Command* cmd) : cmd_(cmd) {};
+ ParameterBuilder(ParameterBuilder&& builder) = default;
+ ~ParameterBuilder();
+
+ template<typename T>
+ ParameterBuilder& operator<<(T t) {
+ cmd_->BuildParameter(&stream_, t);
+ return *this;
+ }
+
+ void Build();
+ private:
+ cvd::Command* cmd_;
+ std::stringstream stream_;
+ };
+
Command(const std::string& executable) {
command_.push_back(executable);
}
@@ -117,6 +135,10 @@
return false;
}
+ ParameterBuilder GetParameterBuilder() {
+ return ParameterBuilder(this);
+ }
+
// Redirects the standard IO of the command.
bool RedirectStdIO(Subprocess::StdIOChannel channel, cvd::SharedFD shared_fd);