Chromium Code Reviews| 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/browser/zygote_host/zygote_host_impl_linux.h" | 5 #include "content/browser/zygote_host/zygote_host_impl_linux.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 #include <sys/socket.h> | 8 #include <sys/socket.h> |
| 9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 10 #include <sys/types.h> | 10 #include <sys/types.h> |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 return HANDLE_EINTR(read(control_fd_, buf, buf_len)); | 287 return HANDLE_EINTR(read(control_fd_, buf, buf_len)); |
| 288 } | 288 } |
| 289 | 289 |
| 290 pid_t ZygoteHostImpl::ForkRequest( | 290 pid_t ZygoteHostImpl::ForkRequest( |
| 291 const std::vector<std::string>& argv, | 291 const std::vector<std::string>& argv, |
| 292 const std::vector<FileDescriptorInfo>& mapping, | 292 const std::vector<FileDescriptorInfo>& mapping, |
| 293 const std::string& process_type) { | 293 const std::string& process_type) { |
| 294 DCHECK(init_); | 294 DCHECK(init_); |
| 295 Pickle pickle; | 295 Pickle pickle; |
| 296 | 296 |
| 297 int raw_socks[2]; | |
| 298 PCHECK(0 == socketpair(AF_UNIX, SOCK_SEQPACKET, 0, raw_socks)); | |
| 299 base::ScopedFD my_sock(raw_socks[0]); | |
| 300 base::ScopedFD peer_sock(raw_socks[1]); | |
| 301 CHECK(UnixDomainSocket::EnableReceiveProcessId(my_sock.get())); | |
| 302 | |
| 297 pickle.WriteInt(kZygoteCommandFork); | 303 pickle.WriteInt(kZygoteCommandFork); |
| 298 pickle.WriteString(process_type); | 304 pickle.WriteString(process_type); |
| 299 pickle.WriteInt(argv.size()); | 305 pickle.WriteInt(argv.size()); |
| 300 for (std::vector<std::string>::const_iterator | 306 for (std::vector<std::string>::const_iterator |
| 301 i = argv.begin(); i != argv.end(); ++i) | 307 i = argv.begin(); i != argv.end(); ++i) |
| 302 pickle.WriteString(*i); | 308 pickle.WriteString(*i); |
| 303 | 309 |
| 304 pickle.WriteInt(mapping.size()); | 310 pickle.WriteInt(1 + mapping.size()); |
|
jln (very slow on Chromium)
2014/05/05 19:01:42
This should be documented. How about something suc
mdempsky
2014/05/05 21:38:18
Done. I implemented something slightly different
| |
| 305 | 311 |
| 306 std::vector<int> fds; | 312 std::vector<int> fds; |
| 307 // Scoped pointers cannot be stored in containers, so we have to use a | 313 ScopedVector<base::ScopedFD> autoclose_fds; |
| 308 // linked_ptr. | 314 |
| 309 std::vector<linked_ptr<base::ScopedFD> > autodelete_fds; | 315 // First FD to send is peer_sock. |
| 316 fds.push_back(peer_sock.get()); | |
| 317 autoclose_fds.push_back(new base::ScopedFD(peer_sock.Pass())); | |
| 318 | |
| 319 // The rest come from mapping. | |
| 310 for (std::vector<FileDescriptorInfo>::const_iterator | 320 for (std::vector<FileDescriptorInfo>::const_iterator |
| 311 i = mapping.begin(); i != mapping.end(); ++i) { | 321 i = mapping.begin(); i != mapping.end(); ++i) { |
| 312 pickle.WriteUInt32(i->id); | 322 pickle.WriteUInt32(i->id); |
| 313 fds.push_back(i->fd.fd); | 323 fds.push_back(i->fd.fd); |
| 314 if (i->fd.auto_close) { | 324 if (i->fd.auto_close) { |
| 315 // Auto-close means we need to close the FDs after they have been passed | 325 // Auto-close means we need to close the FDs after they have been passed |
| 316 // to the other process. | 326 // to the other process. |
| 317 linked_ptr<base::ScopedFD> ptr(new base::ScopedFD(fds.back())); | 327 autoclose_fds.push_back(new base::ScopedFD(i->fd.fd)); |
| 318 autodelete_fds.push_back(ptr); | |
| 319 } | 328 } |
| 320 } | 329 } |
| 321 | 330 |
| 322 pid_t pid; | 331 pid_t pid; |
| 323 { | 332 { |
| 324 base::AutoLock lock(control_lock_); | 333 base::AutoLock lock(control_lock_); |
| 325 if (!SendMessage(pickle, &fds)) | 334 if (!SendMessage(pickle, &fds)) |
| 326 return base::kNullProcessHandle; | 335 return base::kNullProcessHandle; |
| 336 autoclose_fds.clear(); | |
| 337 | |
| 338 { | |
| 339 char buf[sizeof(kZygoteChildPingMessage) + 1]; | |
| 340 ScopedVector<base::ScopedFD> recv_fds; | |
| 341 base::ProcessId real_pid; | |
| 342 | |
| 343 ssize_t n = UnixDomainSocket::RecvMsgWithPid( | |
| 344 my_sock.get(), buf, sizeof(buf), &recv_fds, &real_pid); | |
| 345 if (n != sizeof(kZygoteChildPingMessage) || | |
| 346 0 != memcmp(buf, | |
| 347 kZygoteChildPingMessage, | |
| 348 sizeof(kZygoteChildPingMessage))) { | |
| 349 LOG(ERROR) << "Did not receive ping from zygote child"; | |
| 350 real_pid = -1; | |
|
jln (very slow on Chromium)
2014/05/05 19:01:42
Add NOTREACHED()? I wouldn't be shocked by LOG(FAT
mdempsky
2014/05/05 21:38:18
Done. Went with LOG(FATAL).
| |
| 351 } | |
| 352 my_sock.reset(); | |
| 353 | |
| 354 // Always send PID back to zygote. | |
| 355 Pickle pid_pickle; | |
| 356 pid_pickle.WriteInt(kZygoteCommandForkRealPID); | |
| 357 pid_pickle.WriteInt(real_pid); | |
| 358 if (!SendMessage(pid_pickle, NULL)) | |
| 359 return base::kNullProcessHandle; | |
| 360 } | |
| 327 | 361 |
| 328 // Read the reply, which pickles the PID and an optional UMA enumeration. | 362 // Read the reply, which pickles the PID and an optional UMA enumeration. |
| 329 static const unsigned kMaxReplyLength = 2048; | 363 static const unsigned kMaxReplyLength = 2048; |
| 330 char buf[kMaxReplyLength]; | 364 char buf[kMaxReplyLength]; |
| 331 const ssize_t len = ReadReply(buf, sizeof(buf)); | 365 const ssize_t len = ReadReply(buf, sizeof(buf)); |
| 332 | 366 |
| 333 Pickle reply_pickle(buf, len); | 367 Pickle reply_pickle(buf, len); |
| 334 PickleIterator iter(reply_pickle); | 368 PickleIterator iter(reply_pickle); |
| 335 if (len <= 0 || !reply_pickle.ReadInt(&iter, &pid)) | 369 if (len <= 0 || !reply_pickle.ReadInt(&iter, &pid)) |
| 336 return base::kNullProcessHandle; | 370 return base::kNullProcessHandle; |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 520 return RenderSandboxHostLinux::GetInstance()->pid(); | 554 return RenderSandboxHostLinux::GetInstance()->pid(); |
| 521 } | 555 } |
| 522 | 556 |
| 523 int ZygoteHostImpl::GetSandboxStatus() const { | 557 int ZygoteHostImpl::GetSandboxStatus() const { |
| 524 if (have_read_sandbox_status_word_) | 558 if (have_read_sandbox_status_word_) |
| 525 return sandbox_status_; | 559 return sandbox_status_; |
| 526 return 0; | 560 return 0; |
| 527 } | 561 } |
| 528 | 562 |
| 529 } // namespace content | 563 } // namespace content |
| OLD | NEW |