| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 } | 48 } |
| 49 | 49 |
| 50 ProcessId GetProcId(ProcessHandle process) { | 50 ProcessId GetProcId(ProcessHandle process) { |
| 51 return process; | 51 return process; |
| 52 } | 52 } |
| 53 | 53 |
| 54 // Attempts to kill the process identified by the given process | 54 // Attempts to kill the process identified by the given process |
| 55 // entry structure. Ignores specified exit_code; posix can't force that. | 55 // entry structure. Ignores specified exit_code; posix can't force that. |
| 56 // Returns true if this is successful, false otherwise. | 56 // Returns true if this is successful, false otherwise. |
| 57 bool KillProcess(ProcessHandle process_id, int exit_code, bool wait) { | 57 bool KillProcess(ProcessHandle process_id, int exit_code, bool wait) { |
| 58 bool result = false; | 58 bool result = kill(process_id, SIGTERM) == 0; |
| 59 | 59 |
| 60 int status = kill(process_id, SIGTERM); | 60 if (result && wait) { |
| 61 if (!status && wait) { | |
| 62 int tries = 60; | 61 int tries = 60; |
| 63 // The process may not end immediately due to pending I/O | 62 // The process may not end immediately due to pending I/O |
| 64 while (tries-- > 0) { | 63 while (tries-- > 0) { |
| 65 int pid = waitpid(process_id, &status, WNOHANG); | 64 int pid = waitpid(process_id, NULL, WNOHANG); |
| 66 if (pid == process_id) { | 65 if (pid == process_id) |
| 67 result = true; | |
| 68 break; | 66 break; |
| 69 } | 67 |
| 70 sleep(1); | 68 sleep(1); |
| 71 } | 69 } |
| 70 |
| 71 result = false; |
| 72 } | 72 } |
| 73 |
| 73 if (!result) | 74 if (!result) |
| 74 DLOG(ERROR) << "Unable to terminate process."; | 75 DLOG(ERROR) << "Unable to terminate process."; |
| 76 |
| 75 return result; | 77 return result; |
| 76 } | 78 } |
| 77 | 79 |
| 78 // A class to handle auto-closing of DIR*'s. | 80 // A class to handle auto-closing of DIR*'s. |
| 79 class ScopedDIRClose { | 81 class ScopedDIRClose { |
| 80 public: | 82 public: |
| 81 inline void operator()(DIR* x) const { | 83 inline void operator()(DIR* x) const { |
| 82 if (x) { | 84 if (x) { |
| 83 closedir(x); | 85 closedir(x); |
| 84 } | 86 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 | 135 |
| 134 void EnableTerminationOnHeapCorruption() { | 136 void EnableTerminationOnHeapCorruption() { |
| 135 // On POSIX, there nothing to do AFAIK. | 137 // On POSIX, there nothing to do AFAIK. |
| 136 } | 138 } |
| 137 | 139 |
| 138 void RaiseProcessToHighPriority() { | 140 void RaiseProcessToHighPriority() { |
| 139 // On POSIX, we don't actually do anything here. We could try to nice() or | 141 // On POSIX, we don't actually do anything here. We could try to nice() or |
| 140 // setpriority() or sched_getscheduler, but these all require extra rights. | 142 // setpriority() or sched_getscheduler, but these all require extra rights. |
| 141 } | 143 } |
| 142 | 144 |
| 143 bool DidProcessCrash(ProcessHandle handle) { | 145 bool DidProcessCrash(bool* child_exited, ProcessHandle handle) { |
| 144 int status; | 146 int status; |
| 145 if (waitpid(handle, &status, WNOHANG)) { | 147 const int result = waitpid(handle, &status, WNOHANG); |
| 146 // I feel like dancing! | 148 if (result == -1) { |
| 149 LOG(ERROR) << "waitpid failed pid:" << handle << " errno:" << errno; |
| 150 if (child_exited) |
| 151 *child_exited = false; |
| 152 return false; |
| 153 } else if (result == 0) { |
| 154 // the child hasn't exited yet. |
| 155 if (child_exited) |
| 156 *child_exited = false; |
| 147 return false; | 157 return false; |
| 148 } | 158 } |
| 149 | 159 |
| 160 if (child_exited) |
| 161 *child_exited = true; |
| 162 |
| 150 if (WIFSIGNALED(status)) { | 163 if (WIFSIGNALED(status)) { |
| 151 switch(WTERMSIG(status)) { | 164 switch(WTERMSIG(status)) { |
| 152 case SIGSEGV: | 165 case SIGSEGV: |
| 153 case SIGILL: | 166 case SIGILL: |
| 154 case SIGABRT: | 167 case SIGABRT: |
| 155 case SIGFPE: | 168 case SIGFPE: |
| 156 return true; | 169 return true; |
| 157 default: | 170 default: |
| 158 return false; | 171 return false; |
| 159 } | 172 } |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 const ProcessFilter* filter) { | 449 const ProcessFilter* filter) { |
| 437 bool exited_cleanly = | 450 bool exited_cleanly = |
| 438 WaitForProcessesToExit(executable_name, wait_milliseconds, | 451 WaitForProcessesToExit(executable_name, wait_milliseconds, |
| 439 filter); | 452 filter); |
| 440 if (!exited_cleanly) | 453 if (!exited_cleanly) |
| 441 KillProcesses(executable_name, exit_code, filter); | 454 KillProcesses(executable_name, exit_code, filter); |
| 442 return exited_cleanly; | 455 return exited_cleanly; |
| 443 } | 456 } |
| 444 | 457 |
| 445 } // namespace base | 458 } // namespace base |
| OLD | NEW |