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 |