diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-12 17:36:55 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-12 17:36:55 +0000 |
commit | cc8f146d34a3b13cd80d8b3530fd76445774b1c6 (patch) | |
tree | 65ddd346a7b468f716f0022507112ec7215a17f7 /chrome/browser/zygote_host_linux.cc | |
parent | 9ab7d838fba71523a32d1b1e50e5d9a1c20815b2 (diff) | |
download | chromium_src-cc8f146d34a3b13cd80d8b3530fd76445774b1c6.zip chromium_src-cc8f146d34a3b13cd80d8b3530fd76445774b1c6.tar.gz chromium_src-cc8f146d34a3b13cd80d8b3530fd76445774b1c6.tar.bz2 |
Linux: refactor zygote support
http://code.google.com/p/chromium/wiki/LinuxZygote
* Move Chrome specific bits out of base
* Move away from the idea of reserved file descriptors (which don't really work
with zygotes)
* Load resources before forking renderers (means that we don't need
communication between the zygote process and the renderers)
* Make sure that gdb works against the browser again
* Make sure that we have different ASLR between the renderers and the browser.
http://codereview.chromium.org/119335
(This is a reland. First landed in r18109, reverted in r18112.)
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18291 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/zygote_host_linux.cc')
-rw-r--r-- | chrome/browser/zygote_host_linux.cc | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/chrome/browser/zygote_host_linux.cc b/chrome/browser/zygote_host_linux.cc new file mode 100644 index 0000000..f56e6e93 --- /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())); +} |