Let ProcessReturnCode be publicly constructible v2017.09.25.00
authorYedidya Feldblum <yfeldblum@fb.com>
Sun, 24 Sep 2017 06:12:57 +0000 (23:12 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Sun, 24 Sep 2017 06:19:41 +0000 (23:19 -0700)
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

folly/Subprocess.cpp
folly/Subprocess.h

index 9a0b37eb490ff25f9f7eec44c5137007956f7e38..bd59336e00d986c7c4f603f039b5480d56a72852 100644 (file)
@@ -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<std::string>("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<std::string>(
-      "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_;
 }
index 042a1b9b91f08262c2a88ac6f6aa394f18c04f8e..21e7a8823829b2d0b130ae5544f5a58d20cac94b 100644 (file)
@@ -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<ChildPipe> 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