Commit b10e3e86 authored by Alexey Spiridonov's avatar Alexey Spiridonov Committed by facebook-github-bot-4

Improve waitpid error handling

Summary: Using `checkUnixError` after `waitpid()` is confusing and useless, because the only two possible errors are `ECHILD` (some other part of the program waited for this process!?) and `EINVAL` (invalid options, which are hardcoded in both `Subprocess::wait()` and `poll()`). Neither of these are recoverable. Moreover, even if the caller catches the exception, `~Subprocess` is still booby-trapped to `abort()` since its status remains `RUNNING`.

In short, just abort.

Reviewed By: @yfeldblum

Differential Revision: D2079415
parent 7b481d96
...@@ -542,7 +542,10 @@ ProcessReturnCode Subprocess::poll() { ...@@ -542,7 +542,10 @@ ProcessReturnCode Subprocess::poll() {
DCHECK_GT(pid_, 0); DCHECK_GT(pid_, 0);
int status; int status;
pid_t found = ::waitpid(pid_, &status, WNOHANG); pid_t found = ::waitpid(pid_, &status, WNOHANG);
checkUnixError(found, "waitpid"); // The spec guarantees that EINTR does not occur with WNOHANG, so the only
// two remaining errors are ECHILD (other code reaped the child?), or
// EINVAL (cosmic rays?), both of which merit an abort:
PCHECK(found != -1) << "waitpid(" << pid_ << ", &status, WNOHANG)";
if (found != 0) { if (found != 0) {
// Though the child process had quit, this call does not close the pipes // Though the child process had quit, this call does not close the pipes
// since its descendants may still be using them. // since its descendants may still be using them.
...@@ -568,7 +571,9 @@ ProcessReturnCode Subprocess::wait() { ...@@ -568,7 +571,9 @@ ProcessReturnCode Subprocess::wait() {
do { do {
found = ::waitpid(pid_, &status, 0); found = ::waitpid(pid_, &status, 0);
} while (found == -1 && errno == EINTR); } while (found == -1 && errno == EINTR);
checkUnixError(found, "waitpid"); // The only two remaining errors are ECHILD (other code reaped the
// child?), or EINVAL (cosmic rays?), and both merit an abort:
PCHECK(found != -1) << "waitpid(" << pid_ << ", &status, WNOHANG)";
// Though the child process had quit, this call does not close the pipes // Though the child process had quit, this call does not close the pipes
// since its descendants may still be using them. // since its descendants may still be using them.
DCHECK_EQ(found, pid_); DCHECK_EQ(found, pid_);
......
...@@ -410,11 +410,12 @@ class Subprocess { ...@@ -410,11 +410,12 @@ class Subprocess {
ProcessReturnCode returnCode() const { return returnCode_; } ProcessReturnCode returnCode() const { return returnCode_; }
/** /**
* Poll the child's status and return it, return -1 if the process * Poll the child's status and return it. Return the exit status if the
* is still running. NOTE that it is illegal to call poll again after * subprocess had quit, or RUNNING otherwise. Throws an std::logic_error
* poll indicated that the process has terminated, or to call poll on a * if called on a Subprocess whose status is no longer RUNNING. No other
* process that hasn't been successfully started (the constructor threw an * exceptions are possible. Aborts on egregious violations of contract,
* exception). * e.g. if you wait for the underlying process without going through this
* Subprocess instance.
*/ */
ProcessReturnCode poll(); ProcessReturnCode poll();
...@@ -426,9 +427,10 @@ class Subprocess { ...@@ -426,9 +427,10 @@ class Subprocess {
bool pollChecked(); bool pollChecked();
/** /**
* Wait for the process to terminate and return its status. * Wait for the process to terminate and return its status. Like poll(),
* Similarly to poll, it is illegal to call wait after the process * the only exception this can throw is std::logic_error if you call this
* has already been reaped or if the process has not successfully started. * on a Subprocess whose status is RUNNING. Aborts on egregious
* violations of contract, like an out-of-band waitpid(p.pid(), 0, 0).
*/ */
ProcessReturnCode wait(); ProcessReturnCode wait();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment