OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // On Linux, when the user tries to launch a second copy of chrome, we check | 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 | 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 | 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 | 8 // directory and second process command line flags. The second process then |
9 // exits. | 9 // exits. |
10 // | 10 // |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 #include <cstring> | 53 #include <cstring> |
54 #include <set> | 54 #include <set> |
55 #include <string> | 55 #include <string> |
56 | 56 |
57 #include "app/l10n_util.h" | 57 #include "app/l10n_util.h" |
58 #include "base/base_paths.h" | 58 #include "base/base_paths.h" |
59 #include "base/basictypes.h" | 59 #include "base/basictypes.h" |
60 #include "base/command_line.h" | 60 #include "base/command_line.h" |
61 #include "base/eintr_wrapper.h" | 61 #include "base/eintr_wrapper.h" |
62 #include "base/file_path.h" | 62 #include "base/file_path.h" |
| 63 #include "base/file_util.h" |
63 #include "base/logging.h" | 64 #include "base/logging.h" |
64 #include "base/message_loop.h" | 65 #include "base/message_loop.h" |
65 #include "base/path_service.h" | 66 #include "base/path_service.h" |
66 #include "base/platform_thread.h" | 67 #include "base/platform_thread.h" |
67 #include "base/process_util.h" | 68 #include "base/process_util.h" |
68 #include "base/rand_util.h" | 69 #include "base/rand_util.h" |
69 #include "base/safe_strerror_posix.h" | 70 #include "base/safe_strerror_posix.h" |
70 #include "base/stl_util-inl.h" | 71 #include "base/stl_util-inl.h" |
71 #include "base/string_number_conversions.h" | 72 #include "base/string_number_conversions.h" |
72 #include "base/string_split.h" | 73 #include "base/string_split.h" |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 | 223 |
223 return sock; | 224 return sock; |
224 } | 225 } |
225 | 226 |
226 // Set up a socket and sockaddr appropriate for messaging. | 227 // Set up a socket and sockaddr appropriate for messaging. |
227 void SetupSocket(const std::string& path, int* sock, struct sockaddr_un* addr) { | 228 void SetupSocket(const std::string& path, int* sock, struct sockaddr_un* addr) { |
228 *sock = SetupSocketOnly(); | 229 *sock = SetupSocketOnly(); |
229 SetupSockAddr(path, addr); | 230 SetupSockAddr(path, addr); |
230 } | 231 } |
231 | 232 |
232 // Read a symbolic link, return empty string if given path is not a | |
233 // symbol link. This version does not interpret the errno, leaving | |
234 // the caller to do so. | |
235 bool ReadLinkSilent(const std::string& path, std::string* output) { | |
236 char buf[PATH_MAX]; | |
237 ssize_t len = readlink(path.c_str(), buf, PATH_MAX); | |
238 if (len >= 0) { | |
239 output->assign(buf, len); | |
240 return true; | |
241 } | |
242 output->clear(); | |
243 return false; | |
244 } | |
245 | |
246 // Read a symbolic link, return empty string if given path is not a symbol link. | 233 // Read a symbolic link, return empty string if given path is not a symbol link. |
247 std::string ReadLink(const std::string& path) { | 234 FilePath ReadLink(const FilePath& path) { |
248 std::string target; | 235 FilePath target; |
249 if (!ReadLinkSilent(path, &target)) { | 236 if (!file_util::ReadSymbolicLink(path, &target)) { |
250 // The only errno that should occur is ENOENT. | 237 // The only errno that should occur is ENOENT. |
251 if (errno != 0 && errno != ENOENT) | 238 if (errno != 0 && errno != ENOENT) |
252 PLOG(ERROR) << "readlink(" << path << ") failed"; | 239 PLOG(ERROR) << "readlink(" << path.value() << ") failed"; |
253 } | 240 } |
254 return target; | 241 return target; |
255 } | 242 } |
256 | 243 |
257 // Unlink a path. Return true on success. | 244 // Unlink a path. Return true on success. |
258 bool UnlinkPath(const std::string& path) { | 245 bool UnlinkPath(const FilePath& path) { |
259 int rv = unlink(path.c_str()); | 246 int rv = unlink(path.value().c_str()); |
260 if (rv < 0 && errno != ENOENT) | 247 if (rv < 0 && errno != ENOENT) |
261 PLOG(ERROR) << "Failed to unlink " << path; | 248 PLOG(ERROR) << "Failed to unlink " << path.value(); |
262 | 249 |
263 return rv == 0; | 250 return rv == 0; |
264 } | 251 } |
265 | 252 |
266 // Create a symlink. Returns true on success. | 253 // Create a symlink. Returns true on success. |
267 bool SymlinkPath(const std::string& target, const std::string& path) { | 254 bool SymlinkPath(const FilePath& target, const FilePath& path) { |
268 if (symlink(target.c_str(), path.c_str()) < 0) { | 255 if (!file_util::CreateSymbolicLink(target, path)) { |
269 // Double check the value in case symlink suceeded but we got an incorrect | 256 // Double check the value in case symlink suceeded but we got an incorrect |
270 // failure due to NFS packet loss & retry. | 257 // failure due to NFS packet loss & retry. |
271 int saved_errno = errno; | 258 int saved_errno = errno; |
272 if (ReadLink(path) != target) { | 259 if (ReadLink(path) != target) { |
273 // If we failed to create the lock, most likely another instance won the | 260 // If we failed to create the lock, most likely another instance won the |
274 // startup race. | 261 // startup race. |
275 errno = saved_errno; | 262 errno = saved_errno; |
276 PLOG(ERROR) << "Failed to create " << path; | 263 PLOG(ERROR) << "Failed to create " << path.value(); |
277 return false; | 264 return false; |
278 } | 265 } |
279 } | 266 } |
280 return true; | 267 return true; |
281 } | 268 } |
282 | 269 |
283 // Extract the hostname and pid from the lock symlink. | 270 // Extract the hostname and pid from the lock symlink. |
284 // Returns true if the lock existed. | 271 // Returns true if the lock existed. |
285 bool ParseLockPath(const std::string& path, | 272 bool ParseLockPath(const FilePath& path, |
286 std::string* hostname, | 273 std::string* hostname, |
287 int* pid) { | 274 int* pid) { |
288 std::string real_path = ReadLink(path); | 275 std::string real_path = ReadLink(path).value(); |
289 if (real_path.empty()) | 276 if (real_path.empty()) |
290 return false; | 277 return false; |
291 | 278 |
292 std::string::size_type pos = real_path.rfind(kLockDelimiter); | 279 std::string::size_type pos = real_path.rfind(kLockDelimiter); |
293 | 280 |
294 // If the path is not a symbolic link, or doesn't contain what we expect, | 281 // If the path is not a symbolic link, or doesn't contain what we expect, |
295 // bail. | 282 // bail. |
296 if (pos == std::string::npos) { | 283 if (pos == std::string::npos) { |
297 *hostname = ""; | 284 *hostname = ""; |
298 *pid = -1; | 285 *pid = -1; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 return false; | 330 return false; |
344 } | 331 } |
345 return true; | 332 return true; |
346 } | 333 } |
347 | 334 |
348 // Extract the process's pid from a symbol link path and if it is on | 335 // Extract the process's pid from a symbol link path and if it is on |
349 // the same host, kill the process, unlink the lock file and return true. | 336 // the same host, kill the process, unlink the lock file and return true. |
350 // If the process is part of the same chrome instance, unlink the lock file and | 337 // If the process is part of the same chrome instance, unlink the lock file and |
351 // return true without killing it. | 338 // return true without killing it. |
352 // If the process is on a different host, return false. | 339 // If the process is on a different host, return false. |
353 bool KillProcessByLockPath(const std::string& path) { | 340 bool KillProcessByLockPath(const FilePath& path) { |
354 std::string hostname; | 341 std::string hostname; |
355 int pid; | 342 int pid; |
356 ParseLockPath(path, &hostname, &pid); | 343 ParseLockPath(path, &hostname, &pid); |
357 | 344 |
358 if (!hostname.empty() && hostname != net::GetHostName()) { | 345 if (!hostname.empty() && hostname != net::GetHostName()) { |
359 DisplayProfileInUseError(path, hostname, pid); | 346 DisplayProfileInUseError(path.value(), hostname, pid); |
360 return false; | 347 return false; |
361 } | 348 } |
362 UnlinkPath(path); | 349 UnlinkPath(path); |
363 | 350 |
364 if (IsSameChromeInstance(pid)) | 351 if (IsSameChromeInstance(pid)) |
365 return true; | 352 return true; |
366 | 353 |
367 if (pid > 0) { | 354 if (pid > 0) { |
368 // TODO(james.su@gmail.com): Is SIGKILL ok? | 355 // TODO(james.su@gmail.com): Is SIGKILL ok? |
369 int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL); | 356 int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL); |
370 // ESRCH = No Such Process (can happen if the other process is already in | 357 // ESRCH = No Such Process (can happen if the other process is already in |
371 // progress of shutting down and finishes before we try to kill it). | 358 // progress of shutting down and finishes before we try to kill it). |
372 DCHECK(rv == 0 || errno == ESRCH) << "Error killing process: " | 359 DCHECK(rv == 0 || errno == ESRCH) << "Error killing process: " |
373 << safe_strerror(errno); | 360 << safe_strerror(errno); |
374 return true; | 361 return true; |
375 } | 362 } |
376 | 363 |
377 LOG(ERROR) << "Failed to extract pid from path: " << path; | 364 LOG(ERROR) << "Failed to extract pid from path: " << path.value(); |
378 return true; | 365 return true; |
379 } | 366 } |
380 | 367 |
381 // A helper class to hold onto a socket. | 368 // A helper class to hold onto a socket. |
382 class ScopedSocket { | 369 class ScopedSocket { |
383 public: | 370 public: |
384 ScopedSocket() : fd_(-1) { Reset(); } | 371 ScopedSocket() : fd_(-1) { Reset(); } |
385 ~ScopedSocket() { Close(); } | 372 ~ScopedSocket() { Close(); } |
386 int fd() { return fd_; } | 373 int fd() { return fd_; } |
387 void Reset() { | 374 void Reset() { |
388 Close(); | 375 Close(); |
389 fd_ = SetupSocketOnly(); | 376 fd_ = SetupSocketOnly(); |
390 } | 377 } |
391 void Close() { | 378 void Close() { |
392 if (fd_ >= 0) | 379 if (fd_ >= 0) |
393 CloseSocket(fd_); | 380 CloseSocket(fd_); |
394 fd_ = -1; | 381 fd_ = -1; |
395 } | 382 } |
396 private: | 383 private: |
397 int fd_; | 384 int fd_; |
398 }; | 385 }; |
399 | 386 |
400 // Returns a random string for uniquifying profile connections. | 387 // Returns a random string for uniquifying profile connections. |
401 std::string GenerateCookie() { | 388 std::string GenerateCookie() { |
402 return base::Uint64ToString(base::RandUint64()); | 389 return base::Uint64ToString(base::RandUint64()); |
403 } | 390 } |
404 | 391 |
405 bool CheckCookie(const FilePath& path, const std::string& cookie) { | 392 bool CheckCookie(const FilePath& path, const FilePath& cookie) { |
406 return (cookie == ReadLink(path.value())); | 393 return (cookie == ReadLink(path)); |
407 } | 394 } |
408 | 395 |
409 bool ConnectSocket(ScopedSocket* socket, | 396 bool ConnectSocket(ScopedSocket* socket, |
410 const FilePath& socket_path, | 397 const FilePath& socket_path, |
411 const FilePath& cookie_path) { | 398 const FilePath& cookie_path) { |
412 std::string socket_target; | 399 FilePath socket_target; |
413 if (ReadLinkSilent(socket_path.value(), &socket_target)) { | 400 if (file_util::ReadSymbolicLink(socket_path, &socket_target)) { |
414 // It's a symlink. Read the cookie. | 401 // It's a symlink. Read the cookie. |
415 std::string cookie = ReadLink(cookie_path.value()); | 402 FilePath cookie = ReadLink(cookie_path); |
416 if (cookie.empty()) | 403 if (cookie.empty()) |
417 return false; | 404 return false; |
418 FilePath remote_cookie = FilePath(socket_target).DirName(). | 405 FilePath remote_cookie = socket_target.DirName(). |
419 Append(chrome::kSingletonCookieFilename); | 406 Append(chrome::kSingletonCookieFilename); |
420 // Verify the cookie before connecting. | 407 // Verify the cookie before connecting. |
421 if (!CheckCookie(remote_cookie, cookie)) | 408 if (!CheckCookie(remote_cookie, cookie)) |
422 return false; | 409 return false; |
423 // Now we know the directory was (at that point) created by the profile | 410 // Now we know the directory was (at that point) created by the profile |
424 // owner. Try to connect. | 411 // owner. Try to connect. |
425 sockaddr_un addr; | 412 sockaddr_un addr; |
426 SetupSockAddr(socket_path.value(), &addr); | 413 SetupSockAddr(socket_path.value(), &addr); |
427 int ret = HANDLE_EINTR(connect(socket->fd(), | 414 int ret = HANDLE_EINTR(connect(socket->fd(), |
428 reinterpret_cast<sockaddr*>(&addr), | 415 reinterpret_cast<sockaddr*>(&addr), |
429 sizeof(addr))); | 416 sizeof(addr))); |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 if (ConnectSocket(&socket, socket_path_, cookie_path_)) | 774 if (ConnectSocket(&socket, socket_path_, cookie_path_)) |
788 break; | 775 break; |
789 | 776 |
790 // If we're in a race with another process, they may be in Create() and have | 777 // If we're in a race with another process, they may be in Create() and have |
791 // created the lock but not attached to the socket. So we check if the | 778 // created the lock but not attached to the socket. So we check if the |
792 // process with the pid from the lockfile is currently running and is a | 779 // process with the pid from the lockfile is currently running and is a |
793 // chrome browser. If so, we loop and try again for |timeout_seconds|. | 780 // chrome browser. If so, we loop and try again for |timeout_seconds|. |
794 | 781 |
795 std::string hostname; | 782 std::string hostname; |
796 int pid; | 783 int pid; |
797 if (!ParseLockPath(lock_path_.value(), &hostname, &pid)) { | 784 if (!ParseLockPath(lock_path_, &hostname, &pid)) { |
798 // No lockfile exists. | 785 // No lockfile exists. |
799 return PROCESS_NONE; | 786 return PROCESS_NONE; |
800 } | 787 } |
801 | 788 |
802 if (hostname.empty()) { | 789 if (hostname.empty()) { |
803 // Invalid lockfile. | 790 // Invalid lockfile. |
804 UnlinkPath(lock_path_.value()); | 791 UnlinkPath(lock_path_); |
805 return PROCESS_NONE; | 792 return PROCESS_NONE; |
806 } | 793 } |
807 | 794 |
808 if (hostname != net::GetHostName()) { | 795 if (hostname != net::GetHostName()) { |
809 // Locked by process on another host. | 796 // Locked by process on another host. |
810 DisplayProfileInUseError(lock_path_.value(), hostname, pid); | 797 DisplayProfileInUseError(lock_path_.value(), hostname, pid); |
811 return PROFILE_IN_USE; | 798 return PROFILE_IN_USE; |
812 } | 799 } |
813 | 800 |
814 if (!IsChromeProcess(pid)) { | 801 if (!IsChromeProcess(pid)) { |
815 // Orphaned lockfile (no process with pid, or non-chrome process.) | 802 // Orphaned lockfile (no process with pid, or non-chrome process.) |
816 UnlinkPath(lock_path_.value()); | 803 UnlinkPath(lock_path_); |
817 return PROCESS_NONE; | 804 return PROCESS_NONE; |
818 } | 805 } |
819 | 806 |
820 if (IsSameChromeInstance(pid)) { | 807 if (IsSameChromeInstance(pid)) { |
821 // Orphaned lockfile (pid is part of same chrome instance we are, even | 808 // Orphaned lockfile (pid is part of same chrome instance we are, even |
822 // though we haven't tried to create a lockfile yet). | 809 // though we haven't tried to create a lockfile yet). |
823 UnlinkPath(lock_path_.value()); | 810 UnlinkPath(lock_path_); |
824 return PROCESS_NONE; | 811 return PROCESS_NONE; |
825 } | 812 } |
826 | 813 |
827 if (retries == timeout_seconds) { | 814 if (retries == timeout_seconds) { |
828 // Retries failed. Kill the unresponsive chrome process and continue. | 815 // Retries failed. Kill the unresponsive chrome process and continue. |
829 if (!kill_unresponsive || !KillProcessByLockPath(lock_path_.value())) | 816 if (!kill_unresponsive || !KillProcessByLockPath(lock_path_)) |
830 return PROFILE_IN_USE; | 817 return PROFILE_IN_USE; |
831 return PROCESS_NONE; | 818 return PROCESS_NONE; |
832 } | 819 } |
833 | 820 |
834 PlatformThread::Sleep(1000 /* ms */); | 821 PlatformThread::Sleep(1000 /* ms */); |
835 } | 822 } |
836 | 823 |
837 timeval timeout = {timeout_seconds, 0}; | 824 timeval timeout = {timeout_seconds, 0}; |
838 setsockopt(socket.fd(), SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); | 825 setsockopt(socket.fd(), SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); |
839 | 826 |
(...skipping 10 matching lines...) Expand all Loading... |
850 const std::vector<std::string>& argv = cmd_line.argv(); | 837 const std::vector<std::string>& argv = cmd_line.argv(); |
851 for (std::vector<std::string>::const_iterator it = argv.begin(); | 838 for (std::vector<std::string>::const_iterator it = argv.begin(); |
852 it != argv.end(); ++it) { | 839 it != argv.end(); ++it) { |
853 to_send.push_back(kTokenDelimiter); | 840 to_send.push_back(kTokenDelimiter); |
854 to_send.append(*it); | 841 to_send.append(*it); |
855 } | 842 } |
856 | 843 |
857 // Send the message | 844 // Send the message |
858 if (!WriteToSocket(socket.fd(), to_send.data(), to_send.length())) { | 845 if (!WriteToSocket(socket.fd(), to_send.data(), to_send.length())) { |
859 // Try to kill the other process, because it might have been dead. | 846 // Try to kill the other process, because it might have been dead. |
860 if (!kill_unresponsive || !KillProcessByLockPath(lock_path_.value())) | 847 if (!kill_unresponsive || !KillProcessByLockPath(lock_path_)) |
861 return PROFILE_IN_USE; | 848 return PROFILE_IN_USE; |
862 return PROCESS_NONE; | 849 return PROCESS_NONE; |
863 } | 850 } |
864 | 851 |
865 if (shutdown(socket.fd(), SHUT_WR) < 0) | 852 if (shutdown(socket.fd(), SHUT_WR) < 0) |
866 PLOG(ERROR) << "shutdown() failed"; | 853 PLOG(ERROR) << "shutdown() failed"; |
867 | 854 |
868 // Read ACK message from the other process. It might be blocked for a certain | 855 // Read ACK message from the other process. It might be blocked for a certain |
869 // timeout, to make sure the other process has enough time to return ACK. | 856 // timeout, to make sure the other process has enough time to return ACK. |
870 char buf[kMaxACKMessageLength + 1]; | 857 char buf[kMaxACKMessageLength + 1]; |
871 ssize_t len = | 858 ssize_t len = |
872 ReadFromSocket(socket.fd(), buf, kMaxACKMessageLength, timeout_seconds); | 859 ReadFromSocket(socket.fd(), buf, kMaxACKMessageLength, timeout_seconds); |
873 | 860 |
874 // Failed to read ACK, the other process might have been frozen. | 861 // Failed to read ACK, the other process might have been frozen. |
875 if (len <= 0) { | 862 if (len <= 0) { |
876 if (!kill_unresponsive || !KillProcessByLockPath(lock_path_.value())) | 863 if (!kill_unresponsive || !KillProcessByLockPath(lock_path_)) |
877 return PROFILE_IN_USE; | 864 return PROFILE_IN_USE; |
878 return PROCESS_NONE; | 865 return PROCESS_NONE; |
879 } | 866 } |
880 | 867 |
881 buf[len] = '\0'; | 868 buf[len] = '\0'; |
882 if (strncmp(buf, kShutdownToken, arraysize(kShutdownToken) - 1) == 0) { | 869 if (strncmp(buf, kShutdownToken, arraysize(kShutdownToken) - 1) == 0) { |
883 // The other process is shutting down, it's safe to start a new process. | 870 // The other process is shutting down, it's safe to start a new process. |
884 return PROCESS_NONE; | 871 return PROCESS_NONE; |
885 } else if (strncmp(buf, kACKToken, arraysize(kACKToken) - 1) == 0) { | 872 } else if (strncmp(buf, kACKToken, arraysize(kACKToken) - 1) == 0) { |
886 // Notify the window manager that we've started up; if we do not open a | 873 // Notify the window manager that we've started up; if we do not open a |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
921 | 908 |
922 return LOCK_ERROR; | 909 return LOCK_ERROR; |
923 } | 910 } |
924 | 911 |
925 bool ProcessSingleton::Create() { | 912 bool ProcessSingleton::Create() { |
926 int sock; | 913 int sock; |
927 sockaddr_un addr; | 914 sockaddr_un addr; |
928 | 915 |
929 // The symlink lock is pointed to the hostname and process id, so other | 916 // The symlink lock is pointed to the hostname and process id, so other |
930 // processes can find it out. | 917 // processes can find it out. |
931 std::string symlink_content = StringPrintf( | 918 FilePath symlink_content(StringPrintf( |
932 "%s%c%u", | 919 "%s%c%u", |
933 net::GetHostName().c_str(), | 920 net::GetHostName().c_str(), |
934 kLockDelimiter, | 921 kLockDelimiter, |
935 base::GetCurrentProcId()); | 922 base::GetCurrentProcId())); |
936 | 923 |
937 // Create symbol link before binding the socket, to ensure only one instance | 924 // Create symbol link before binding the socket, to ensure only one instance |
938 // can have the socket open. | 925 // can have the socket open. |
939 if (!SymlinkPath(symlink_content, lock_path_.value())) { | 926 if (!SymlinkPath(symlink_content, lock_path_)) { |
940 // If we failed to create the lock, most likely another instance won the | 927 // If we failed to create the lock, most likely another instance won the |
941 // startup race. | 928 // startup race. |
942 return false; | 929 return false; |
943 } | 930 } |
944 | 931 |
945 // Create the socket file somewhere in /tmp which is usually mounted as a | 932 // Create the socket file somewhere in /tmp which is usually mounted as a |
946 // normal filesystem. Some network filesystems (notably AFS) are screwy and | 933 // normal filesystem. Some network filesystems (notably AFS) are screwy and |
947 // do not support Unix domain sockets. | 934 // do not support Unix domain sockets. |
948 if (!socket_dir_.CreateUniqueTempDir()) { | 935 if (!socket_dir_.CreateUniqueTempDir()) { |
949 LOG(ERROR) << "Failed to create socket directory."; | 936 LOG(ERROR) << "Failed to create socket directory."; |
950 return false; | 937 return false; |
951 } | 938 } |
952 // Setup the socket symlink and the two cookies. | 939 // Setup the socket symlink and the two cookies. |
953 FilePath socket_target_path = | 940 FilePath socket_target_path = |
954 socket_dir_.path().Append(chrome::kSingletonSocketFilename); | 941 socket_dir_.path().Append(chrome::kSingletonSocketFilename); |
955 std::string cookie = GenerateCookie(); | 942 FilePath cookie(GenerateCookie()); |
956 FilePath remote_cookie_path = | 943 FilePath remote_cookie_path = |
957 socket_dir_.path().Append(chrome::kSingletonCookieFilename); | 944 socket_dir_.path().Append(chrome::kSingletonCookieFilename); |
958 UnlinkPath(socket_path_.value()); | 945 UnlinkPath(socket_path_); |
959 UnlinkPath(cookie_path_.value()); | 946 UnlinkPath(cookie_path_); |
960 if (!SymlinkPath(socket_target_path.value(), socket_path_.value()) || | 947 if (!SymlinkPath(socket_target_path, socket_path_) || |
961 !SymlinkPath(cookie, cookie_path_.value()) || | 948 !SymlinkPath(cookie, cookie_path_) || |
962 !SymlinkPath(cookie, remote_cookie_path.value())) { | 949 !SymlinkPath(cookie, remote_cookie_path)) { |
963 // We've already locked things, so we can't have lost the startup race, | 950 // We've already locked things, so we can't have lost the startup race, |
964 // but something doesn't like us. | 951 // but something doesn't like us. |
965 LOG(ERROR) << "Failed to create symlinks."; | 952 LOG(ERROR) << "Failed to create symlinks."; |
966 socket_dir_.Delete(); | 953 socket_dir_.Delete(); |
967 return false; | 954 return false; |
968 } | 955 } |
969 | 956 |
970 SetupSocket(socket_target_path.value(), &sock, &addr); | 957 SetupSocket(socket_target_path.value(), &sock, &addr); |
971 | 958 |
972 if (bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) { | 959 if (bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) { |
(...skipping 12 matching lines...) Expand all Loading... |
985 DCHECK(ml); | 972 DCHECK(ml); |
986 ml->PostTask(FROM_HERE, NewRunnableMethod( | 973 ml->PostTask(FROM_HERE, NewRunnableMethod( |
987 watcher_.get(), | 974 watcher_.get(), |
988 &ProcessSingleton::LinuxWatcher::StartListening, | 975 &ProcessSingleton::LinuxWatcher::StartListening, |
989 sock)); | 976 sock)); |
990 | 977 |
991 return true; | 978 return true; |
992 } | 979 } |
993 | 980 |
994 void ProcessSingleton::Cleanup() { | 981 void ProcessSingleton::Cleanup() { |
995 UnlinkPath(socket_path_.value()); | 982 UnlinkPath(socket_path_); |
996 UnlinkPath(cookie_path_.value()); | 983 UnlinkPath(cookie_path_); |
997 UnlinkPath(lock_path_.value()); | 984 UnlinkPath(lock_path_); |
998 } | 985 } |
OLD | NEW |