diff options
-rw-r--r-- | base/command_line.cc | 24 | ||||
-rw-r--r-- | base/command_line.h | 32 | ||||
-rw-r--r-- | chrome/browser/process_singleton.h | 5 | ||||
-rw-r--r-- | chrome/browser/process_singleton_linux.cc | 7 | ||||
-rw-r--r-- | chrome/browser/process_singleton_linux_uitest.cc | 72 | ||||
-rw-r--r-- | chrome/browser/zygote_main_linux.cc | 5 |
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; } |