#include <folly/Exception.h>
#include <folly/File.h>
#include <folly/FileUtil.h>
+#include <folly/Function.h>
#include <folly/gen/String.h>
#include <folly/io/IOBufQueue.h>
#include <folly/MapUtil.h>
Subprocess(Subprocess&&) = default;
Subprocess& operator=(Subprocess&&) = default;
+ /**
+ * Create an uninitialized subprocess.
+ *
+ * In this state it can only be destroyed, or assigned to using the move
+ * assignment operator.
+ */
+ Subprocess();
+
/**
* Create a subprocess from the given arguments. argv[0] must be listed.
* If not-null, executable must be the actual executable
* expensive implementation choice, in order to make closeParentFd()
* thread-safe.
*/
- typedef std::function<bool(int, int)> FdCallback;
+ using FdCallback = folly::Function<bool(int, int)>;
void communicate(FdCallback readCallback, FdCallback writeCallback);
/**
* descriptors. Use the readLinesCallback() helper to get template
* deduction. For example:
*
- * auto read_cb = Subprocess::readLinesCallback(
- * [](int fd, folly::StringPiece s) {
- * std::cout << fd << " said: " << s;
- * return false; // Keep reading from the child
- * }
- * );
* subprocess.communicate(
- * // ReadLinesCallback contains StreamSplitter contains IOBuf, making
- * // it noncopyable, whereas std::function must be copyable. So, we
- * // keep the callback in a local, and instead pass a reference.
- * std::ref(read_cb),
+ * Subprocess::readLinesCallback(
+ * [](int fd, folly::StringPiece s) {
+ * std::cout << fd << " said: " << s;
+ * return false; // Keep reading from the child
+ * }
+ * ),
* [](int pdf, int cfd){ return true; } // Don't write to the child
* );
*
uint64_t maxLineLength = 0, // No line length limit by default
char delimiter = '\n',
uint64_t bufSize = 1024
- ) : fdLineCb_(std::move(fdLineCb)),
+ ) : fdLineCb_(std::forward<Callback>(fdLineCb)),
maxLineLength_(maxLineLength),
delimiter_(delimiter),
bufSize_(bufSize) {}
// Helper to enable template deduction
template <class Callback>
- static ReadLinesCallback<Callback> readLinesCallback(
+ static auto readLinesCallback(
Callback&& fdLineCb,
- uint64_t maxLineLength = 0, // No line length limit by default
+ uint64_t maxLineLength = 0, // No line length limit by default
char delimiter = '\n',
- uint64_t bufSize = 1024) {
- return ReadLinesCallback<Callback>(
- std::move(fdLineCb), maxLineLength, delimiter, bufSize
- );
+ uint64_t bufSize = 1024)
+ -> ReadLinesCallback<typename std::decay<Callback>::type> {
+ return ReadLinesCallback<typename std::decay<Callback>::type>(
+ std::forward<Callback>(fdLineCb), maxLineLength, delimiter, bufSize);
}
/**
// Returns an index into pipes_. Throws std::invalid_argument if not found.
size_t findByChildFd(const int childFd) const;
-
- pid_t pid_;
- ProcessReturnCode returnCode_;
+ pid_t pid_{-1};
+ ProcessReturnCode returnCode_{RV_NOT_STARTED};
/**
* Represents a pipe between this process, and the child process (or its