| Index: chrome/browser/process_singleton_linux.cc
|
| diff --git a/chrome/browser/process_singleton_linux.cc b/chrome/browser/process_singleton_linux.cc
|
| index 583f4bf20e875559cb4347d68c49d4c2dfb5d80f..5189b1e00cba07e8e8a08c65141cdf7cd15cfc00 100644
|
| --- a/chrome/browser/process_singleton_linux.cc
|
| +++ b/chrome/browser/process_singleton_linux.cc
|
| @@ -708,12 +708,101 @@ ProcessSingleton::ProcessSingleton(const FilePath& user_data_dir)
|
| ProcessSingleton::~ProcessSingleton() {
|
| }
|
|
|
| +ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate(
|
| + const NotificationCallback& notification_callback) {
|
| + return NotifyOtherProcessWithTimeoutOrCreate(
|
| + *CommandLine::ForCurrentProcess(),
|
| + notification_callback,
|
| + kTimeoutInSeconds);
|
| +}
|
| +
|
| +void ProcessSingleton::Cleanup() {
|
| + UnlinkPath(socket_path_);
|
| + UnlinkPath(cookie_path_);
|
| + UnlinkPath(lock_path_);
|
| +}
|
| +
|
| +void ProcessSingleton::DisablePromptForTesting() {
|
| + g_disable_prompt = true;
|
| +}
|
| +
|
| ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
|
| return NotifyOtherProcessWithTimeout(*CommandLine::ForCurrentProcess(),
|
| kTimeoutInSeconds,
|
| true);
|
| }
|
|
|
| +bool ProcessSingleton::Create(
|
| + const NotificationCallback& notification_callback) {
|
| + int sock;
|
| + sockaddr_un addr;
|
| +
|
| + // The symlink lock is pointed to the hostname and process id, so other
|
| + // processes can find it out.
|
| + FilePath symlink_content(base::StringPrintf(
|
| + "%s%c%u",
|
| + net::GetHostName().c_str(),
|
| + kLockDelimiter,
|
| + current_pid_));
|
| +
|
| + // Create symbol link before binding the socket, to ensure only one instance
|
| + // can have the socket open.
|
| + if (!SymlinkPath(symlink_content, lock_path_)) {
|
| + // If we failed to create the lock, most likely another instance won the
|
| + // startup race.
|
| + return false;
|
| + }
|
| +
|
| + // Create the socket file somewhere in /tmp which is usually mounted as a
|
| + // normal filesystem. Some network filesystems (notably AFS) are screwy and
|
| + // do not support Unix domain sockets.
|
| + if (!socket_dir_.CreateUniqueTempDir()) {
|
| + LOG(ERROR) << "Failed to create socket directory.";
|
| + return false;
|
| + }
|
| + // Setup the socket symlink and the two cookies.
|
| + FilePath socket_target_path =
|
| + socket_dir_.path().Append(chrome::kSingletonSocketFilename);
|
| + FilePath cookie(GenerateCookie());
|
| + FilePath remote_cookie_path =
|
| + socket_dir_.path().Append(chrome::kSingletonCookieFilename);
|
| + UnlinkPath(socket_path_);
|
| + UnlinkPath(cookie_path_);
|
| + if (!SymlinkPath(socket_target_path, socket_path_) ||
|
| + !SymlinkPath(cookie, cookie_path_) ||
|
| + !SymlinkPath(cookie, remote_cookie_path)) {
|
| + // We've already locked things, so we can't have lost the startup race,
|
| + // but something doesn't like us.
|
| + LOG(ERROR) << "Failed to create symlinks.";
|
| + if (!socket_dir_.Delete())
|
| + LOG(ERROR) << "Encountered a problem when deleting socket directory.";
|
| + return false;
|
| + }
|
| +
|
| + SetupSocket(socket_target_path.value(), &sock, &addr);
|
| +
|
| + if (bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
|
| + PLOG(ERROR) << "Failed to bind() " << socket_target_path.value();
|
| + CloseSocket(sock);
|
| + return false;
|
| + }
|
| +
|
| + if (listen(sock, 5) < 0)
|
| + NOTREACHED() << "listen failed: " << safe_strerror(errno);
|
| +
|
| + notification_callback_ = notification_callback;
|
| +
|
| + DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::IO));
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO,
|
| + FROM_HERE,
|
| + base::Bind(&ProcessSingleton::LinuxWatcher::StartListening,
|
| + watcher_.get(),
|
| + sock));
|
| +
|
| + return true;
|
| +}
|
| +
|
| ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
|
| const CommandLine& cmd_line,
|
| int timeout_seconds,
|
| @@ -835,14 +924,6 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
|
| return PROCESS_NOTIFIED;
|
| }
|
|
|
| -ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate(
|
| - const NotificationCallback& notification_callback) {
|
| - return NotifyOtherProcessWithTimeoutOrCreate(
|
| - *CommandLine::ForCurrentProcess(),
|
| - notification_callback,
|
| - kTimeoutInSeconds);
|
| -}
|
| -
|
| ProcessSingleton::NotifyResult
|
| ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate(
|
| const CommandLine& command_line,
|
| @@ -875,87 +956,6 @@ void ProcessSingleton::OverrideKillCallbackForTesting(
|
| kill_callback_ = callback;
|
| }
|
|
|
| -void ProcessSingleton::DisablePromptForTesting() {
|
| - g_disable_prompt = true;
|
| -}
|
| -
|
| -bool ProcessSingleton::Create(
|
| - const NotificationCallback& notification_callback) {
|
| - int sock;
|
| - sockaddr_un addr;
|
| -
|
| - // The symlink lock is pointed to the hostname and process id, so other
|
| - // processes can find it out.
|
| - FilePath symlink_content(base::StringPrintf(
|
| - "%s%c%u",
|
| - net::GetHostName().c_str(),
|
| - kLockDelimiter,
|
| - current_pid_));
|
| -
|
| - // Create symbol link before binding the socket, to ensure only one instance
|
| - // can have the socket open.
|
| - if (!SymlinkPath(symlink_content, lock_path_)) {
|
| - // If we failed to create the lock, most likely another instance won the
|
| - // startup race.
|
| - return false;
|
| - }
|
| -
|
| - // Create the socket file somewhere in /tmp which is usually mounted as a
|
| - // normal filesystem. Some network filesystems (notably AFS) are screwy and
|
| - // do not support Unix domain sockets.
|
| - if (!socket_dir_.CreateUniqueTempDir()) {
|
| - LOG(ERROR) << "Failed to create socket directory.";
|
| - return false;
|
| - }
|
| - // Setup the socket symlink and the two cookies.
|
| - FilePath socket_target_path =
|
| - socket_dir_.path().Append(chrome::kSingletonSocketFilename);
|
| - FilePath cookie(GenerateCookie());
|
| - FilePath remote_cookie_path =
|
| - socket_dir_.path().Append(chrome::kSingletonCookieFilename);
|
| - UnlinkPath(socket_path_);
|
| - UnlinkPath(cookie_path_);
|
| - if (!SymlinkPath(socket_target_path, socket_path_) ||
|
| - !SymlinkPath(cookie, cookie_path_) ||
|
| - !SymlinkPath(cookie, remote_cookie_path)) {
|
| - // We've already locked things, so we can't have lost the startup race,
|
| - // but something doesn't like us.
|
| - LOG(ERROR) << "Failed to create symlinks.";
|
| - if (!socket_dir_.Delete())
|
| - LOG(ERROR) << "Encountered a problem when deleting socket directory.";
|
| - return false;
|
| - }
|
| -
|
| - SetupSocket(socket_target_path.value(), &sock, &addr);
|
| -
|
| - if (bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
|
| - PLOG(ERROR) << "Failed to bind() " << socket_target_path.value();
|
| - CloseSocket(sock);
|
| - return false;
|
| - }
|
| -
|
| - if (listen(sock, 5) < 0)
|
| - NOTREACHED() << "listen failed: " << safe_strerror(errno);
|
| -
|
| - notification_callback_ = notification_callback;
|
| -
|
| - DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::IO));
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO,
|
| - FROM_HERE,
|
| - base::Bind(&ProcessSingleton::LinuxWatcher::StartListening,
|
| - watcher_.get(),
|
| - sock));
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void ProcessSingleton::Cleanup() {
|
| - UnlinkPath(socket_path_);
|
| - UnlinkPath(cookie_path_);
|
| - UnlinkPath(lock_path_);
|
| -}
|
| -
|
| bool ProcessSingleton::IsSameChromeInstance(pid_t pid) {
|
| pid_t cur_pid = current_pid_;
|
| while (pid != cur_pid) {
|
|
|