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 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 break; | 229 break; |
230 } | 230 } |
231 DPLOG(ERROR) << "Error waiting for process " << process_id; | 231 DPLOG(ERROR) << "Error waiting for process " << process_id; |
232 } | 232 } |
233 | 233 |
234 usleep(sleep_ms * 1000); | 234 usleep(sleep_ms * 1000); |
235 if (sleep_ms < kMaxSleepMs) | 235 if (sleep_ms < kMaxSleepMs) |
236 sleep_ms *= 2; | 236 sleep_ms *= 2; |
237 } | 237 } |
238 | 238 |
| 239 // If we're waiting and the child hasn't died by now, force it |
| 240 // with a SIGKILL. |
239 if (!exited) | 241 if (!exited) |
240 result = kill(process_id, SIGKILL) == 0; | 242 result = kill(process_id, SIGKILL) == 0; |
241 } | 243 } |
242 | 244 |
243 if (!result) | 245 if (!result) |
244 DPLOG(ERROR) << "Unable to terminate process " << process_id; | 246 DPLOG(ERROR) << "Unable to terminate process " << process_id; |
245 | 247 |
246 return result; | 248 return result; |
247 } | 249 } |
248 | 250 |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 success &= (signal(SIGSYS, handler) != SIG_ERR); | 625 success &= (signal(SIGSYS, handler) != SIG_ERR); |
624 | 626 |
625 return success; | 627 return success; |
626 } | 628 } |
627 | 629 |
628 void RaiseProcessToHighPriority() { | 630 void RaiseProcessToHighPriority() { |
629 // On POSIX, we don't actually do anything here. We could try to nice() or | 631 // On POSIX, we don't actually do anything here. We could try to nice() or |
630 // setpriority() or sched_getscheduler, but these all require extra rights. | 632 // setpriority() or sched_getscheduler, but these all require extra rights. |
631 } | 633 } |
632 | 634 |
633 bool DidProcessCrash(bool* child_exited, ProcessHandle handle) { | 635 TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) { |
634 int status; | 636 int status = 0; |
635 const pid_t result = HANDLE_EINTR(waitpid(handle, &status, WNOHANG)); | 637 const pid_t result = HANDLE_EINTR(waitpid(handle, &status, WNOHANG)); |
636 if (result == -1) { | 638 if (result == -1) { |
637 PLOG(ERROR) << "waitpid(" << handle << ")"; | 639 PLOG(ERROR) << "waitpid(" << handle << ")"; |
638 if (child_exited) | 640 if (exit_code) |
639 *child_exited = false; | 641 *exit_code = 0; |
640 return false; | 642 return TERMINATION_STATUS_NORMAL_TERMINATION; |
641 } else if (result == 0) { | 643 } else if (result == 0) { |
642 // the child hasn't exited yet. | 644 // the child hasn't exited yet. |
643 if (child_exited) | 645 if (exit_code) |
644 *child_exited = false; | 646 *exit_code = 0; |
645 return false; | 647 return TERMINATION_STATUS_STILL_RUNNING; |
646 } | 648 } |
647 | 649 |
648 if (child_exited) | 650 if (exit_code) |
649 *child_exited = true; | 651 *exit_code = status; |
650 | 652 |
651 if (WIFSIGNALED(status)) { | 653 if (WIFSIGNALED(status)) { |
652 switch (WTERMSIG(status)) { | 654 switch (WTERMSIG(status)) { |
| 655 case SIGABRT: |
| 656 case SIGBUS: |
| 657 case SIGFPE: |
| 658 case SIGILL: |
653 case SIGSEGV: | 659 case SIGSEGV: |
654 case SIGILL: | 660 return TERMINATION_STATUS_PROCESS_CRASHED; |
655 case SIGABRT: | 661 case SIGINT: |
656 case SIGFPE: | 662 case SIGKILL: |
657 return true; | 663 case SIGTERM: |
| 664 return TERMINATION_STATUS_PROCESS_WAS_KILLED; |
658 default: | 665 default: |
659 return false; | 666 break; |
660 } | 667 } |
661 } | 668 } |
662 | 669 |
663 if (WIFEXITED(status)) | 670 if (WIFEXITED(status) && WEXITSTATUS(status) != 0) |
664 return WEXITSTATUS(status) != 0; | 671 return TERMINATION_STATUS_ABNORMAL_TERMINATION; |
665 | 672 |
666 return false; | 673 return TERMINATION_STATUS_NORMAL_TERMINATION; |
667 } | 674 } |
668 | 675 |
669 bool WaitForExitCode(ProcessHandle handle, int* exit_code) { | 676 bool WaitForExitCode(ProcessHandle handle, int* exit_code) { |
670 int status; | 677 int status; |
671 if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) { | 678 if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) { |
672 NOTREACHED(); | 679 NOTREACHED(); |
673 return false; | 680 return false; |
674 } | 681 } |
675 | 682 |
676 if (WIFEXITED(status)) { | 683 if (WIFEXITED(status)) { |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 const ProcessFilter* filter) { | 898 const ProcessFilter* filter) { |
892 bool exited_cleanly = | 899 bool exited_cleanly = |
893 WaitForProcessesToExit(executable_name, wait_milliseconds, | 900 WaitForProcessesToExit(executable_name, wait_milliseconds, |
894 filter); | 901 filter); |
895 if (!exited_cleanly) | 902 if (!exited_cleanly) |
896 KillProcesses(executable_name, exit_code, filter); | 903 KillProcesses(executable_name, exit_code, filter); |
897 return exited_cleanly; | 904 return exited_cleanly; |
898 } | 905 } |
899 | 906 |
900 } // namespace base | 907 } // namespace base |
OLD | NEW |