| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <dirent.h> | 5 #include <dirent.h> |
| 6 #include <errno.h> | 6 #include <errno.h> |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <signal.h> | 8 #include <signal.h> |
| 9 #include <stdlib.h> | 9 #include <stdlib.h> |
| 10 #include <sys/resource.h> | 10 #include <sys/resource.h> |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 break; | 178 break; |
| 179 } | 179 } |
| 180 DPLOG(ERROR) << "Error waiting for process " << process_id; | 180 DPLOG(ERROR) << "Error waiting for process " << process_id; |
| 181 } | 181 } |
| 182 | 182 |
| 183 usleep(sleep_ms * 1000); | 183 usleep(sleep_ms * 1000); |
| 184 if (sleep_ms < kMaxSleepMs) | 184 if (sleep_ms < kMaxSleepMs) |
| 185 sleep_ms *= 2; | 185 sleep_ms *= 2; |
| 186 } | 186 } |
| 187 | 187 |
| 188 // If we're waiting and the child hasn't died by now, force it |
| 189 // with a SIGKILL. |
| 188 if (!exited) | 190 if (!exited) |
| 189 result = kill(process_id, SIGKILL) == 0; | 191 result = kill(process_id, SIGKILL) == 0; |
| 190 } | 192 } |
| 191 | 193 |
| 192 if (!result) | 194 if (!result) |
| 193 DPLOG(ERROR) << "Unable to terminate process " << process_id; | 195 DPLOG(ERROR) << "Unable to terminate process " << process_id; |
| 194 | 196 |
| 195 return result; | 197 return result; |
| 196 } | 198 } |
| 197 | 199 |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 void AttachToConsole() { | 578 void AttachToConsole() { |
| 577 // On POSIX, there nothing to do AFAIK. Maybe create a new console if none | 579 // On POSIX, there nothing to do AFAIK. Maybe create a new console if none |
| 578 // exist? | 580 // exist? |
| 579 } | 581 } |
| 580 | 582 |
| 581 void RaiseProcessToHighPriority() { | 583 void RaiseProcessToHighPriority() { |
| 582 // On POSIX, we don't actually do anything here. We could try to nice() or | 584 // On POSIX, we don't actually do anything here. We could try to nice() or |
| 583 // setpriority() or sched_getscheduler, but these all require extra rights. | 585 // setpriority() or sched_getscheduler, but these all require extra rights. |
| 584 } | 586 } |
| 585 | 587 |
| 586 bool DidProcessCrash(bool* child_exited, ProcessHandle handle) { | 588 TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) { |
| 587 int status; | 589 int status = 0; |
| 588 const pid_t result = HANDLE_EINTR(waitpid(handle, &status, WNOHANG)); | 590 const pid_t result = HANDLE_EINTR(waitpid(handle, &status, WNOHANG)); |
| 589 if (result == -1) { | 591 if (result == -1) { |
| 590 PLOG(ERROR) << "waitpid(" << handle << ")"; | 592 PLOG(ERROR) << "waitpid(" << handle << ")"; |
| 591 if (child_exited) | 593 if (exit_code) |
| 592 *child_exited = false; | 594 *exit_code = 0; |
| 593 return false; | 595 return TERMINATION_STATUS_NORMAL_TERMINATION; |
| 594 } else if (result == 0) { | 596 } else if (result == 0) { |
| 595 // the child hasn't exited yet. | 597 // the child hasn't exited yet. |
| 596 if (child_exited) | 598 if (exit_code) |
| 597 *child_exited = false; | 599 *exit_code = 0; |
| 598 return false; | 600 return TERMINATION_STATUS_STILL_RUNNING; |
| 599 } | 601 } |
| 600 | 602 |
| 601 if (child_exited) | 603 if (exit_code) |
| 602 *child_exited = true; | 604 *exit_code = status; |
| 603 | 605 |
| 604 if (WIFSIGNALED(status)) { | 606 if (WIFSIGNALED(status)) { |
| 605 switch (WTERMSIG(status)) { | 607 switch (WTERMSIG(status)) { |
| 608 case SIGABRT: |
| 609 case SIGBUS: |
| 610 case SIGFPE: |
| 611 case SIGILL: |
| 606 case SIGSEGV: | 612 case SIGSEGV: |
| 607 case SIGILL: | 613 return TERMINATION_STATUS_PROCESS_CRASHED; |
| 608 case SIGABRT: | 614 case SIGINT: |
| 609 case SIGFPE: | 615 case SIGKILL: |
| 610 return true; | 616 case SIGTERM: |
| 617 return TERMINATION_STATUS_PROCESS_WAS_KILLED; |
| 611 default: | 618 default: |
| 612 return false; | 619 break; |
| 613 } | 620 } |
| 614 } | 621 } |
| 615 | 622 |
| 616 if (WIFEXITED(status)) | 623 if (WIFEXITED(status) && WEXITSTATUS(status) != 0) |
| 617 return WEXITSTATUS(status) != 0; | 624 return TERMINATION_STATUS_ABNORMAL_TERMINATION; |
| 618 | 625 |
| 619 return false; | 626 return TERMINATION_STATUS_NORMAL_TERMINATION; |
| 620 } | 627 } |
| 621 | 628 |
| 622 bool WaitForExitCode(ProcessHandle handle, int* exit_code) { | 629 bool WaitForExitCode(ProcessHandle handle, int* exit_code) { |
| 623 int status; | 630 int status; |
| 624 if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) { | 631 if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) { |
| 625 NOTREACHED(); | 632 NOTREACHED(); |
| 626 return false; | 633 return false; |
| 627 } | 634 } |
| 628 | 635 |
| 629 if (WIFEXITED(status)) { | 636 if (WIFEXITED(status)) { |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 844 const ProcessFilter* filter) { | 851 const ProcessFilter* filter) { |
| 845 bool exited_cleanly = | 852 bool exited_cleanly = |
| 846 WaitForProcessesToExit(executable_name, wait_milliseconds, | 853 WaitForProcessesToExit(executable_name, wait_milliseconds, |
| 847 filter); | 854 filter); |
| 848 if (!exited_cleanly) | 855 if (!exited_cleanly) |
| 849 KillProcesses(executable_name, exit_code, filter); | 856 KillProcesses(executable_name, exit_code, filter); |
| 850 return exited_cleanly; | 857 return exited_cleanly; |
| 851 } | 858 } |
| 852 | 859 |
| 853 } // namespace base | 860 } // namespace base |
| OLD | NEW |