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