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 |