Index: chrome/browser/zygote_host_linux.cc |
diff --git a/chrome/browser/zygote_host_linux.cc b/chrome/browser/zygote_host_linux.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f56e6e93bcbd8d068cd8b334b4a24390f4cca145 |
--- /dev/null |
+++ b/chrome/browser/zygote_host_linux.cc |
@@ -0,0 +1,90 @@ |
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/zygote_host_linux.h" |
+ |
+#include <unistd.h> |
+#include <sys/types.h> |
+#include <sys/socket.h> |
+ |
+#include "base/command_line.h" |
+#include "base/eintr_wrapper.h" |
+#include "base/logging.h" |
+#include "base/path_service.h" |
+#include "base/pickle.h" |
+#include "base/process_util.h" |
+#include "base/unix_domain_socket_posix.h" |
+ |
+#include "chrome/common/chrome_switches.h" |
+ |
+ZygoteHost::ZygoteHost() { |
+ std::wstring chrome_path; |
+ CHECK(PathService::Get(base::FILE_EXE, &chrome_path)); |
+ CommandLine cmd_line(chrome_path); |
+ |
+ cmd_line.AppendSwitchWithValue(switches::kProcessType, |
+ switches::kZygoteProcess); |
+ |
+ int fds[2]; |
+ CHECK(socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fds) == 0); |
+ base::file_handle_mapping_vector fds_to_map; |
+ fds_to_map.push_back(std::make_pair(fds[1], 3)); |
+ |
+ const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
+ if (browser_command_line.HasSwitch(switches::kZygoteCmdPrefix)) { |
+ const std::wstring prefix = |
+ browser_command_line.GetSwitchValue(switches::kZygoteCmdPrefix); |
+ cmd_line.PrependWrapper(prefix); |
+ } |
+ |
+ base::ProcessHandle process; |
+ base::LaunchApp(cmd_line.argv(), fds_to_map, false, &process); |
+ CHECK(process != -1) << "Failed to launch zygote process"; |
+ |
+ close(fds[1]); |
+ control_fd_ = fds[0]; |
+} |
+ |
+ZygoteHost::~ZygoteHost() { |
+ close(control_fd_); |
+} |
+ |
+pid_t ZygoteHost::ForkRenderer( |
+ const std::vector<std::string>& argv, |
+ const base::GlobalDescriptors::Mapping& mapping) { |
+ Pickle pickle; |
+ |
+ pickle.WriteInt(kCmdFork); |
+ pickle.WriteInt(argv.size()); |
+ for (std::vector<std::string>::const_iterator |
+ i = argv.begin(); i != argv.end(); ++i) |
+ pickle.WriteString(*i); |
+ |
+ pickle.WriteInt(mapping.size()); |
+ |
+ std::vector<int> fds; |
+ for (base::GlobalDescriptors::Mapping::const_iterator |
+ i = mapping.begin(); i != mapping.end(); ++i) { |
+ pickle.WriteUInt32(i->first); |
+ fds.push_back(i->second); |
+ } |
+ |
+ if (!base::SendMsg(control_fd_, pickle.data(), pickle.size(), fds)) |
+ return -1; |
+ |
+ pid_t pid; |
+ if (HANDLE_EINTR(read(control_fd_, &pid, sizeof(pid))) != sizeof(pid)) |
+ return -1; |
+ |
+ return pid; |
+} |
+ |
+void ZygoteHost::EnsureProcessTerminated(pid_t process) { |
+ Pickle pickle; |
+ |
+ pickle.WriteInt(kCmdReap); |
+ pickle.WriteInt(process); |
+ |
+ HANDLE_EINTR(write(control_fd_, pickle.data(), pickle.size())); |
+} |