1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/browser_main_posix.h"
63345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <errno.h>
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <limits.h>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <signal.h>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <sys/resource.h>
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <unistd.h>
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include <string>
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/eintr_wrapper.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/defaults.h"
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_switches.h"
22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/printing/print_dialog_gtk.h"
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// See comment in |PreEarlyInitialization()|, where sigaction is called.
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SIGCHLDHandler(int signal) {
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint g_shutdown_pipe_write_fd = -1;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint g_shutdown_pipe_read_fd = -1;
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Common code between SIG{HUP, INT, TERM}Handler.
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GracefulShutdownHandler(int signal) {
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reinstall the default handler.  We had one shot at graceful shutdown.
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct sigaction action;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  memset(&action, 0, sizeof(action));
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  action.sa_handler = SIG_DFL;
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RAW_CHECK(sigaction(signal, &action, NULL) == 0);
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RAW_CHECK(g_shutdown_pipe_write_fd != -1);
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RAW_CHECK(g_shutdown_pipe_read_fd != -1);
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t bytes_written = 0;
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  do {
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = HANDLE_EINTR(
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        write(g_shutdown_pipe_write_fd,
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              reinterpret_cast<const char*>(&signal) + bytes_written,
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              sizeof(signal) - bytes_written));
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RAW_CHECK(rv >= 0);
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bytes_written += rv;
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } while (bytes_written < sizeof(signal));
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// See comment in |PreEarlyInitialization()|, where sigaction is called.
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SIGHUPHandler(int signal) {
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RAW_CHECK(signal == SIGHUP);
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GracefulShutdownHandler(signal);
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// See comment in |PreEarlyInitialization()|, where sigaction is called.
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SIGINTHandler(int signal) {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RAW_CHECK(signal == SIGINT);
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GracefulShutdownHandler(signal);
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// See comment in |PreEarlyInitialization()|, where sigaction is called.
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SIGTERMHandler(int signal) {
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RAW_CHECK(signal == SIGTERM);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GracefulShutdownHandler(signal);
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenclass ShutdownDetector : public base::PlatformThread::Delegate {
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit ShutdownDetector(int shutdown_fd);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void ThreadMain();
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int shutdown_fd_;
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ShutdownDetector);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochShutdownDetector::ShutdownDetector(int shutdown_fd)
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : shutdown_fd_(shutdown_fd) {
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK_NE(shutdown_fd_, -1);
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// These functions are used to help us diagnose crash dumps that happen
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// during the shutdown process.
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenNOINLINE void ShutdownFDReadError() {
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Ensure function isn't optimized away.
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  asm("");
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  sleep(UINT_MAX);
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenNOINLINE void ShutdownFDClosedError() {
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Ensure function isn't optimized away.
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  asm("");
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  sleep(UINT_MAX);
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenNOINLINE void CloseAllBrowsersAndExitPosted() {
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Ensure function isn't optimized away.
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  asm("");
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  sleep(UINT_MAX);
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ShutdownDetector::ThreadMain() {
1153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  base::PlatformThread::SetName("CrShutdownDetector");
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int signal;
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t bytes_read = 0;
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ssize_t ret;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  do {
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ret = HANDLE_EINTR(
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        read(shutdown_fd_,
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch             reinterpret_cast<char*>(&signal) + bytes_read,
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch             sizeof(signal) - bytes_read));
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (ret < 0) {
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED() << "Unexpected error: " << strerror(errno);
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ShutdownFDReadError();
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (ret == 0) {
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED() << "Unexpected closure of shutdown pipe.";
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ShutdownFDClosedError();
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bytes_read += ret;
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } while (bytes_read < sizeof(signal));
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  VLOG(1) << "Handling shutdown for signal " << signal << ".";
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!BrowserThread::PostTask(
140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit))) {
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Without a UI thread to post the exit task to, there aren't many
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // options.  Raise the signal again.  The default handler will pick it up
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // and cause an ungraceful exit.
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RAW_LOG(WARNING, "No UI thread, exiting ungracefully.");
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    kill(getpid(), signal);
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The signal may be handled on another thread.  Give that a chance to
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // happen.
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sleep(3);
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We really should be dead by now.  For whatever reason, we're not. Exit
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // immediately, with the exit status set to the signal number with bit 8
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // set.  On the systems that we care about, this exit status is what is
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // normally used to indicate an exit by this signal's default handler.
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This mechanism isn't a de jure standard, but even in the worst case, it
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // should at least result in an immediate exit.
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RAW_LOG(WARNING, "Still here, exiting really ungracefully.");
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    _exit(signal | (1 << 7));
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CloseAllBrowsersAndExitPosted();
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Sets the file descriptor soft limit to |max_descriptors| or the OS hard
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// limit, whichever is lower.
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SetFileDescriptorLimit(unsigned int max_descriptors) {
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct rlimit limits;
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (getrlimit(RLIMIT_NOFILE, &limits) == 0) {
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unsigned int new_limit = max_descriptors;
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) {
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new_limit = limits.rlim_max;
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    limits.rlim_cur = new_limit;
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (setrlimit(RLIMIT_NOFILE, &limits) != 0) {
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      PLOG(INFO) << "Failed to set file descriptor limit";
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PLOG(INFO) << "Failed to get file descriptor limit";
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// BrowserMainPartsPosix -------------------------------------------------------
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BrowserMainPartsPosix::PreEarlyInitialization() {
1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // We need to accept SIGCHLD, even though our handler is a no-op because
1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // otherwise we cannot wait on children. (According to POSIX 2001.)
1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  struct sigaction action;
1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  memset(&action, 0, sizeof(action));
1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  action.sa_handler = SIGCHLDHandler;
1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(sigaction(SIGCHLD, &action, NULL) == 0);
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If adding to this list of signal handlers, note the new signal probably
1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // needs to be reset in child processes. See
1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // base/process_util_posix.cc:LaunchApp
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // We need to handle SIGTERM, because that is how many POSIX-based distros ask
1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // processes to quit gracefully at shutdown time.
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  memset(&action, 0, sizeof(action));
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  action.sa_handler = SIGTERMHandler;
2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(sigaction(SIGTERM, &action, NULL) == 0);
2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Also handle SIGINT - when the user terminates the browser via Ctrl+C. If
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // the browser process is being debugged, GDB will catch the SIGINT first.
2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  action.sa_handler = SIGINTHandler;
2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(sigaction(SIGINT, &action, NULL) == 0);
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // And SIGHUP, for when the terminal disappears. On shutdown, many Linux
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // distros send SIGHUP, SIGTERM, and then SIGKILL.
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  action.sa_handler = SIGHUPHandler;
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(sigaction(SIGHUP, &action, NULL) == 0);
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const std::string fd_limit_string =
2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      parsed_command_line().GetSwitchValueASCII(
2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          switches::kFileDescriptorLimit);
2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int fd_limit = 0;
2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!fd_limit_string.empty()) {
2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    base::StringToInt(fd_limit_string, &fd_limit);
2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX)
2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // We use quite a few file descriptors for our IPC, and the default limit on
2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // the Mac is low (256), so bump it up if there is no explicit override.
2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (fd_limit == 0) {
2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    fd_limit = 1024;
2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // OS_MACOSX
2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (fd_limit > 0)
2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SetFileDescriptorLimit(fd_limit);
228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_CHROMEOS)
230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (parsed_command_line().HasSwitch(switches::kGuestSession)) {
231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Disable sync and extensions if we're in "browse without sign-in" mode.
232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CommandLine* singleton_command_line = CommandLine::ForCurrentProcess();
233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    singleton_command_line->AppendSwitch(switches::kDisableSync);
234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    singleton_command_line->AppendSwitch(switches::kDisableExtensions);
235dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    browser_defaults::bookmarks_enabled = false;
236dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
237dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif
2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BrowserMainPartsPosix::PostMainMessageLoopStart() {
2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int pipefd[2];
2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int ret = pipe(pipefd);
2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (ret < 0) {
2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    PLOG(DFATAL) << "Failed to create pipe";
2453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else {
2463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    g_shutdown_pipe_read_fd = pipefd[0];
2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    g_shutdown_pipe_write_fd = pipefd[1];
2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const size_t kShutdownDetectorThreadStackSize = 4096;
2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // TODO(viettrungluu,willchan): crbug.com/29675 - This currently leaks, so
2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // if you change this, you'll probably need to change the suppression.
2513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (!base::PlatformThread::CreateNonJoinable(
2523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            kShutdownDetectorThreadStackSize,
2533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            new ShutdownDetector(g_shutdown_pipe_read_fd))) {
2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      LOG(DFATAL) << "Failed to create shutdown detector task.";
2553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  printing::PrintingContextCairo::SetCreatePrintDialogFunction(
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      &PrintDialogGtk::CreatePrintDialog);
261dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif  // defined(OS_LINUX) && !defined(OS_CHROMEOS)
2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
263