• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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.
4 
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.
10 //
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.
20 //
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.
26 //
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.
32 //
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.
39 //
40 // TODO(james.su@gmail.com): Add unittest for this class.
41 
42 #include "chrome/browser/process_singleton.h"
43 
44 #include <errno.h>
45 #include <fcntl.h>
46 #include <gdk/gdk.h>
47 #include <signal.h>
48 #include <sys/socket.h>
49 #include <sys/stat.h>
50 #include <sys/types.h>
51 #include <sys/un.h>
52 #include <unistd.h>
53 
54 #include <cstring>
55 #include <set>
56 #include <string>
57 
58 #include "base/base_paths.h"
59 #include "base/basictypes.h"
60 #include "base/command_line.h"
61 #include "base/eintr_wrapper.h"
62 #include "base/file_path.h"
63 #include "base/file_util.h"
64 #include "base/logging.h"
65 #include "base/message_loop.h"
66 #include "base/path_service.h"
67 #include "base/process_util.h"
68 #include "base/rand_util.h"
69 #include "base/safe_strerror_posix.h"
70 #include "base/stl_util-inl.h"
71 #include "base/string_number_conversions.h"
72 #include "base/string_split.h"
73 #include "base/sys_string_conversions.h"
74 #include "base/threading/platform_thread.h"
75 #include "base/time.h"
76 #include "base/timer.h"
77 #include "base/utf_string_conversions.h"
78 #include "chrome/browser/browser_process.h"
79 #if defined(TOOLKIT_GTK)
80 #include "chrome/browser/ui/gtk/process_singleton_dialog.h"
81 #endif
82 #include "chrome/browser/io_thread.h"
83 #include "chrome/browser/profiles/profile.h"
84 #include "chrome/browser/profiles/profile_manager.h"
85 #include "chrome/browser/ui/browser_init.h"
86 #include "chrome/common/chrome_constants.h"
87 #include "chrome/common/chrome_paths.h"
88 #include "chrome/common/chrome_switches.h"
89 #include "content/browser/browser_thread.h"
90 #include "grit/chromium_strings.h"
91 #include "grit/generated_resources.h"
92 #include "net/base/net_util.h"
93 #include "ui/base/l10n/l10n_util.h"
94 
95 const int ProcessSingleton::kTimeoutInSeconds;
96 
97 namespace {
98 
99 const char kStartToken[] = "START";
100 const char kACKToken[] = "ACK";
101 const char kShutdownToken[] = "SHUTDOWN";
102 const char kTokenDelimiter = '\0';
103 const int kMaxMessageLength = 32 * 1024;
104 const int kMaxACKMessageLength = arraysize(kShutdownToken) - 1;
105 
106 const char kLockDelimiter = '-';
107 
108 // Set a file descriptor to be non-blocking.
109 // Return 0 on success, -1 on failure.
SetNonBlocking(int fd)110 int SetNonBlocking(int fd) {
111   int flags = fcntl(fd, F_GETFL, 0);
112   if (-1 == flags)
113     return flags;
114   if (flags & O_NONBLOCK)
115     return 0;
116   return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
117 }
118 
119 // Set the close-on-exec bit on a file descriptor.
120 // Returns 0 on success, -1 on failure.
SetCloseOnExec(int fd)121 int SetCloseOnExec(int fd) {
122   int flags = fcntl(fd, F_GETFD, 0);
123   if (-1 == flags)
124     return flags;
125   if (flags & FD_CLOEXEC)
126     return 0;
127   return fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
128 }
129 
130 // Close a socket and check return value.
CloseSocket(int fd)131 void CloseSocket(int fd) {
132   int rv = HANDLE_EINTR(close(fd));
133   DCHECK_EQ(0, rv) << "Error closing socket: " << safe_strerror(errno);
134 }
135 
136 // Write a message to a socket fd.
WriteToSocket(int fd,const char * message,size_t length)137 bool WriteToSocket(int fd, const char *message, size_t length) {
138   DCHECK(message);
139   DCHECK(length);
140   size_t bytes_written = 0;
141   do {
142     ssize_t rv = HANDLE_EINTR(
143         write(fd, message + bytes_written, length - bytes_written));
144     if (rv < 0) {
145       if (errno == EAGAIN || errno == EWOULDBLOCK) {
146         // The socket shouldn't block, we're sending so little data.  Just give
147         // up here, since NotifyOtherProcess() doesn't have an asynchronous api.
148         LOG(ERROR) << "ProcessSingleton would block on write(), so it gave up.";
149         return false;
150       }
151       PLOG(ERROR) << "write() failed";
152       return false;
153     }
154     bytes_written += rv;
155   } while (bytes_written < length);
156 
157   return true;
158 }
159 
160 // Wait a socket for read for a certain timeout in seconds.
161 // Returns -1 if error occurred, 0 if timeout reached, > 0 if the socket is
162 // ready for read.
WaitSocketForRead(int fd,int timeout)163 int WaitSocketForRead(int fd, int timeout) {
164   fd_set read_fds;
165   struct timeval tv;
166 
167   FD_ZERO(&read_fds);
168   FD_SET(fd, &read_fds);
169   tv.tv_sec = timeout;
170   tv.tv_usec = 0;
171 
172   return HANDLE_EINTR(select(fd + 1, &read_fds, NULL, NULL, &tv));
173 }
174 
175 // Read a message from a socket fd, with an optional timeout in seconds.
176 // If |timeout| <= 0 then read immediately.
177 // Return number of bytes actually read, or -1 on error.
ReadFromSocket(int fd,char * buf,size_t bufsize,int timeout)178 ssize_t ReadFromSocket(int fd, char *buf, size_t bufsize, int timeout) {
179   if (timeout > 0) {
180     int rv = WaitSocketForRead(fd, timeout);
181     if (rv <= 0)
182       return rv;
183   }
184 
185   size_t bytes_read = 0;
186   do {
187     ssize_t rv = HANDLE_EINTR(read(fd, buf + bytes_read, bufsize - bytes_read));
188     if (rv < 0) {
189       if (errno != EAGAIN && errno != EWOULDBLOCK) {
190         PLOG(ERROR) << "read() failed";
191         return rv;
192       } else {
193         // It would block, so we just return what has been read.
194         return bytes_read;
195       }
196     } else if (!rv) {
197       // No more data to read.
198       return bytes_read;
199     } else {
200       bytes_read += rv;
201     }
202   } while (bytes_read < bufsize);
203 
204   return bytes_read;
205 }
206 
207 // Set up a sockaddr appropriate for messaging.
SetupSockAddr(const std::string & path,struct sockaddr_un * addr)208 void SetupSockAddr(const std::string& path, struct sockaddr_un* addr) {
209   addr->sun_family = AF_UNIX;
210   CHECK(path.length() < arraysize(addr->sun_path))
211       << "Socket path too long: " << path;
212   base::strlcpy(addr->sun_path, path.c_str(), arraysize(addr->sun_path));
213 }
214 
215 // Set up a socket appropriate for messaging.
SetupSocketOnly()216 int SetupSocketOnly() {
217   int sock = socket(PF_UNIX, SOCK_STREAM, 0);
218   PCHECK(sock >= 0) << "socket() failed";
219 
220   int rv = SetNonBlocking(sock);
221   DCHECK_EQ(0, rv) << "Failed to make non-blocking socket.";
222   rv = SetCloseOnExec(sock);
223   DCHECK_EQ(0, rv) << "Failed to set CLOEXEC on socket.";
224 
225   return sock;
226 }
227 
228 // Set up a socket and sockaddr appropriate for messaging.
SetupSocket(const std::string & path,int * sock,struct sockaddr_un * addr)229 void SetupSocket(const std::string& path, int* sock, struct sockaddr_un* addr) {
230   *sock = SetupSocketOnly();
231   SetupSockAddr(path, addr);
232 }
233 
234 // Read a symbolic link, return empty string if given path is not a symbol link.
ReadLink(const FilePath & path)235 FilePath ReadLink(const FilePath& path) {
236   FilePath target;
237   if (!file_util::ReadSymbolicLink(path, &target)) {
238     // The only errno that should occur is ENOENT.
239     if (errno != 0 && errno != ENOENT)
240       PLOG(ERROR) << "readlink(" << path.value() << ") failed";
241   }
242   return target;
243 }
244 
245 // Unlink a path. Return true on success.
UnlinkPath(const FilePath & path)246 bool UnlinkPath(const FilePath& path) {
247   int rv = unlink(path.value().c_str());
248   if (rv < 0 && errno != ENOENT)
249     PLOG(ERROR) << "Failed to unlink " << path.value();
250 
251   return rv == 0;
252 }
253 
254 // Create a symlink. Returns true on success.
SymlinkPath(const FilePath & target,const FilePath & path)255 bool SymlinkPath(const FilePath& target, const FilePath& path) {
256   if (!file_util::CreateSymbolicLink(target, path)) {
257     // Double check the value in case symlink suceeded but we got an incorrect
258     // failure due to NFS packet loss & retry.
259     int saved_errno = errno;
260     if (ReadLink(path) != target) {
261       // If we failed to create the lock, most likely another instance won the
262       // startup race.
263       errno = saved_errno;
264       PLOG(ERROR) << "Failed to create " << path.value();
265       return false;
266     }
267   }
268   return true;
269 }
270 
271 // Extract the hostname and pid from the lock symlink.
272 // Returns true if the lock existed.
ParseLockPath(const FilePath & path,std::string * hostname,int * pid)273 bool ParseLockPath(const FilePath& path,
274                    std::string* hostname,
275                    int* pid) {
276   std::string real_path = ReadLink(path).value();
277   if (real_path.empty())
278     return false;
279 
280   std::string::size_type pos = real_path.rfind(kLockDelimiter);
281 
282   // If the path is not a symbolic link, or doesn't contain what we expect,
283   // bail.
284   if (pos == std::string::npos) {
285     *hostname = "";
286     *pid = -1;
287     return true;
288   }
289 
290   *hostname = real_path.substr(0, pos);
291 
292   const std::string& pid_str = real_path.substr(pos + 1);
293   if (!base::StringToInt(pid_str, pid))
294     *pid = -1;
295 
296   return true;
297 }
298 
DisplayProfileInUseError(const std::string & lock_path,const std::string & hostname,int pid)299 void DisplayProfileInUseError(const std::string& lock_path,
300                               const std::string& hostname,
301                               int pid) {
302   string16 error = l10n_util::GetStringFUTF16(
303       IDS_PROFILE_IN_USE_LINUX,
304       base::IntToString16(pid),
305       ASCIIToUTF16(hostname),
306       WideToUTF16(base::SysNativeMBToWide(lock_path)),
307       l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
308   LOG(ERROR) << base::SysWideToNativeMB(UTF16ToWide(error)).c_str();
309 #if defined(TOOLKIT_GTK)
310   if (!CommandLine::ForCurrentProcess()->HasSwitch(
311       switches::kNoProcessSingletonDialog))
312     ProcessSingletonDialog::ShowAndRun(UTF16ToUTF8(error));
313 #endif
314 }
315 
IsChromeProcess(pid_t pid)316 bool IsChromeProcess(pid_t pid) {
317   FilePath other_chrome_path(base::GetProcessExecutablePath(pid));
318   return (!other_chrome_path.empty() &&
319           other_chrome_path.BaseName() ==
320           FilePath(chrome::kBrowserProcessExecutableName));
321 }
322 
323 // Return true if the given pid is one of our child processes.
324 // Assumes that the current pid is the root of all pids of the current instance.
IsSameChromeInstance(pid_t pid)325 bool IsSameChromeInstance(pid_t pid) {
326   pid_t cur_pid = base::GetCurrentProcId();
327   while (pid != cur_pid) {
328     pid = base::GetParentProcessId(pid);
329     if (pid < 0)
330       return false;
331     if (!IsChromeProcess(pid))
332       return false;
333   }
334   return true;
335 }
336 
337 // Extract the process's pid from a symbol link path and if it is on
338 // the same host, kill the process, unlink the lock file and return true.
339 // If the process is part of the same chrome instance, unlink the lock file and
340 // return true without killing it.
341 // If the process is on a different host, return false.
KillProcessByLockPath(const FilePath & path)342 bool KillProcessByLockPath(const FilePath& path) {
343   std::string hostname;
344   int pid;
345   ParseLockPath(path, &hostname, &pid);
346 
347   if (!hostname.empty() && hostname != net::GetHostName()) {
348     DisplayProfileInUseError(path.value(), hostname, pid);
349     return false;
350   }
351   UnlinkPath(path);
352 
353   if (IsSameChromeInstance(pid))
354     return true;
355 
356   if (pid > 0) {
357     // TODO(james.su@gmail.com): Is SIGKILL ok?
358     int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL);
359     // ESRCH = No Such Process (can happen if the other process is already in
360     // progress of shutting down and finishes before we try to kill it).
361     DCHECK(rv == 0 || errno == ESRCH) << "Error killing process: "
362                                       << safe_strerror(errno);
363     return true;
364   }
365 
366   LOG(ERROR) << "Failed to extract pid from path: " << path.value();
367   return true;
368 }
369 
370 // A helper class to hold onto a socket.
371 class ScopedSocket {
372  public:
ScopedSocket()373   ScopedSocket() : fd_(-1) { Reset(); }
~ScopedSocket()374   ~ScopedSocket() { Close(); }
fd()375   int fd() { return fd_; }
Reset()376   void Reset() {
377     Close();
378     fd_ = SetupSocketOnly();
379   }
Close()380   void Close() {
381     if (fd_ >= 0)
382       CloseSocket(fd_);
383     fd_ = -1;
384   }
385  private:
386   int fd_;
387 };
388 
389 // Returns a random string for uniquifying profile connections.
GenerateCookie()390 std::string GenerateCookie() {
391   return base::Uint64ToString(base::RandUint64());
392 }
393 
CheckCookie(const FilePath & path,const FilePath & cookie)394 bool CheckCookie(const FilePath& path, const FilePath& cookie) {
395   return (cookie == ReadLink(path));
396 }
397 
ConnectSocket(ScopedSocket * socket,const FilePath & socket_path,const FilePath & cookie_path)398 bool ConnectSocket(ScopedSocket* socket,
399                    const FilePath& socket_path,
400                    const FilePath& cookie_path) {
401   FilePath socket_target;
402   if (file_util::ReadSymbolicLink(socket_path, &socket_target)) {
403     // It's a symlink. Read the cookie.
404     FilePath cookie = ReadLink(cookie_path);
405     if (cookie.empty())
406       return false;
407     FilePath remote_cookie = socket_target.DirName().
408                              Append(chrome::kSingletonCookieFilename);
409     // Verify the cookie before connecting.
410     if (!CheckCookie(remote_cookie, cookie))
411       return false;
412     // Now we know the directory was (at that point) created by the profile
413     // owner. Try to connect.
414     sockaddr_un addr;
415     SetupSockAddr(socket_path.value(), &addr);
416     int ret = HANDLE_EINTR(connect(socket->fd(),
417                                    reinterpret_cast<sockaddr*>(&addr),
418                                    sizeof(addr)));
419     if (ret != 0)
420       return false;
421     // Check the cookie again. We only link in /tmp, which is sticky, so, if the
422     // directory is still correct, it must have been correct in-between when we
423     // connected. POSIX, sadly, lacks a connectat().
424     if (!CheckCookie(remote_cookie, cookie)) {
425       socket->Reset();
426       return false;
427     }
428     // Success!
429     return true;
430   } else if (errno == EINVAL) {
431     // It exists, but is not a symlink (or some other error we detect
432     // later). Just connect to it directly; this is an older version of Chrome.
433     sockaddr_un addr;
434     SetupSockAddr(socket_path.value(), &addr);
435     int ret = HANDLE_EINTR(connect(socket->fd(),
436                                    reinterpret_cast<sockaddr*>(&addr),
437                                    sizeof(addr)));
438     return (ret == 0);
439   } else {
440     // File is missing, or other error.
441     if (errno != ENOENT)
442       PLOG(ERROR) << "readlink failed";
443     return false;
444   }
445 }
446 
447 }  // namespace
448 
449 ///////////////////////////////////////////////////////////////////////////////
450 // ProcessSingleton::LinuxWatcher
451 // A helper class for a Linux specific implementation of the process singleton.
452 // This class sets up a listener on the singleton socket and handles parsing
453 // messages that come in on the singleton socket.
454 class ProcessSingleton::LinuxWatcher
455     : public MessageLoopForIO::Watcher,
456       public MessageLoop::DestructionObserver,
457       public base::RefCountedThreadSafe<ProcessSingleton::LinuxWatcher> {
458  public:
459   // A helper class to read message from an established socket.
460   class SocketReader : public MessageLoopForIO::Watcher {
461    public:
SocketReader(ProcessSingleton::LinuxWatcher * parent,MessageLoop * ui_message_loop,int fd)462     SocketReader(ProcessSingleton::LinuxWatcher* parent,
463                  MessageLoop* ui_message_loop,
464                  int fd)
465         : parent_(parent),
466           ui_message_loop_(ui_message_loop),
467           fd_(fd),
468           bytes_read_(0) {
469       // Wait for reads.
470       MessageLoopForIO::current()->WatchFileDescriptor(
471           fd, true, MessageLoopForIO::WATCH_READ, &fd_reader_, this);
472       timer_.Start(base::TimeDelta::FromSeconds(kTimeoutInSeconds),
473                    this, &SocketReader::OnTimerExpiry);
474     }
475 
~SocketReader()476     virtual ~SocketReader() {
477       CloseSocket(fd_);
478     }
479 
480     // MessageLoopForIO::Watcher impl.
481     virtual void OnFileCanReadWithoutBlocking(int fd);
OnFileCanWriteWithoutBlocking(int fd)482     virtual void OnFileCanWriteWithoutBlocking(int fd) {
483       // SocketReader only watches for accept (read) events.
484       NOTREACHED();
485     }
486 
487     // Finish handling the incoming message by optionally sending back an ACK
488     // message and removing this SocketReader.
489     void FinishWithACK(const char *message, size_t length);
490 
491    private:
492     // If we haven't completed in a reasonable amount of time, give up.
OnTimerExpiry()493     void OnTimerExpiry() {
494       parent_->RemoveSocketReader(this);
495       // We're deleted beyond this point.
496     }
497 
498     MessageLoopForIO::FileDescriptorWatcher fd_reader_;
499 
500     // The ProcessSingleton::LinuxWatcher that owns us.
501     ProcessSingleton::LinuxWatcher* const parent_;
502 
503     // A reference to the UI message loop.
504     MessageLoop* const ui_message_loop_;
505 
506     // The file descriptor we're reading.
507     const int fd_;
508 
509     // Store the message in this buffer.
510     char buf_[kMaxMessageLength];
511 
512     // Tracks the number of bytes we've read in case we're getting partial
513     // reads.
514     size_t bytes_read_;
515 
516     base::OneShotTimer<SocketReader> timer_;
517 
518     DISALLOW_COPY_AND_ASSIGN(SocketReader);
519   };
520 
521   // We expect to only be constructed on the UI thread.
LinuxWatcher(ProcessSingleton * parent)522   explicit LinuxWatcher(ProcessSingleton* parent)
523       : ui_message_loop_(MessageLoop::current()),
524         parent_(parent) {
525   }
526 
527   // Start listening for connections on the socket.  This method should be
528   // called from the IO thread.
529   void StartListening(int socket);
530 
531   // This method determines if we should use the same process and if we should,
532   // opens a new browser tab.  This runs on the UI thread.
533   // |reader| is for sending back ACK message.
534   void HandleMessage(const std::string& current_dir,
535                      const std::vector<std::string>& argv,
536                      SocketReader *reader);
537 
538   // MessageLoopForIO::Watcher impl.  These run on the IO thread.
539   virtual void OnFileCanReadWithoutBlocking(int fd);
OnFileCanWriteWithoutBlocking(int fd)540   virtual void OnFileCanWriteWithoutBlocking(int fd) {
541     // ProcessSingleton only watches for accept (read) events.
542     NOTREACHED();
543   }
544 
545   // MessageLoop::DestructionObserver
WillDestroyCurrentMessageLoop()546   virtual void WillDestroyCurrentMessageLoop() {
547     fd_watcher_.StopWatchingFileDescriptor();
548   }
549 
550  private:
551   friend class base::RefCountedThreadSafe<ProcessSingleton::LinuxWatcher>;
552 
~LinuxWatcher()553   virtual ~LinuxWatcher() {
554     STLDeleteElements(&readers_);
555   }
556 
557   // Removes and deletes the SocketReader.
558   void RemoveSocketReader(SocketReader* reader);
559 
560   MessageLoopForIO::FileDescriptorWatcher fd_watcher_;
561 
562   // A reference to the UI message loop (i.e., the message loop we were
563   // constructed on).
564   MessageLoop* ui_message_loop_;
565 
566   // The ProcessSingleton that owns us.
567   ProcessSingleton* const parent_;
568 
569   std::set<SocketReader*> readers_;
570 
571   DISALLOW_COPY_AND_ASSIGN(LinuxWatcher);
572 };
573 
OnFileCanReadWithoutBlocking(int fd)574 void ProcessSingleton::LinuxWatcher::OnFileCanReadWithoutBlocking(int fd) {
575   // Accepting incoming client.
576   sockaddr_un from;
577   socklen_t from_len = sizeof(from);
578   int connection_socket = HANDLE_EINTR(accept(
579       fd, reinterpret_cast<sockaddr*>(&from), &from_len));
580   if (-1 == connection_socket) {
581     PLOG(ERROR) << "accept() failed";
582     return;
583   }
584   int rv = SetNonBlocking(connection_socket);
585   DCHECK_EQ(0, rv) << "Failed to make non-blocking socket.";
586   SocketReader* reader = new SocketReader(this,
587                                           ui_message_loop_,
588                                           connection_socket);
589   readers_.insert(reader);
590 }
591 
StartListening(int socket)592 void ProcessSingleton::LinuxWatcher::StartListening(int socket) {
593   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
594   // Watch for client connections on this socket.
595   MessageLoopForIO* ml = MessageLoopForIO::current();
596   ml->AddDestructionObserver(this);
597   ml->WatchFileDescriptor(socket, true, MessageLoopForIO::WATCH_READ,
598                           &fd_watcher_, this);
599 }
600 
HandleMessage(const std::string & current_dir,const std::vector<std::string> & argv,SocketReader * reader)601 void ProcessSingleton::LinuxWatcher::HandleMessage(
602     const std::string& current_dir, const std::vector<std::string>& argv,
603     SocketReader* reader) {
604   DCHECK(ui_message_loop_ == MessageLoop::current());
605   DCHECK(reader);
606   // If locked, it means we are not ready to process this message because
607   // we are probably in a first run critical phase.
608   if (parent_->locked()) {
609     DLOG(WARNING) << "Browser is locked";
610     // Send back "ACK" message to prevent the client process from starting up.
611     reader->FinishWithACK(kACKToken, arraysize(kACKToken) - 1);
612     return;
613   }
614 
615   // Ignore the request if the browser process is already in shutdown path.
616   if (!g_browser_process || g_browser_process->IsShuttingDown()) {
617     LOG(WARNING) << "Not handling interprocess notification as browser"
618                     " is shutting down";
619     // Send back "SHUTDOWN" message, so that the client process can start up
620     // without killing this process.
621     reader->FinishWithACK(kShutdownToken, arraysize(kShutdownToken) - 1);
622     return;
623   }
624 
625   CommandLine parsed_command_line(argv);
626   PrefService* prefs = g_browser_process->local_state();
627   DCHECK(prefs);
628 
629   Profile* profile = ProfileManager::GetDefaultProfile();
630 
631   if (!profile) {
632     // We should only be able to get here if the profile already exists and
633     // has been created.
634     NOTREACHED();
635     return;
636   }
637 
638   // Ignore the request if the process was passed the --product-version flag.
639   // Normally we wouldn't get here if that flag had been passed, but it can
640   // happen if it is passed to an older version of chrome. Since newer versions
641   // of chrome do this in the background, we want to avoid spawning extra
642   // windows.
643   if (parsed_command_line.HasSwitch(switches::kProductVersion)) {
644     DLOG(WARNING) << "Remote process was passed product version flag, "
645                   << "but ignored it. Doing nothing.";
646   } else {
647     // Run the browser startup sequence again, with the command line of the
648     // signalling process.
649     FilePath current_dir_file_path(current_dir);
650     BrowserInit::ProcessCommandLine(parsed_command_line, current_dir_file_path,
651                                     false /* not process startup */, profile,
652                                     NULL);
653   }
654 
655   // Send back "ACK" message to prevent the client process from starting up.
656   reader->FinishWithACK(kACKToken, arraysize(kACKToken) - 1);
657 }
658 
RemoveSocketReader(SocketReader * reader)659 void ProcessSingleton::LinuxWatcher::RemoveSocketReader(SocketReader* reader) {
660   DCHECK(reader);
661   readers_.erase(reader);
662   delete reader;
663 }
664 
665 ///////////////////////////////////////////////////////////////////////////////
666 // ProcessSingleton::LinuxWatcher::SocketReader
667 //
668 
OnFileCanReadWithoutBlocking(int fd)669 void ProcessSingleton::LinuxWatcher::SocketReader::OnFileCanReadWithoutBlocking(
670     int fd) {
671   DCHECK_EQ(fd, fd_);
672   while (bytes_read_ < sizeof(buf_)) {
673     ssize_t rv = HANDLE_EINTR(
674         read(fd, buf_ + bytes_read_, sizeof(buf_) - bytes_read_));
675     if (rv < 0) {
676       if (errno != EAGAIN && errno != EWOULDBLOCK) {
677         PLOG(ERROR) << "read() failed";
678         CloseSocket(fd);
679         return;
680       } else {
681         // It would block, so we just return and continue to watch for the next
682         // opportunity to read.
683         return;
684       }
685     } else if (!rv) {
686       // No more data to read.  It's time to process the message.
687       break;
688     } else {
689       bytes_read_ += rv;
690     }
691   }
692 
693   // Validate the message.  The shortest message is kStartToken\0x\0x
694   const size_t kMinMessageLength = arraysize(kStartToken) + 4;
695   if (bytes_read_ < kMinMessageLength) {
696     buf_[bytes_read_] = 0;
697     LOG(ERROR) << "Invalid socket message (wrong length):" << buf_;
698     return;
699   }
700 
701   std::string str(buf_, bytes_read_);
702   std::vector<std::string> tokens;
703   base::SplitString(str, kTokenDelimiter, &tokens);
704 
705   if (tokens.size() < 3 || tokens[0] != kStartToken) {
706     LOG(ERROR) << "Wrong message format: " << str;
707     return;
708   }
709 
710   // Stop the expiration timer to prevent this SocketReader object from being
711   // terminated unexpectly.
712   timer_.Stop();
713 
714   std::string current_dir = tokens[1];
715   // Remove the first two tokens.  The remaining tokens should be the command
716   // line argv array.
717   tokens.erase(tokens.begin());
718   tokens.erase(tokens.begin());
719 
720   // Return to the UI thread to handle opening a new browser tab.
721   ui_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
722       parent_,
723       &ProcessSingleton::LinuxWatcher::HandleMessage,
724       current_dir,
725       tokens,
726       this));
727   fd_reader_.StopWatchingFileDescriptor();
728 
729   // LinuxWatcher::HandleMessage() is in charge of destroying this SocketReader
730   // object by invoking SocketReader::FinishWithACK().
731 }
732 
FinishWithACK(const char * message,size_t length)733 void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
734     const char *message, size_t length) {
735   if (message && length) {
736     // Not necessary to care about the return value.
737     WriteToSocket(fd_, message, length);
738   }
739 
740   if (shutdown(fd_, SHUT_WR) < 0)
741     PLOG(ERROR) << "shutdown() failed";
742 
743   parent_->RemoveSocketReader(this);
744   // We are deleted beyond this point.
745 }
746 
747 ///////////////////////////////////////////////////////////////////////////////
748 // ProcessSingleton
749 //
ProcessSingleton(const FilePath & user_data_dir)750 ProcessSingleton::ProcessSingleton(const FilePath& user_data_dir)
751     : locked_(false),
752       foreground_window_(NULL),
753       ALLOW_THIS_IN_INITIALIZER_LIST(watcher_(new LinuxWatcher(this))) {
754   socket_path_ = user_data_dir.Append(chrome::kSingletonSocketFilename);
755   lock_path_ = user_data_dir.Append(chrome::kSingletonLockFilename);
756   cookie_path_ = user_data_dir.Append(chrome::kSingletonCookieFilename);
757 }
758 
~ProcessSingleton()759 ProcessSingleton::~ProcessSingleton() {
760 }
761 
NotifyOtherProcess()762 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
763   return NotifyOtherProcessWithTimeout(*CommandLine::ForCurrentProcess(),
764                                        kTimeoutInSeconds,
765                                        true);
766 }
767 
NotifyOtherProcessWithTimeout(const CommandLine & cmd_line,int timeout_seconds,bool kill_unresponsive)768 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
769     const CommandLine& cmd_line,
770     int timeout_seconds,
771     bool kill_unresponsive) {
772   DCHECK_GE(timeout_seconds, 0);
773 
774   ScopedSocket socket;
775   for (int retries = 0; retries <= timeout_seconds; ++retries) {
776     // Try to connect to the socket.
777     if (ConnectSocket(&socket, socket_path_, cookie_path_))
778       break;
779 
780     // If we're in a race with another process, they may be in Create() and have
781     // created the lock but not attached to the socket.  So we check if the
782     // process with the pid from the lockfile is currently running and is a
783     // chrome browser.  If so, we loop and try again for |timeout_seconds|.
784 
785     std::string hostname;
786     int pid;
787     if (!ParseLockPath(lock_path_, &hostname, &pid)) {
788       // No lockfile exists.
789       return PROCESS_NONE;
790     }
791 
792     if (hostname.empty()) {
793       // Invalid lockfile.
794       UnlinkPath(lock_path_);
795       return PROCESS_NONE;
796     }
797 
798     if (hostname != net::GetHostName()) {
799       // Locked by process on another host.
800       DisplayProfileInUseError(lock_path_.value(), hostname, pid);
801       return PROFILE_IN_USE;
802     }
803 
804     if (!IsChromeProcess(pid)) {
805       // Orphaned lockfile (no process with pid, or non-chrome process.)
806       UnlinkPath(lock_path_);
807       return PROCESS_NONE;
808     }
809 
810     if (IsSameChromeInstance(pid)) {
811       // Orphaned lockfile (pid is part of same chrome instance we are, even
812       // though we haven't tried to create a lockfile yet).
813       UnlinkPath(lock_path_);
814       return PROCESS_NONE;
815     }
816 
817     if (retries == timeout_seconds) {
818       // Retries failed.  Kill the unresponsive chrome process and continue.
819       if (!kill_unresponsive || !KillProcessByLockPath(lock_path_))
820         return PROFILE_IN_USE;
821       return PROCESS_NONE;
822     }
823 
824     base::PlatformThread::Sleep(1000 /* ms */);
825   }
826 
827   timeval timeout = {timeout_seconds, 0};
828   setsockopt(socket.fd(), SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
829 
830   // Found another process, prepare our command line
831   // format is "START\0<current dir>\0<argv[0]>\0...\0<argv[n]>".
832   std::string to_send(kStartToken);
833   to_send.push_back(kTokenDelimiter);
834 
835   FilePath current_dir;
836   if (!PathService::Get(base::DIR_CURRENT, &current_dir))
837     return PROCESS_NONE;
838   to_send.append(current_dir.value());
839 
840   const std::vector<std::string>& argv = cmd_line.argv();
841   for (std::vector<std::string>::const_iterator it = argv.begin();
842       it != argv.end(); ++it) {
843     to_send.push_back(kTokenDelimiter);
844     to_send.append(*it);
845   }
846 
847   // Send the message
848   if (!WriteToSocket(socket.fd(), to_send.data(), to_send.length())) {
849     // Try to kill the other process, because it might have been dead.
850     if (!kill_unresponsive || !KillProcessByLockPath(lock_path_))
851       return PROFILE_IN_USE;
852     return PROCESS_NONE;
853   }
854 
855   if (shutdown(socket.fd(), SHUT_WR) < 0)
856     PLOG(ERROR) << "shutdown() failed";
857 
858   // Read ACK message from the other process. It might be blocked for a certain
859   // timeout, to make sure the other process has enough time to return ACK.
860   char buf[kMaxACKMessageLength + 1];
861   ssize_t len =
862       ReadFromSocket(socket.fd(), buf, kMaxACKMessageLength, timeout_seconds);
863 
864   // Failed to read ACK, the other process might have been frozen.
865   if (len <= 0) {
866     if (!kill_unresponsive || !KillProcessByLockPath(lock_path_))
867       return PROFILE_IN_USE;
868     return PROCESS_NONE;
869   }
870 
871   buf[len] = '\0';
872   if (strncmp(buf, kShutdownToken, arraysize(kShutdownToken) - 1) == 0) {
873     // The other process is shutting down, it's safe to start a new process.
874     return PROCESS_NONE;
875   } else if (strncmp(buf, kACKToken, arraysize(kACKToken) - 1) == 0) {
876     // Notify the window manager that we've started up; if we do not open a
877     // window, GTK will not automatically call this for us.
878     gdk_notify_startup_complete();
879     // Assume the other process is handling the request.
880     return PROCESS_NOTIFIED;
881   }
882 
883   NOTREACHED() << "The other process returned unknown message: " << buf;
884   return PROCESS_NOTIFIED;
885 }
886 
NotifyOtherProcessOrCreate()887 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() {
888   return NotifyOtherProcessWithTimeoutOrCreate(
889       *CommandLine::ForCurrentProcess(),
890       kTimeoutInSeconds);
891 }
892 
893 ProcessSingleton::NotifyResult
NotifyOtherProcessWithTimeoutOrCreate(const CommandLine & command_line,int timeout_seconds)894 ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate(
895     const CommandLine& command_line,
896     int timeout_seconds) {
897   NotifyResult result = NotifyOtherProcessWithTimeout(command_line,
898                                                       timeout_seconds, true);
899   if (result != PROCESS_NONE)
900     return result;
901   if (Create())
902     return PROCESS_NONE;
903   // If the Create() failed, try again to notify. (It could be that another
904   // instance was starting at the same time and managed to grab the lock before
905   // we did.)
906   // This time, we don't want to kill anything if we aren't successful, since we
907   // aren't going to try to take over the lock ourselves.
908   result = NotifyOtherProcessWithTimeout(command_line, timeout_seconds, false);
909   if (result != PROCESS_NONE)
910     return result;
911 
912   return LOCK_ERROR;
913 }
914 
Create()915 bool ProcessSingleton::Create() {
916   int sock;
917   sockaddr_un addr;
918 
919   // The symlink lock is pointed to the hostname and process id, so other
920   // processes can find it out.
921   FilePath symlink_content(StringPrintf(
922       "%s%c%u",
923       net::GetHostName().c_str(),
924       kLockDelimiter,
925       base::GetCurrentProcId()));
926 
927   // Create symbol link before binding the socket, to ensure only one instance
928   // can have the socket open.
929   if (!SymlinkPath(symlink_content, lock_path_)) {
930       // If we failed to create the lock, most likely another instance won the
931       // startup race.
932       return false;
933   }
934 
935   // Create the socket file somewhere in /tmp which is usually mounted as a
936   // normal filesystem. Some network filesystems (notably AFS) are screwy and
937   // do not support Unix domain sockets.
938   if (!socket_dir_.CreateUniqueTempDir()) {
939     LOG(ERROR) << "Failed to create socket directory.";
940     return false;
941   }
942   // Setup the socket symlink and the two cookies.
943   FilePath socket_target_path =
944       socket_dir_.path().Append(chrome::kSingletonSocketFilename);
945   FilePath cookie(GenerateCookie());
946   FilePath remote_cookie_path =
947       socket_dir_.path().Append(chrome::kSingletonCookieFilename);
948   UnlinkPath(socket_path_);
949   UnlinkPath(cookie_path_);
950   if (!SymlinkPath(socket_target_path, socket_path_) ||
951       !SymlinkPath(cookie, cookie_path_) ||
952       !SymlinkPath(cookie, remote_cookie_path)) {
953     // We've already locked things, so we can't have lost the startup race,
954     // but something doesn't like us.
955     LOG(ERROR) << "Failed to create symlinks.";
956     if (!socket_dir_.Delete())
957       LOG(ERROR) << "Encountered a problem when deleting socket directory.";
958     return false;
959   }
960 
961   SetupSocket(socket_target_path.value(), &sock, &addr);
962 
963   if (bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
964     PLOG(ERROR) << "Failed to bind() " << socket_target_path.value();
965     CloseSocket(sock);
966     return false;
967   }
968 
969   if (listen(sock, 5) < 0)
970     NOTREACHED() << "listen failed: " << safe_strerror(errno);
971 
972   // Normally we would use BrowserThread, but the IO thread hasn't started yet.
973   // Using g_browser_process, we start the thread so we can listen on the
974   // socket.
975   MessageLoop* ml = g_browser_process->io_thread()->message_loop();
976   DCHECK(ml);
977   ml->PostTask(FROM_HERE, NewRunnableMethod(
978     watcher_.get(),
979     &ProcessSingleton::LinuxWatcher::StartListening,
980     sock));
981 
982   return true;
983 }
984 
Cleanup()985 void ProcessSingleton::Cleanup() {
986   UnlinkPath(socket_path_);
987   UnlinkPath(cookie_path_);
988   UnlinkPath(lock_path_);
989 }
990