From: Yedidya Feldblum Date: Sun, 24 Sep 2017 06:12:57 +0000 (-0700) Subject: Let ProcessReturnCode be publicly constructible X-Git-Tag: v2017.09.25.00^0 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=4af3040b4c2192818a413bad35f7a6cc5846ed0b;p=folly.git Let ProcessReturnCode be publicly constructible Summary: [Folly] Let `ProcessReturnCode` be publicly constructible. Via provided constructor functions, which limit how it may be constructed so that it is only constructible into a valid state. Differential Revision: D5898739 fbshipit-source-id: 7490018adfc39408b4290248ef1220e8fd0238cb --- diff --git a/folly/Subprocess.cpp b/folly/Subprocess.cpp index 9a0b37eb..bd59336e 100644 --- a/folly/Subprocess.cpp +++ b/folly/Subprocess.cpp @@ -51,6 +51,14 @@ constexpr int kChildFailure = 126; namespace folly { +ProcessReturnCode ProcessReturnCode::make(int status) { + if (!WIFEXITED(status) && !WIFSIGNALED(status)) { + throw std::runtime_error( + to("Invalid ProcessReturnCode: ", status)); + } + return ProcessReturnCode(status); +} + ProcessReturnCode::ProcessReturnCode(ProcessReturnCode&& p) noexcept : rawStatus_(p.rawStatus_) { p.rawStatus_ = ProcessReturnCode::RV_NOT_STARTED; @@ -68,8 +76,7 @@ ProcessReturnCode::State ProcessReturnCode::state() const { if (rawStatus_ == RV_RUNNING) return RUNNING; if (WIFEXITED(rawStatus_)) return EXITED; if (WIFSIGNALED(rawStatus_)) return KILLED; - throw std::runtime_error(to( - "Invalid ProcessReturnCode: ", rawStatus_)); + assume_unreachable(); } void ProcessReturnCode::enforce(State expected) const { @@ -427,7 +434,7 @@ void Subprocess::spawnInternal( // child has exited and can be immediately waited for. In all other cases, // we have no way of cleaning up the child. pid_ = pid; - returnCode_ = ProcessReturnCode(RV_RUNNING); + returnCode_ = ProcessReturnCode::makeRunning(); } int Subprocess::prepareChild(const Options& options, @@ -562,7 +569,7 @@ ProcessReturnCode Subprocess::poll(struct rusage* ru) { if (found != 0) { // Though the child process had quit, this call does not close the pipes // since its descendants may still be using them. - returnCode_ = ProcessReturnCode(status); + returnCode_ = ProcessReturnCode::make(status); pid_ = -1; } return returnCode_; @@ -590,7 +597,7 @@ ProcessReturnCode Subprocess::wait() { // Though the child process had quit, this call does not close the pipes // since its descendants may still be using them. DCHECK_EQ(found, pid_); - returnCode_ = ProcessReturnCode(status); + returnCode_ = ProcessReturnCode::make(status); pid_ = -1; return returnCode_; } diff --git a/folly/Subprocess.h b/folly/Subprocess.h index 042a1b9b..21e7a882 100644 --- a/folly/Subprocess.h +++ b/folly/Subprocess.h @@ -127,7 +127,6 @@ namespace folly { */ class Subprocess; class ProcessReturnCode { - friend class Subprocess; public: enum State { // Subprocess starts in the constructor, so this state designates only @@ -135,12 +134,22 @@ class ProcessReturnCode { NOT_STARTED, RUNNING, EXITED, - KILLED + KILLED, }; + static ProcessReturnCode makeNotStarted() { + return ProcessReturnCode(RV_NOT_STARTED); + } + + static ProcessReturnCode makeRunning() { + return ProcessReturnCode(RV_RUNNING); + } + + static ProcessReturnCode make(int status); + // Default-initialized for convenience. Subprocess::returnCode() will // never produce this value. - ProcessReturnCode() : ProcessReturnCode(RV_NOT_STARTED) {} + ProcessReturnCode() : rawStatus_(RV_NOT_STARTED) {} // Trivially copyable ProcessReturnCode(const ProcessReturnCode& p) = default; @@ -813,9 +822,6 @@ class Subprocess { std::vector takeOwnershipOfPipes(); private: - static const int RV_RUNNING = ProcessReturnCode::RV_RUNNING; - static const int RV_NOT_STARTED = ProcessReturnCode::RV_NOT_STARTED; - // spawn() sets up a pipe to read errors from the child, // then calls spawnInternal() to do the bulk of the work. Once // spawnInternal() returns it reads the error pipe to see if the child @@ -851,7 +857,7 @@ class Subprocess { size_t findByChildFd(const int childFd) const; pid_t pid_{-1}; - ProcessReturnCode returnCode_{RV_NOT_STARTED}; + ProcessReturnCode returnCode_; /** * Represents a pipe between this process, and the child process (or its