summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/command_line.cc24
-rw-r--r--base/command_line.h32
-rw-r--r--chrome/browser/process_singleton.h5
-rw-r--r--chrome/browser/process_singleton_linux.cc7
-rw-r--r--chrome/browser/process_singleton_linux_uitest.cc72
-rw-r--r--chrome/browser/zygote_main_linux.cc5
6 files changed, 70 insertions, 75 deletions
diff --git a/base/command_line.cc b/base/command_line.cc
index ac8402cb..84fa415 100644
--- a/base/command_line.cc
+++ b/base/command_line.cc
@@ -109,17 +109,14 @@ CommandLine::CommandLine(const std::wstring& program) {
}
}
#elif defined(OS_POSIX)
-CommandLine::CommandLine(int argc, const char* const* argv) {
+void CommandLine::InitFromArgv(int argc, const char* const* argv) {
for (int i = 0; i < argc; ++i)
argv_.push_back(argv[i]);
- InitFromArgv();
-}
-CommandLine::CommandLine(const std::vector<std::string>& argv) {
- argv_ = argv;
- InitFromArgv();
+ InitFromArgv(argv_);
}
-void CommandLine::InitFromArgv() {
+void CommandLine::InitFromArgv(const std::vector<std::string>& argv) {
+ argv_ = argv;
bool parse_switches = true;
for (size_t i = 1; i < argv_.size(); ++i) {
const std::string& arg = argv_[i];
@@ -192,22 +189,11 @@ bool CommandLine::IsSwitch(const StringType& parameter_string,
// static
void CommandLine::Init(int argc, const char* const* argv) {
-#if defined(OS_WIN)
current_process_commandline_ = new CommandLine;
- current_process_commandline_->ParseFromString(::GetCommandLineW());
-#elif defined(OS_POSIX)
- current_process_commandline_ = new CommandLine(argc, argv);
-#endif
-}
-
-// static
-void CommandLine::Init(const std::vector<std::string>& argv) {
- DCHECK(current_process_commandline_ == NULL);
#if defined(OS_WIN)
- current_process_commandline_ = new CommandLine;
current_process_commandline_->ParseFromString(::GetCommandLineW());
#elif defined(OS_POSIX)
- current_process_commandline_ = new CommandLine(argv);
+ current_process_commandline_->InitFromArgv(argc, argv);
#endif
}
diff --git a/base/command_line.h b/base/command_line.h
index 3eb3dbb..6b7d1f4 100644
--- a/base/command_line.h
+++ b/base/command_line.h
@@ -24,21 +24,28 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/file_path.h"
#include "base/logging.h"
-class FilePath;
class InProcessBrowserTest;
class CommandLine {
public:
#if defined(OS_WIN)
- // Creates a parsed version of the given command-line string.
+ // Initialize by parsing the given command-line string.
// The program name is assumed to be the first item in the string.
void ParseFromString(const std::wstring& command_line);
#elif defined(OS_POSIX)
- // Initialize from an argv vector (or directly from main()'s argv).
- CommandLine(int argc, const char* const* argv);
- explicit CommandLine(const std::vector<std::string>& argv);
+ // Initialize from an argv vector.
+ void InitFromArgv(int argc, const char* const* argv);
+ void InitFromArgv(const std::vector<std::string>& argv);
+
+ CommandLine(int argc, const char* const* argv) {
+ InitFromArgv(argc, argv);
+ }
+ explicit CommandLine(const std::vector<std::string>& argv) {
+ InitFromArgv(argv);
+ }
#endif
// Construct a new, empty command line.
@@ -53,7 +60,6 @@ class CommandLine {
// directly) because we don't trust the CRT's parsing of the command
// line, but it still must be called to set up the command line.
static void Init(int argc, const char* const* argv);
- static void Init(const std::vector<std::string>& argv);
#if defined(OS_LINUX) || defined(OS_FREEBSD)
// Sets the current process' arguments that show in "ps" etc. to those
@@ -76,8 +82,9 @@ class CommandLine {
static void Terminate() { Reset(); }
// Get the singleton CommandLine representing the current process's
- // command line.
- static const CommandLine* ForCurrentProcess() {
+ // command line. Note: returned value is mutable, but not thread safe;
+ // only mutate if you know what you're doing!
+ static CommandLine* ForCurrentProcess() {
DCHECK(current_process_commandline_);
return current_process_commandline_;
}
@@ -111,6 +118,12 @@ class CommandLine {
#endif
// Returns the program part of the command line string (the first item).
+ FilePath GetProgram() const {
+ return FilePath::FromWStringHack(program());
+ }
+
+ // Returns the program part of the command line string (the first item).
+ // Deprecated version of the above.
std::wstring program() const;
// Return a copy of the string prefixed with a switch prefix.
@@ -178,9 +191,6 @@ class CommandLine {
// The type of native command line arguments.
typedef std::string StringType;
-
- // Shared by the two POSIX constructor forms. Initalize from argv_.
- void InitFromArgv();
#endif
// Returns true and fills in |switch_string| and |switch_value|
diff --git a/chrome/browser/process_singleton.h b/chrome/browser/process_singleton.h
index c7fc904..76c9c22 100644
--- a/chrome/browser/process_singleton.h
+++ b/chrome/browser/process_singleton.h
@@ -18,6 +18,8 @@
#include "base/non_thread_safe.h"
#include "base/ref_counted.h"
+class CommandLine;
+
// ProcessSingleton ----------------------------------------------------------
//
// This class allows different browser processes to communicate with
@@ -53,7 +55,8 @@ class ProcessSingleton : public NonThreadSafe {
#if defined(OS_LINUX)
// Exposed for testing. We use a timeout on Linux, and in tests we want
// this timeout to be short.
- NotifyResult NotifyOtherProcessWithTimeout(int timeout_seconds);
+ NotifyResult NotifyOtherProcessWithTimeout(const CommandLine& command_line,
+ int timeout_seconds);
#endif
// Sets ourself up as the singleton instance.
diff --git a/chrome/browser/process_singleton_linux.cc b/chrome/browser/process_singleton_linux.cc
index 634b68f..bfff289 100644
--- a/chrome/browser/process_singleton_linux.cc
+++ b/chrome/browser/process_singleton_linux.cc
@@ -627,10 +627,12 @@ ProcessSingleton::~ProcessSingleton() {
}
ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
- return NotifyOtherProcessWithTimeout(kTimeoutInSeconds);
+ return NotifyOtherProcessWithTimeout(*CommandLine::ForCurrentProcess(),
+ kTimeoutInSeconds);
}
ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
+ const CommandLine& cmd_line,
int timeout_seconds) {
int socket;
sockaddr_un addr;
@@ -666,8 +668,7 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
return PROCESS_NONE;
to_send.append(current_dir.value());
- const std::vector<std::string>& argv =
- CommandLine::ForCurrentProcess()->argv();
+ const std::vector<std::string>& argv = cmd_line.argv();
for (std::vector<std::string>::const_iterator it = argv.begin();
it != argv.end(); ++it) {
to_send.push_back(kTokenDelimiter);
diff --git a/chrome/browser/process_singleton_linux_uitest.cc b/chrome/browser/process_singleton_linux_uitest.cc
index d7f309a..2e775f4 100644
--- a/chrome/browser/process_singleton_linux_uitest.cc
+++ b/chrome/browser/process_singleton_linux_uitest.cc
@@ -25,46 +25,38 @@
#include "chrome/test/ui/ui_test.h"
#include "testing/gtest/include/gtest/gtest.h"
-class ProcessSingletonLinuxTest : public UITest {
- public:
- virtual void SetUp() {
- UITest::SetUp();
- old_argv_ = CommandLine::ForCurrentProcess()->argv();
- }
-
- virtual void TearDown() {
- if (!old_argv_.empty()) {
- CommandLine::Reset();
- CommandLine::Init(old_argv_);
- }
- UITest::TearDown();
- }
-
- protected:
- // A helper method to call ProcessSingleton::NotifyOtherProcess().
- // |url| will be added to CommandLine for current process, so that it can be
- // sent to browser process by ProcessSingleton::NotifyOtherProcess().
- ProcessSingleton::NotifyResult NotifyOtherProcess(const std::string& url) {
- FilePath user_data_dir;
- PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
-
- std::vector<std::string> argv;
- argv.push_back(old_argv_[0]);
- argv.push_back(url);
- argv.push_back("--" + WideToASCII(switches::kNoProcessSingletonDialog));
-
- CommandLine::Reset();
- CommandLine::Init(argv);
-
- ProcessSingleton process_singleton(user_data_dir);
-
- // Use a short timeout to keep tests fast.
- const int kTimeoutSeconds = 3;
- return process_singleton.NotifyOtherProcessWithTimeout(kTimeoutSeconds);
- }
-
- std::vector<std::string> old_argv_;
-};
+
+namespace {
+
+typedef UITest ProcessSingletonLinuxTest;
+
+// A helper method to call ProcessSingleton::NotifyOtherProcess().
+// |url| will be added to CommandLine for current process, so that it can be
+// sent to browser process by ProcessSingleton::NotifyOtherProcess().
+ProcessSingleton::NotifyResult NotifyOtherProcess(const std::string& url) {
+ FilePath user_data_dir;
+ PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
+
+ // Hack: mutate the current process's command line so we don't show a dialog.
+ // Note that this only works if we have no loose values on the command line,
+ // but that's fine for unit tests. In a UI test we disable error dialogs
+ // when spawning Chrome, but this test hits the ProcessSingleton directly.
+ CommandLine* cmd_line = CommandLine::ForCurrentProcess();
+ if (!cmd_line->HasSwitch(switches::kNoProcessSingletonDialog))
+ cmd_line->AppendSwitch(switches::kNoProcessSingletonDialog);
+
+ CommandLine new_cmd_line(*cmd_line);
+ new_cmd_line.AppendLooseValue(ASCIIToWide(url));
+
+ ProcessSingleton process_singleton(user_data_dir);
+
+ // Use a short timeout to keep tests fast.
+ const int kTimeoutSeconds = 3;
+ return process_singleton.NotifyOtherProcessWithTimeout(new_cmd_line,
+ kTimeoutSeconds);
+}
+
+} // namespace
// Test if the socket file and symbol link created by ProcessSingletonLinux
// are valid. When running this test, the ProcessSingleton object is already
diff --git a/chrome/browser/zygote_main_linux.cc b/chrome/browser/zygote_main_linux.cc
index eb0ef42..ecf7291 100644
--- a/chrome/browser/zygote_main_linux.cc
+++ b/chrome/browser/zygote_main_linux.cc
@@ -193,8 +193,11 @@ class Zygote {
if (!child) {
close(3); // our socket from the browser is in fd 3
Singleton<base::GlobalDescriptors>()->Reset(mapping);
+
+ // Reset the process-wide command line to our new command line.
CommandLine::Reset();
- CommandLine::Init(args);
+ CommandLine::Init(0, NULL);
+ CommandLine::ForCurrentProcess()->InitFromArgv(args);
CommandLine::SetProcTitle();
return true;
}