| 597 | } |
| 598 | |
| 599 | Status Subprocess::Kill(int signal) { |
| 600 | if (state_ != kRunning) { |
| 601 | const string err_str = "Sub-process is not running"; |
| 602 | LOG(DFATAL) << err_str; |
| 603 | return Status::IllegalState(err_str); |
| 604 | } |
| 605 | int ret = kill(child_pid_, signal); |
| 606 | if (ret != 0 && ret != ESRCH) { |
| 607 | return Status::RuntimeError("Unable to kill", |
| 608 | ErrnoToString(errno), |
| 609 | errno); |
| 610 | } |
| 611 | if (ret == ESRCH) { |
| 612 | LOG(WARNING) << Substitute("Process $0 ($1) has already exited", program_, child_pid_.load()); |
| 613 | } |
| 614 | |
| 615 | // Signal delivery is often asynchronous. For some signals, we try to wait |
| 616 | // for the process to actually change state, using /proc/<pid>/stat as a |
| 617 | // guide. This is best-effort. |
| 618 | ProcfsState desired_state; |
| 619 | switch (signal) { |
| 620 | case SIGSTOP: |
| 621 | desired_state = ProcfsState::PAUSED; |
| 622 | break; |
| 623 | case SIGCONT: |
| 624 | desired_state = ProcfsState::RUNNING; |
| 625 | break; |
| 626 | default: |
| 627 | return Status::OK(); |
| 628 | } |
| 629 | Stopwatch sw; |
| 630 | sw.start(); |
| 631 | do { |
| 632 | ProcfsState current_state; |
| 633 | if (!GetProcfsState(child_pid_, ¤t_state).ok()) { |
| 634 | // There was some error parsing /proc/<pid>/stat (or perhaps it doesn't |
| 635 | // exist on this platform). |
| 636 | return Status::OK(); |
| 637 | } |
| 638 | if (current_state == desired_state) { |
| 639 | return Status::OK(); |
| 640 | } |
| 641 | SleepFor(MonoDelta::FromMilliseconds(10)); |
| 642 | } while (sw.elapsed().wall_seconds() < kProcessWaitTimeoutSeconds); |
| 643 | return Status::OK(); |
| 644 | } |
| 645 | |
| 646 | Status Subprocess::KillAndWait(int signal) { |
| 647 | if (state_ != kRunning) { |