OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/zygote/zygote_linux.h" | 5 #include "content/zygote/zygote_linux.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <string.h> | 8 #include <string.h> |
9 #include <sys/socket.h> | 9 #include <sys/socket.h> |
10 #include <sys/types.h> | 10 #include <sys/types.h> |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 } else { | 197 } else { |
198 actual_child = child; | 198 actual_child = child; |
199 } | 199 } |
200 | 200 |
201 base::EnsureProcessTerminated(actual_child); | 201 base::EnsureProcessTerminated(actual_child); |
202 } | 202 } |
203 | 203 |
204 void Zygote::HandleGetTerminationStatus(int fd, | 204 void Zygote::HandleGetTerminationStatus(int fd, |
205 const Pickle& pickle, | 205 const Pickle& pickle, |
206 PickleIterator iter) { | 206 PickleIterator iter) { |
| 207 bool known_dead; |
207 base::ProcessHandle child; | 208 base::ProcessHandle child; |
208 | 209 |
209 if (!pickle.ReadInt(&iter, &child)) { | 210 if (!pickle.ReadBool(&iter, &known_dead) || |
| 211 !pickle.ReadInt(&iter, &child)) { |
210 LOG(WARNING) << "Error parsing GetTerminationStatus request " | 212 LOG(WARNING) << "Error parsing GetTerminationStatus request " |
211 << "from browser"; | 213 << "from browser"; |
212 return; | 214 return; |
213 } | 215 } |
214 | 216 |
215 base::TerminationStatus status; | 217 base::TerminationStatus status; |
216 int exit_code; | 218 int exit_code; |
217 if (UsingSUIDSandbox()) | 219 if (UsingSUIDSandbox()) |
218 child = real_pids_to_sandbox_pids[child]; | 220 child = real_pids_to_sandbox_pids[child]; |
219 if (child) { | 221 if (child) { |
220 status = base::GetTerminationStatus(child, &exit_code); | 222 if (known_dead) { |
| 223 // If we know that the process is already dead and the kernel is cleaning |
| 224 // it up, we do want to wait until it becomes a zombie and not risk |
| 225 // returning eroneously that it is still running. However, we do not |
| 226 // want to risk a bug where we're told a process is dead when it's not. |
| 227 // By sending SIGKILL, we make sure that WaitForTerminationStatus will |
| 228 // return quickly even in this case. |
| 229 if (kill(child, SIGKILL)) { |
| 230 PLOG(ERROR) << "kill (" << child << ")"; |
| 231 } |
| 232 status = base::WaitForTerminationStatus(child, &exit_code); |
| 233 } else { |
| 234 status = base::GetTerminationStatus(child, &exit_code); |
| 235 } |
221 } else { | 236 } else { |
222 // Assume that if we can't find the child in the sandbox, then | 237 // Assume that if we can't find the child in the sandbox, then |
223 // it terminated normally. | 238 // it terminated normally. |
224 status = base::TERMINATION_STATUS_NORMAL_TERMINATION; | 239 status = base::TERMINATION_STATUS_NORMAL_TERMINATION; |
225 exit_code = RESULT_CODE_NORMAL_EXIT; | 240 exit_code = RESULT_CODE_NORMAL_EXIT; |
226 } | 241 } |
227 | 242 |
228 Pickle write_pickle; | 243 Pickle write_pickle; |
229 write_pickle.WriteInt(static_cast<int>(status)); | 244 write_pickle.WriteInt(static_cast<int>(status)); |
230 write_pickle.WriteInt(exit_code); | 245 write_pickle.WriteInt(exit_code); |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 PickleIterator iter) { | 505 PickleIterator iter) { |
491 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) != | 506 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) != |
492 sizeof(sandbox_flags_)) { | 507 sizeof(sandbox_flags_)) { |
493 PLOG(ERROR) << "write"; | 508 PLOG(ERROR) << "write"; |
494 } | 509 } |
495 | 510 |
496 return false; | 511 return false; |
497 } | 512 } |
498 | 513 |
499 } // namespace content | 514 } // namespace content |
OLD | NEW |