Revert of Merge apps/pref* to extensions/browser/pref* (patchset #1 of https://codere...
[chromium-blink-merge.git] / chrome / browser / process_singleton_posix.cc
blobb65911fd4828786fc69ee4998a76cd3664dc9e32
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // On Linux, when the user tries to launch a second copy of chrome, we check
6 // for a socket in the user's profile directory. If the socket file is open we
7 // send a message to the first chrome browser process with the current
8 // directory and second process command line flags. The second process then
9 // exits.
11 // Because many networked filesystem implementations do not support unix domain
12 // sockets, we create the socket in a temporary directory and create a symlink
13 // in the profile. This temporary directory is no longer bound to the profile,
14 // and may disappear across a reboot or login to a separate session. To bind
15 // them, we store a unique cookie in the profile directory, which must also be
16 // present in the remote directory to connect. The cookie is checked both before
17 // and after the connection. /tmp is sticky, and different Chrome sessions use
18 // different cookies. Thus, a matching cookie before and after means the
19 // connection was to a directory with a valid cookie.
21 // We also have a lock file, which is a symlink to a non-existent destination.
22 // The destination is a string containing the hostname and process id of
23 // chrome's browser process, eg. "SingletonLock -> example.com-9156". When the
24 // first copy of chrome exits it will delete the lock file on shutdown, so that
25 // a different instance on a different host may then use the profile directory.
27 // If writing to the socket fails, the hostname in the lock is checked to see if
28 // another instance is running a different host using a shared filesystem (nfs,
29 // etc.) If the hostname differs an error is displayed and the second process
30 // exits. Otherwise the first process (if any) is killed and the second process
31 // starts as normal.
33 // When the second process sends the current directory and command line flags to
34 // the first process, it waits for an ACK message back from the first process
35 // for a certain time. If there is no ACK message back in time, then the first
36 // process will be considered as hung for some reason. The second process then
37 // retrieves the process id from the symbol link and kills it by sending
38 // SIGKILL. Then the second process starts as normal.
40 #include "chrome/browser/process_singleton.h"
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <signal.h>
45 #include <sys/socket.h>
46 #include <sys/stat.h>
47 #include <sys/types.h>
48 #include <sys/un.h>
49 #include <unistd.h>
51 #include <cstring>
52 #include <set>
53 #include <string>
55 #include "base/base_paths.h"
56 #include "base/basictypes.h"
57 #include "base/bind.h"
58 #include "base/command_line.h"
59 #include "base/file_util.h"
60 #include "base/files/file_path.h"
61 #include "base/logging.h"
62 #include "base/message_loop/message_loop.h"
63 #include "base/path_service.h"
64 #include "base/posix/eintr_wrapper.h"
65 #include "base/rand_util.h"
66 #include "base/safe_strerror_posix.h"
67 #include "base/sequenced_task_runner_helpers.h"
68 #include "base/stl_util.h"
69 #include "base/strings/string_number_conversions.h"
70 #include "base/strings/string_split.h"
71 #include "base/strings/string_util.h"
72 #include "base/strings/stringprintf.h"
73 #include "base/strings/sys_string_conversions.h"
74 #include "base/strings/utf_string_conversions.h"
75 #include "base/threading/platform_thread.h"
76 #include "base/time/time.h"
77 #include "base/timer/timer.h"
78 #include "chrome/common/chrome_constants.h"
79 #include "chrome/grit/chromium_strings.h"
80 #include "chrome/grit/generated_resources.h"
81 #include "content/public/browser/browser_thread.h"
82 #include "net/base/net_util.h"
83 #include "ui/base/l10n/l10n_util.h"
85 #if defined(OS_LINUX)
86 #include "chrome/browser/ui/process_singleton_dialog_linux.h"
87 #endif
89 #if defined(TOOLKIT_VIEWS) && defined(OS_LINUX) && !defined(OS_CHROMEOS)
90 #include "ui/views/linux_ui/linux_ui.h"
91 #endif
93 using content::BrowserThread;
95 const int ProcessSingleton::kTimeoutInSeconds;
97 namespace {
99 static bool g_disable_prompt;
100 const char kStartToken[] = "START";
101 const char kACKToken[] = "ACK";
102 const char kShutdownToken[] = "SHUTDOWN";
103 const char kTokenDelimiter = '\0';
104 const int kMaxMessageLength = 32 * 1024;
105 const int kMaxACKMessageLength = arraysize(kShutdownToken) - 1;
107 const char kLockDelimiter = '-';
109 // Set a file descriptor to be non-blocking.
110 // Return 0 on success, -1 on failure.
111 int SetNonBlocking(int fd) {
112 int flags = fcntl(fd, F_GETFL, 0);
113 if (-1 == flags)
114 return flags;
115 if (flags & O_NONBLOCK)
116 return 0;
117 return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
120 // Set the close-on-exec bit on a file descriptor.
121 // Returns 0 on success, -1 on failure.
122 int SetCloseOnExec(int fd) {
123 int flags = fcntl(fd, F_GETFD, 0);
124 if (-1 == flags)
125 return flags;
126 if (flags & FD_CLOEXEC)
127 return 0;
128 return fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
131 // Close a socket and check return value.
132 void CloseSocket(int fd) {
133 int rv = IGNORE_EINTR(close(fd));
134 DCHECK_EQ(0, rv) << "Error closing socket: " << safe_strerror(errno);
137 // Write a message to a socket fd.
138 bool WriteToSocket(int fd, const char *message, size_t length) {
139 DCHECK(message);
140 DCHECK(length);
141 size_t bytes_written = 0;
142 do {
143 ssize_t rv = HANDLE_EINTR(
144 write(fd, message + bytes_written, length - bytes_written));
145 if (rv < 0) {
146 if (errno == EAGAIN || errno == EWOULDBLOCK) {
147 // The socket shouldn't block, we're sending so little data. Just give
148 // up here, since NotifyOtherProcess() doesn't have an asynchronous api.
149 LOG(ERROR) << "ProcessSingleton would block on write(), so it gave up.";
150 return false;
152 PLOG(ERROR) << "write() failed";
153 return false;
155 bytes_written += rv;
156 } while (bytes_written < length);
158 return true;
161 // Wait a socket for read for a certain timeout in seconds.
162 // Returns -1 if error occurred, 0 if timeout reached, > 0 if the socket is
163 // ready for read.
164 int WaitSocketForRead(int fd, int timeout) {
165 fd_set read_fds;
166 struct timeval tv;
168 FD_ZERO(&read_fds);
169 FD_SET(fd, &read_fds);
170 tv.tv_sec = timeout;
171 tv.tv_usec = 0;
173 return HANDLE_EINTR(select(fd + 1, &read_fds, NULL, NULL, &tv));
176 // Read a message from a socket fd, with an optional timeout in seconds.
177 // If |timeout| <= 0 then read immediately.
178 // Return number of bytes actually read, or -1 on error.
179 ssize_t ReadFromSocket(int fd, char *buf, size_t bufsize, int timeout) {
180 if (timeout > 0) {
181 int rv = WaitSocketForRead(fd, timeout);
182 if (rv <= 0)
183 return rv;
186 size_t bytes_read = 0;
187 do {
188 ssize_t rv = HANDLE_EINTR(read(fd, buf + bytes_read, bufsize - bytes_read));
189 if (rv < 0) {
190 if (errno != EAGAIN && errno != EWOULDBLOCK) {
191 PLOG(ERROR) << "read() failed";
192 return rv;
193 } else {
194 // It would block, so we just return what has been read.
195 return bytes_read;
197 } else if (!rv) {
198 // No more data to read.
199 return bytes_read;
200 } else {
201 bytes_read += rv;
203 } while (bytes_read < bufsize);
205 return bytes_read;
208 // Set up a sockaddr appropriate for messaging.
209 void SetupSockAddr(const std::string& path, struct sockaddr_un* addr) {
210 addr->sun_family = AF_UNIX;
211 CHECK(path.length() < arraysize(addr->sun_path))
212 << "Socket path too long: " << path;
213 base::strlcpy(addr->sun_path, path.c_str(), arraysize(addr->sun_path));
216 // Set up a socket appropriate for messaging.
217 int SetupSocketOnly() {
218 int sock = socket(PF_UNIX, SOCK_STREAM, 0);
219 PCHECK(sock >= 0) << "socket() failed";
221 int rv = SetNonBlocking(sock);
222 DCHECK_EQ(0, rv) << "Failed to make non-blocking socket.";
223 rv = SetCloseOnExec(sock);
224 DCHECK_EQ(0, rv) << "Failed to set CLOEXEC on socket.";
226 return sock;
229 // Set up a socket and sockaddr appropriate for messaging.
230 void SetupSocket(const std::string& path, int* sock, struct sockaddr_un* addr) {
231 *sock = SetupSocketOnly();
232 SetupSockAddr(path, addr);
235 // Read a symbolic link, return empty string if given path is not a symbol link.
236 base::FilePath ReadLink(const base::FilePath& path) {
237 base::FilePath target;
238 if (!base::ReadSymbolicLink(path, &target)) {
239 // The only errno that should occur is ENOENT.
240 if (errno != 0 && errno != ENOENT)
241 PLOG(ERROR) << "readlink(" << path.value() << ") failed";
243 return target;
246 // Unlink a path. Return true on success.
247 bool UnlinkPath(const base::FilePath& path) {
248 int rv = unlink(path.value().c_str());
249 if (rv < 0 && errno != ENOENT)
250 PLOG(ERROR) << "Failed to unlink " << path.value();
252 return rv == 0;
255 // Create a symlink. Returns true on success.
256 bool SymlinkPath(const base::FilePath& target, const base::FilePath& path) {
257 if (!base::CreateSymbolicLink(target, path)) {
258 // Double check the value in case symlink suceeded but we got an incorrect
259 // failure due to NFS packet loss & retry.
260 int saved_errno = errno;
261 if (ReadLink(path) != target) {
262 // If we failed to create the lock, most likely another instance won the
263 // startup race.
264 errno = saved_errno;
265 PLOG(ERROR) << "Failed to create " << path.value();
266 return false;
269 return true;
272 // Extract the hostname and pid from the lock symlink.
273 // Returns true if the lock existed.
274 bool ParseLockPath(const base::FilePath& path,
275 std::string* hostname,
276 int* pid) {
277 std::string real_path = ReadLink(path).value();
278 if (real_path.empty())
279 return false;
281 std::string::size_type pos = real_path.rfind(kLockDelimiter);
283 // If the path is not a symbolic link, or doesn't contain what we expect,
284 // bail.
285 if (pos == std::string::npos) {
286 *hostname = "";
287 *pid = -1;
288 return true;
291 *hostname = real_path.substr(0, pos);
293 const std::string& pid_str = real_path.substr(pos + 1);
294 if (!base::StringToInt(pid_str, pid))
295 *pid = -1;
297 return true;
300 // Returns true if the user opted to unlock the profile.
301 bool DisplayProfileInUseError(const base::FilePath& lock_path,
302 const std::string& hostname,
303 int pid) {
304 base::string16 error = l10n_util::GetStringFUTF16(
305 IDS_PROFILE_IN_USE_POSIX,
306 base::IntToString16(pid),
307 base::ASCIIToUTF16(hostname));
308 LOG(ERROR) << error;
310 if (g_disable_prompt)
311 return false;
313 #if defined(OS_LINUX)
314 base::string16 relaunch_button_text = l10n_util::GetStringUTF16(
315 IDS_PROFILE_IN_USE_LINUX_RELAUNCH);
316 return ShowProcessSingletonDialog(error, relaunch_button_text);
317 #elif defined(OS_MACOSX)
318 // On Mac, always usurp the lock.
319 return true;
320 #endif
322 NOTREACHED();
323 return false;
326 bool IsChromeProcess(pid_t pid) {
327 base::FilePath other_chrome_path(base::GetProcessExecutablePath(pid));
328 return (!other_chrome_path.empty() &&
329 other_chrome_path.BaseName() ==
330 base::FilePath(chrome::kBrowserProcessExecutableName));
333 // A helper class to hold onto a socket.
334 class ScopedSocket {
335 public:
336 ScopedSocket() : fd_(-1) { Reset(); }
337 ~ScopedSocket() { Close(); }
338 int fd() { return fd_; }
339 void Reset() {
340 Close();
341 fd_ = SetupSocketOnly();
343 void Close() {
344 if (fd_ >= 0)
345 CloseSocket(fd_);
346 fd_ = -1;
348 private:
349 int fd_;
352 // Returns a random string for uniquifying profile connections.
353 std::string GenerateCookie() {
354 return base::Uint64ToString(base::RandUint64());
357 bool CheckCookie(const base::FilePath& path, const base::FilePath& cookie) {
358 return (cookie == ReadLink(path));
361 bool ConnectSocket(ScopedSocket* socket,
362 const base::FilePath& socket_path,
363 const base::FilePath& cookie_path) {
364 base::FilePath socket_target;
365 if (base::ReadSymbolicLink(socket_path, &socket_target)) {
366 // It's a symlink. Read the cookie.
367 base::FilePath cookie = ReadLink(cookie_path);
368 if (cookie.empty())
369 return false;
370 base::FilePath remote_cookie = socket_target.DirName().
371 Append(chrome::kSingletonCookieFilename);
372 // Verify the cookie before connecting.
373 if (!CheckCookie(remote_cookie, cookie))
374 return false;
375 // Now we know the directory was (at that point) created by the profile
376 // owner. Try to connect.
377 sockaddr_un addr;
378 SetupSockAddr(socket_target.value(), &addr);
379 int ret = HANDLE_EINTR(connect(socket->fd(),
380 reinterpret_cast<sockaddr*>(&addr),
381 sizeof(addr)));
382 if (ret != 0)
383 return false;
384 // Check the cookie again. We only link in /tmp, which is sticky, so, if the
385 // directory is still correct, it must have been correct in-between when we
386 // connected. POSIX, sadly, lacks a connectat().
387 if (!CheckCookie(remote_cookie, cookie)) {
388 socket->Reset();
389 return false;
391 // Success!
392 return true;
393 } else if (errno == EINVAL) {
394 // It exists, but is not a symlink (or some other error we detect
395 // later). Just connect to it directly; this is an older version of Chrome.
396 sockaddr_un addr;
397 SetupSockAddr(socket_path.value(), &addr);
398 int ret = HANDLE_EINTR(connect(socket->fd(),
399 reinterpret_cast<sockaddr*>(&addr),
400 sizeof(addr)));
401 return (ret == 0);
402 } else {
403 // File is missing, or other error.
404 if (errno != ENOENT)
405 PLOG(ERROR) << "readlink failed";
406 return false;
410 #if defined(OS_MACOSX)
411 bool ReplaceOldSingletonLock(const base::FilePath& symlink_content,
412 const base::FilePath& lock_path) {
413 // Try taking an flock(2) on the file. Failure means the lock is taken so we
414 // should quit.
415 base::ScopedFD lock_fd(HANDLE_EINTR(
416 open(lock_path.value().c_str(), O_RDWR | O_CREAT | O_SYMLINK, 0644)));
417 if (!lock_fd.is_valid()) {
418 PLOG(ERROR) << "Could not open singleton lock";
419 return false;
422 int rc = HANDLE_EINTR(flock(lock_fd.get(), LOCK_EX | LOCK_NB));
423 if (rc == -1) {
424 if (errno == EWOULDBLOCK) {
425 LOG(ERROR) << "Singleton lock held by old process.";
426 } else {
427 PLOG(ERROR) << "Error locking singleton lock";
429 return false;
432 // Successfully taking the lock means we can replace it with the a new symlink
433 // lock. We never flock() the lock file from now on. I.e. we assume that an
434 // old version of Chrome will not run with the same user data dir after this
435 // version has run.
436 if (!base::DeleteFile(lock_path, false)) {
437 PLOG(ERROR) << "Could not delete old singleton lock.";
438 return false;
441 return SymlinkPath(symlink_content, lock_path);
443 #endif // defined(OS_MACOSX)
445 } // namespace
447 ///////////////////////////////////////////////////////////////////////////////
448 // ProcessSingleton::LinuxWatcher
449 // A helper class for a Linux specific implementation of the process singleton.
450 // This class sets up a listener on the singleton socket and handles parsing
451 // messages that come in on the singleton socket.
452 class ProcessSingleton::LinuxWatcher
453 : public base::MessageLoopForIO::Watcher,
454 public base::MessageLoop::DestructionObserver,
455 public base::RefCountedThreadSafe<ProcessSingleton::LinuxWatcher,
456 BrowserThread::DeleteOnIOThread> {
457 public:
458 // A helper class to read message from an established socket.
459 class SocketReader : public base::MessageLoopForIO::Watcher {
460 public:
461 SocketReader(ProcessSingleton::LinuxWatcher* parent,
462 base::MessageLoop* ui_message_loop,
463 int fd)
464 : parent_(parent),
465 ui_message_loop_(ui_message_loop),
466 fd_(fd),
467 bytes_read_(0) {
468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
469 // Wait for reads.
470 base::MessageLoopForIO::current()->WatchFileDescriptor(
471 fd, true, base::MessageLoopForIO::WATCH_READ, &fd_reader_, this);
472 // If we haven't completed in a reasonable amount of time, give up.
473 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kTimeoutInSeconds),
474 this, &SocketReader::CleanupAndDeleteSelf);
477 virtual ~SocketReader() {
478 CloseSocket(fd_);
481 // MessageLoopForIO::Watcher impl.
482 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
483 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {
484 // SocketReader only watches for accept (read) events.
485 NOTREACHED();
488 // Finish handling the incoming message by optionally sending back an ACK
489 // message and removing this SocketReader.
490 void FinishWithACK(const char *message, size_t length);
492 private:
493 void CleanupAndDeleteSelf() {
494 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
496 parent_->RemoveSocketReader(this);
497 // We're deleted beyond this point.
500 base::MessageLoopForIO::FileDescriptorWatcher fd_reader_;
502 // The ProcessSingleton::LinuxWatcher that owns us.
503 ProcessSingleton::LinuxWatcher* const parent_;
505 // A reference to the UI message loop.
506 base::MessageLoop* const ui_message_loop_;
508 // The file descriptor we're reading.
509 const int fd_;
511 // Store the message in this buffer.
512 char buf_[kMaxMessageLength];
514 // Tracks the number of bytes we've read in case we're getting partial
515 // reads.
516 size_t bytes_read_;
518 base::OneShotTimer<SocketReader> timer_;
520 DISALLOW_COPY_AND_ASSIGN(SocketReader);
523 // We expect to only be constructed on the UI thread.
524 explicit LinuxWatcher(ProcessSingleton* parent)
525 : ui_message_loop_(base::MessageLoop::current()),
526 parent_(parent) {
529 // Start listening for connections on the socket. This method should be
530 // called from the IO thread.
531 void StartListening(int socket);
533 // This method determines if we should use the same process and if we should,
534 // opens a new browser tab. This runs on the UI thread.
535 // |reader| is for sending back ACK message.
536 void HandleMessage(const std::string& current_dir,
537 const std::vector<std::string>& argv,
538 SocketReader* reader);
540 // MessageLoopForIO::Watcher impl. These run on the IO thread.
541 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
542 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {
543 // ProcessSingleton only watches for accept (read) events.
544 NOTREACHED();
547 // MessageLoop::DestructionObserver
548 virtual void WillDestroyCurrentMessageLoop() OVERRIDE {
549 fd_watcher_.StopWatchingFileDescriptor();
552 private:
553 friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
554 friend class base::DeleteHelper<ProcessSingleton::LinuxWatcher>;
556 virtual ~LinuxWatcher() {
557 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
558 STLDeleteElements(&readers_);
560 base::MessageLoopForIO* ml = base::MessageLoopForIO::current();
561 ml->RemoveDestructionObserver(this);
564 // Removes and deletes the SocketReader.
565 void RemoveSocketReader(SocketReader* reader);
567 base::MessageLoopForIO::FileDescriptorWatcher fd_watcher_;
569 // A reference to the UI message loop (i.e., the message loop we were
570 // constructed on).
571 base::MessageLoop* ui_message_loop_;
573 // The ProcessSingleton that owns us.
574 ProcessSingleton* const parent_;
576 std::set<SocketReader*> readers_;
578 DISALLOW_COPY_AND_ASSIGN(LinuxWatcher);
581 void ProcessSingleton::LinuxWatcher::OnFileCanReadWithoutBlocking(int fd) {
582 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
583 // Accepting incoming client.
584 sockaddr_un from;
585 socklen_t from_len = sizeof(from);
586 int connection_socket = HANDLE_EINTR(accept(
587 fd, reinterpret_cast<sockaddr*>(&from), &from_len));
588 if (-1 == connection_socket) {
589 PLOG(ERROR) << "accept() failed";
590 return;
592 int rv = SetNonBlocking(connection_socket);
593 DCHECK_EQ(0, rv) << "Failed to make non-blocking socket.";
594 SocketReader* reader = new SocketReader(this,
595 ui_message_loop_,
596 connection_socket);
597 readers_.insert(reader);
600 void ProcessSingleton::LinuxWatcher::StartListening(int socket) {
601 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
602 // Watch for client connections on this socket.
603 base::MessageLoopForIO* ml = base::MessageLoopForIO::current();
604 ml->AddDestructionObserver(this);
605 ml->WatchFileDescriptor(socket, true, base::MessageLoopForIO::WATCH_READ,
606 &fd_watcher_, this);
609 void ProcessSingleton::LinuxWatcher::HandleMessage(
610 const std::string& current_dir, const std::vector<std::string>& argv,
611 SocketReader* reader) {
612 DCHECK(ui_message_loop_ == base::MessageLoop::current());
613 DCHECK(reader);
615 if (parent_->notification_callback_.Run(CommandLine(argv),
616 base::FilePath(current_dir))) {
617 // Send back "ACK" message to prevent the client process from starting up.
618 reader->FinishWithACK(kACKToken, arraysize(kACKToken) - 1);
619 } else {
620 LOG(WARNING) << "Not handling interprocess notification as browser"
621 " is shutting down";
622 // Send back "SHUTDOWN" message, so that the client process can start up
623 // without killing this process.
624 reader->FinishWithACK(kShutdownToken, arraysize(kShutdownToken) - 1);
625 return;
629 void ProcessSingleton::LinuxWatcher::RemoveSocketReader(SocketReader* reader) {
630 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
631 DCHECK(reader);
632 readers_.erase(reader);
633 delete reader;
636 ///////////////////////////////////////////////////////////////////////////////
637 // ProcessSingleton::LinuxWatcher::SocketReader
640 void ProcessSingleton::LinuxWatcher::SocketReader::OnFileCanReadWithoutBlocking(
641 int fd) {
642 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
643 DCHECK_EQ(fd, fd_);
644 while (bytes_read_ < sizeof(buf_)) {
645 ssize_t rv = HANDLE_EINTR(
646 read(fd, buf_ + bytes_read_, sizeof(buf_) - bytes_read_));
647 if (rv < 0) {
648 if (errno != EAGAIN && errno != EWOULDBLOCK) {
649 PLOG(ERROR) << "read() failed";
650 CloseSocket(fd);
651 return;
652 } else {
653 // It would block, so we just return and continue to watch for the next
654 // opportunity to read.
655 return;
657 } else if (!rv) {
658 // No more data to read. It's time to process the message.
659 break;
660 } else {
661 bytes_read_ += rv;
665 // Validate the message. The shortest message is kStartToken\0x\0x
666 const size_t kMinMessageLength = arraysize(kStartToken) + 4;
667 if (bytes_read_ < kMinMessageLength) {
668 buf_[bytes_read_] = 0;
669 LOG(ERROR) << "Invalid socket message (wrong length):" << buf_;
670 CleanupAndDeleteSelf();
671 return;
674 std::string str(buf_, bytes_read_);
675 std::vector<std::string> tokens;
676 base::SplitString(str, kTokenDelimiter, &tokens);
678 if (tokens.size() < 3 || tokens[0] != kStartToken) {
679 LOG(ERROR) << "Wrong message format: " << str;
680 CleanupAndDeleteSelf();
681 return;
684 // Stop the expiration timer to prevent this SocketReader object from being
685 // terminated unexpectly.
686 timer_.Stop();
688 std::string current_dir = tokens[1];
689 // Remove the first two tokens. The remaining tokens should be the command
690 // line argv array.
691 tokens.erase(tokens.begin());
692 tokens.erase(tokens.begin());
694 // Return to the UI thread to handle opening a new browser tab.
695 ui_message_loop_->PostTask(FROM_HERE, base::Bind(
696 &ProcessSingleton::LinuxWatcher::HandleMessage,
697 parent_,
698 current_dir,
699 tokens,
700 this));
701 fd_reader_.StopWatchingFileDescriptor();
703 // LinuxWatcher::HandleMessage() is in charge of destroying this SocketReader
704 // object by invoking SocketReader::FinishWithACK().
707 void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
708 const char *message, size_t length) {
709 if (message && length) {
710 // Not necessary to care about the return value.
711 WriteToSocket(fd_, message, length);
714 if (shutdown(fd_, SHUT_WR) < 0)
715 PLOG(ERROR) << "shutdown() failed";
717 BrowserThread::PostTask(
718 BrowserThread::IO,
719 FROM_HERE,
720 base::Bind(&ProcessSingleton::LinuxWatcher::RemoveSocketReader,
721 parent_,
722 this));
723 // We will be deleted once the posted RemoveSocketReader task runs.
726 ///////////////////////////////////////////////////////////////////////////////
727 // ProcessSingleton
729 ProcessSingleton::ProcessSingleton(
730 const base::FilePath& user_data_dir,
731 const NotificationCallback& notification_callback)
732 : notification_callback_(notification_callback),
733 current_pid_(base::GetCurrentProcId()),
734 watcher_(new LinuxWatcher(this)) {
735 socket_path_ = user_data_dir.Append(chrome::kSingletonSocketFilename);
736 lock_path_ = user_data_dir.Append(chrome::kSingletonLockFilename);
737 cookie_path_ = user_data_dir.Append(chrome::kSingletonCookieFilename);
739 kill_callback_ = base::Bind(&ProcessSingleton::KillProcess,
740 base::Unretained(this));
743 ProcessSingleton::~ProcessSingleton() {
746 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
747 return NotifyOtherProcessWithTimeout(*CommandLine::ForCurrentProcess(),
748 kTimeoutInSeconds,
749 true);
752 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
753 const CommandLine& cmd_line,
754 int timeout_seconds,
755 bool kill_unresponsive) {
756 DCHECK_GE(timeout_seconds, 0);
758 ScopedSocket socket;
759 for (int retries = 0; retries <= timeout_seconds; ++retries) {
760 // Try to connect to the socket.
761 if (ConnectSocket(&socket, socket_path_, cookie_path_))
762 break;
764 // If we're in a race with another process, they may be in Create() and have
765 // created the lock but not attached to the socket. So we check if the
766 // process with the pid from the lockfile is currently running and is a
767 // chrome browser. If so, we loop and try again for |timeout_seconds|.
769 std::string hostname;
770 int pid;
771 if (!ParseLockPath(lock_path_, &hostname, &pid)) {
772 // No lockfile exists.
773 return PROCESS_NONE;
776 if (hostname.empty()) {
777 // Invalid lockfile.
778 UnlinkPath(lock_path_);
779 return PROCESS_NONE;
782 if (hostname != net::GetHostName() && !IsChromeProcess(pid)) {
783 // Locked by process on another host. If the user selected to unlock
784 // the profile, try to continue; otherwise quit.
785 if (DisplayProfileInUseError(lock_path_, hostname, pid)) {
786 UnlinkPath(lock_path_);
787 return PROCESS_NONE;
789 return PROFILE_IN_USE;
792 if (!IsChromeProcess(pid)) {
793 // Orphaned lockfile (no process with pid, or non-chrome process.)
794 UnlinkPath(lock_path_);
795 return PROCESS_NONE;
798 if (IsSameChromeInstance(pid)) {
799 // Orphaned lockfile (pid is part of same chrome instance we are, even
800 // though we haven't tried to create a lockfile yet).
801 UnlinkPath(lock_path_);
802 return PROCESS_NONE;
805 if (retries == timeout_seconds) {
806 // Retries failed. Kill the unresponsive chrome process and continue.
807 if (!kill_unresponsive || !KillProcessByLockPath())
808 return PROFILE_IN_USE;
809 return PROCESS_NONE;
812 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
815 timeval timeout = {timeout_seconds, 0};
816 setsockopt(socket.fd(), SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
818 // Found another process, prepare our command line
819 // format is "START\0<current dir>\0<argv[0]>\0...\0<argv[n]>".
820 std::string to_send(kStartToken);
821 to_send.push_back(kTokenDelimiter);
823 base::FilePath current_dir;
824 if (!PathService::Get(base::DIR_CURRENT, &current_dir))
825 return PROCESS_NONE;
826 to_send.append(current_dir.value());
828 const std::vector<std::string>& argv = cmd_line.argv();
829 for (std::vector<std::string>::const_iterator it = argv.begin();
830 it != argv.end(); ++it) {
831 to_send.push_back(kTokenDelimiter);
832 to_send.append(*it);
835 // Send the message
836 if (!WriteToSocket(socket.fd(), to_send.data(), to_send.length())) {
837 // Try to kill the other process, because it might have been dead.
838 if (!kill_unresponsive || !KillProcessByLockPath())
839 return PROFILE_IN_USE;
840 return PROCESS_NONE;
843 if (shutdown(socket.fd(), SHUT_WR) < 0)
844 PLOG(ERROR) << "shutdown() failed";
846 // Read ACK message from the other process. It might be blocked for a certain
847 // timeout, to make sure the other process has enough time to return ACK.
848 char buf[kMaxACKMessageLength + 1];
849 ssize_t len =
850 ReadFromSocket(socket.fd(), buf, kMaxACKMessageLength, timeout_seconds);
852 // Failed to read ACK, the other process might have been frozen.
853 if (len <= 0) {
854 if (!kill_unresponsive || !KillProcessByLockPath())
855 return PROFILE_IN_USE;
856 return PROCESS_NONE;
859 buf[len] = '\0';
860 if (strncmp(buf, kShutdownToken, arraysize(kShutdownToken) - 1) == 0) {
861 // The other process is shutting down, it's safe to start a new process.
862 return PROCESS_NONE;
863 } else if (strncmp(buf, kACKToken, arraysize(kACKToken) - 1) == 0) {
864 #if defined(TOOLKIT_VIEWS) && defined(OS_LINUX) && !defined(OS_CHROMEOS)
865 // Likely NULL in unit tests.
866 views::LinuxUI* linux_ui = views::LinuxUI::instance();
867 if (linux_ui)
868 linux_ui->NotifyWindowManagerStartupComplete();
869 #endif
871 // Assume the other process is handling the request.
872 return PROCESS_NOTIFIED;
875 NOTREACHED() << "The other process returned unknown message: " << buf;
876 return PROCESS_NOTIFIED;
879 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() {
880 return NotifyOtherProcessWithTimeoutOrCreate(
881 *CommandLine::ForCurrentProcess(),
882 kTimeoutInSeconds);
885 ProcessSingleton::NotifyResult
886 ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate(
887 const CommandLine& command_line,
888 int timeout_seconds) {
889 NotifyResult result = NotifyOtherProcessWithTimeout(command_line,
890 timeout_seconds, true);
891 if (result != PROCESS_NONE)
892 return result;
893 if (Create())
894 return PROCESS_NONE;
895 // If the Create() failed, try again to notify. (It could be that another
896 // instance was starting at the same time and managed to grab the lock before
897 // we did.)
898 // This time, we don't want to kill anything if we aren't successful, since we
899 // aren't going to try to take over the lock ourselves.
900 result = NotifyOtherProcessWithTimeout(command_line, timeout_seconds, false);
901 if (result != PROCESS_NONE)
902 return result;
904 return LOCK_ERROR;
907 void ProcessSingleton::OverrideCurrentPidForTesting(base::ProcessId pid) {
908 current_pid_ = pid;
911 void ProcessSingleton::OverrideKillCallbackForTesting(
912 const base::Callback<void(int)>& callback) {
913 kill_callback_ = callback;
916 void ProcessSingleton::DisablePromptForTesting() {
917 g_disable_prompt = true;
920 bool ProcessSingleton::Create() {
921 int sock;
922 sockaddr_un addr;
924 // The symlink lock is pointed to the hostname and process id, so other
925 // processes can find it out.
926 base::FilePath symlink_content(base::StringPrintf(
927 "%s%c%u",
928 net::GetHostName().c_str(),
929 kLockDelimiter,
930 current_pid_));
932 // Create symbol link before binding the socket, to ensure only one instance
933 // can have the socket open.
934 if (!SymlinkPath(symlink_content, lock_path_)) {
935 // TODO(jackhou): Remove this case once this code is stable on Mac.
936 // http://crbug.com/367612
937 #if defined(OS_MACOSX)
938 // On Mac, an existing non-symlink lock file means the lock could be held by
939 // the old process singleton code. If we can successfully replace the lock,
940 // continue as normal.
941 if (base::IsLink(lock_path_) ||
942 !ReplaceOldSingletonLock(symlink_content, lock_path_)) {
943 return false;
945 #else
946 // If we failed to create the lock, most likely another instance won the
947 // startup race.
948 return false;
949 #endif
952 // Create the socket file somewhere in /tmp which is usually mounted as a
953 // normal filesystem. Some network filesystems (notably AFS) are screwy and
954 // do not support Unix domain sockets.
955 if (!socket_dir_.CreateUniqueTempDir()) {
956 LOG(ERROR) << "Failed to create socket directory.";
957 return false;
960 // Check that the directory was created with the correct permissions.
961 int dir_mode = 0;
962 CHECK(base::GetPosixFilePermissions(socket_dir_.path(), &dir_mode) &&
963 dir_mode == base::FILE_PERMISSION_USER_MASK)
964 << "Temp directory mode is not 700: " << std::oct << dir_mode;
966 // Setup the socket symlink and the two cookies.
967 base::FilePath socket_target_path =
968 socket_dir_.path().Append(chrome::kSingletonSocketFilename);
969 base::FilePath cookie(GenerateCookie());
970 base::FilePath remote_cookie_path =
971 socket_dir_.path().Append(chrome::kSingletonCookieFilename);
972 UnlinkPath(socket_path_);
973 UnlinkPath(cookie_path_);
974 if (!SymlinkPath(socket_target_path, socket_path_) ||
975 !SymlinkPath(cookie, cookie_path_) ||
976 !SymlinkPath(cookie, remote_cookie_path)) {
977 // We've already locked things, so we can't have lost the startup race,
978 // but something doesn't like us.
979 LOG(ERROR) << "Failed to create symlinks.";
980 if (!socket_dir_.Delete())
981 LOG(ERROR) << "Encountered a problem when deleting socket directory.";
982 return false;
985 SetupSocket(socket_target_path.value(), &sock, &addr);
987 if (bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
988 PLOG(ERROR) << "Failed to bind() " << socket_target_path.value();
989 CloseSocket(sock);
990 return false;
993 if (listen(sock, 5) < 0)
994 NOTREACHED() << "listen failed: " << safe_strerror(errno);
996 DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::IO));
997 BrowserThread::PostTask(
998 BrowserThread::IO,
999 FROM_HERE,
1000 base::Bind(&ProcessSingleton::LinuxWatcher::StartListening,
1001 watcher_.get(),
1002 sock));
1004 return true;
1007 void ProcessSingleton::Cleanup() {
1008 UnlinkPath(socket_path_);
1009 UnlinkPath(cookie_path_);
1010 UnlinkPath(lock_path_);
1013 bool ProcessSingleton::IsSameChromeInstance(pid_t pid) {
1014 pid_t cur_pid = current_pid_;
1015 while (pid != cur_pid) {
1016 pid = base::GetParentProcessId(pid);
1017 if (pid < 0)
1018 return false;
1019 if (!IsChromeProcess(pid))
1020 return false;
1022 return true;
1025 bool ProcessSingleton::KillProcessByLockPath() {
1026 std::string hostname;
1027 int pid;
1028 ParseLockPath(lock_path_, &hostname, &pid);
1030 if (!hostname.empty() && hostname != net::GetHostName()) {
1031 return DisplayProfileInUseError(lock_path_, hostname, pid);
1033 UnlinkPath(lock_path_);
1035 if (IsSameChromeInstance(pid))
1036 return true;
1038 if (pid > 0) {
1039 kill_callback_.Run(pid);
1040 return true;
1043 LOG(ERROR) << "Failed to extract pid from path: " << lock_path_.value();
1044 return true;
1047 void ProcessSingleton::KillProcess(int pid) {
1048 // TODO(james.su@gmail.com): Is SIGKILL ok?
1049 int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL);
1050 // ESRCH = No Such Process (can happen if the other process is already in
1051 // progress of shutting down and finishes before we try to kill it).
1052 DCHECK(rv == 0 || errno == ESRCH) << "Error killing process: "
1053 << safe_strerror(errno);