#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <folly/Subprocess.h>
#if defined(__linux__)
#include <sys/prctl.h>
#endif
#include <fcntl.h>
#include <algorithm>
#include <array>
#include <system_error>
#include <thread>
#include <boost/container/flat_set.hpp>
#include <boost/range/adaptors.hpp>
#include <folly/Conv.h>
#include <folly/Exception.h>
#include <folly/ScopeGuard.h>
#include <folly/String.h>
#include <folly/io/Cursor.h>
#include <folly/lang/Assume.h>
#include <folly/logging/xlog.h>
#include <folly/portability/Dirent.h>
#include <folly/portability/Fcntl.h>
#include <folly/portability/Sockets.h>
#include <folly/portability/Stdlib.h>
#include <folly/portability/SysSyscall.h>
#include <folly/portability/Unistd.h>
#include <folly/system/AtFork.h>
#include <folly/system/Shell.h>
constexpr int kExecFailure = …;
constexpr int kChildFailure = …;
namespace folly {
ProcessReturnCode ProcessReturnCode::make(int status) { … }
ProcessReturnCode::ProcessReturnCode(ProcessReturnCode&& p) noexcept
: … { … }
ProcessReturnCode& ProcessReturnCode::operator=(
ProcessReturnCode&& p) noexcept { … }
ProcessReturnCode::State ProcessReturnCode::state() const { … }
void ProcessReturnCode::enforce(State expected) const { … }
int ProcessReturnCode::exitStatus() const { … }
int ProcessReturnCode::killSignal() const { … }
bool ProcessReturnCode::coreDumped() const { … }
bool ProcessReturnCode::succeeded() const { … }
std::string ProcessReturnCode::str() const { … }
CalledProcessError::CalledProcessError(ProcessReturnCode rc)
: … { … }
static inline std::string toSubprocessSpawnErrorMessage(
char const* executable, int errCode, int errnoValue) { … }
SubprocessSpawnError::SubprocessSpawnError(
const char* executable, int errCode, int errnoValue)
: … { … }
namespace {
std::unique_ptr<const char*[]> cloneStrings(const std::vector<std::string>& s) { … }
void checkStatus(ProcessReturnCode returnCode) { … }
}
Subprocess::Options& Subprocess::Options::fd(int fd, int action) { … }
Subprocess::Subprocess() = default;
Subprocess::Subprocess(
const std::vector<std::string>& argv,
const Options& options,
const char* executable,
const std::vector<std::string>* env)
: … { … }
Subprocess::Subprocess(
const std::string& cmd,
const Options& options,
const std::vector<std::string>* env)
: … { … }
Subprocess Subprocess::fromExistingProcess(pid_t pid) { … }
Subprocess::~Subprocess() { … }
namespace {
struct ChildErrorInfo { … };
[[noreturn]] void childError(int errFd, int errCode, int errnoValue) { … }
}
void Subprocess::setAllNonBlocking() { … }
void Subprocess::spawn(
std::unique_ptr<const char*[]> argv,
const char* executable,
const Options& optionsIn,
const std::vector<std::string>* env) { … }
FOLLY_PUSH_WARNING
FOLLY_GCC_DISABLE_WARNING(…)
void Subprocess::spawnInternal(
std::unique_ptr<const char*[]> argv,
const char* executable,
Options& options,
const std::vector<std::string>* env,
int errFd) { … }
FOLLY_POP_WARNING
void Subprocess::closeInheritedFds(const Options::FdMap& fdActions) { … }
int Subprocess::prepareChild(
const Options& options,
const sigset_t* sigmask,
const char* childDir) const { … }
int Subprocess::runChild(
const char* executable,
char** argv,
char** env,
const Options& options) const { … }
void Subprocess::readChildErrorPipe(int pfd, const char* executable) { … }
ProcessReturnCode Subprocess::poll(struct rusage* ru) { … }
bool Subprocess::pollChecked() { … }
ProcessReturnCode Subprocess::wait() { … }
void Subprocess::waitChecked() { … }
ProcessReturnCode Subprocess::waitTimeout(TimeoutDuration timeout) { … }
void Subprocess::sendSignal(int signal) { … }
ProcessReturnCode Subprocess::waitOrTerminateOrKill(
TimeoutDuration waitTimeout, TimeoutDuration sigtermTimeout) { … }
ProcessReturnCode Subprocess::terminateOrKill(TimeoutDuration sigtermTimeout) { … }
pid_t Subprocess::pid() const { … }
namespace {
ByteRange queueFront(const IOBufQueue& queue) { … }
bool handleWrite(int fd, IOBufQueue& queue) { … }
bool handleRead(int fd, IOBufQueue& queue) { … }
bool discardRead(int fd) { … }
}
std::pair<std::string, std::string> Subprocess::communicate(StringPiece input) { … }
std::pair<IOBufQueue, IOBufQueue> Subprocess::communicateIOBuf(
IOBufQueue input) { … }
void Subprocess::communicate(
FdCallback readCallback, FdCallback writeCallback) { … }
void Subprocess::enableNotifications(int childFd, bool enabled) { … }
bool Subprocess::notificationsEnabled(int childFd) const { … }
size_t Subprocess::findByChildFd(int childFd) const { … }
void Subprocess::closeParentFd(int childFd) { … }
std::vector<Subprocess::ChildPipe> Subprocess::takeOwnershipOfPipes() { … }
namespace {
class Initializer { … };
Initializer initializer;
}
}