| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 | 223 |
| 224 // Set up a socket and sockaddr appropriate for messaging. | 224 // Set up a socket and sockaddr appropriate for messaging. |
| 225 void SetupSocket(const std::string& path, int* sock, struct sockaddr_un* addr) { | 225 void SetupSocket(const std::string& path, int* sock, struct sockaddr_un* addr) { |
| 226 *sock = SetupSocketOnly(); | 226 *sock = SetupSocketOnly(); |
| 227 SetupSockAddr(path, addr); | 227 SetupSockAddr(path, addr); |
| 228 } | 228 } |
| 229 | 229 |
| 230 // Read a symbolic link, return empty string if given path is not a symbol link. | 230 // Read a symbolic link, return empty string if given path is not a symbol link. |
| 231 base::FilePath ReadLink(const base::FilePath& path) { | 231 base::FilePath ReadLink(const base::FilePath& path) { |
| 232 base::FilePath target; | 232 base::FilePath target; |
| 233 if (!file_util::ReadSymbolicLink(path, &target)) { | 233 if (!base::ReadSymbolicLink(path, &target)) { |
| 234 // The only errno that should occur is ENOENT. | 234 // The only errno that should occur is ENOENT. |
| 235 if (errno != 0 && errno != ENOENT) | 235 if (errno != 0 && errno != ENOENT) |
| 236 PLOG(ERROR) << "readlink(" << path.value() << ") failed"; | 236 PLOG(ERROR) << "readlink(" << path.value() << ") failed"; |
| 237 } | 237 } |
| 238 return target; | 238 return target; |
| 239 } | 239 } |
| 240 | 240 |
| 241 // Unlink a path. Return true on success. | 241 // Unlink a path. Return true on success. |
| 242 bool UnlinkPath(const base::FilePath& path) { | 242 bool UnlinkPath(const base::FilePath& path) { |
| 243 int rv = unlink(path.value().c_str()); | 243 int rv = unlink(path.value().c_str()); |
| 244 if (rv < 0 && errno != ENOENT) | 244 if (rv < 0 && errno != ENOENT) |
| 245 PLOG(ERROR) << "Failed to unlink " << path.value(); | 245 PLOG(ERROR) << "Failed to unlink " << path.value(); |
| 246 | 246 |
| 247 return rv == 0; | 247 return rv == 0; |
| 248 } | 248 } |
| 249 | 249 |
| 250 // Create a symlink. Returns true on success. | 250 // Create a symlink. Returns true on success. |
| 251 bool SymlinkPath(const base::FilePath& target, const base::FilePath& path) { | 251 bool SymlinkPath(const base::FilePath& target, const base::FilePath& path) { |
| 252 if (!file_util::CreateSymbolicLink(target, path)) { | 252 if (!base::CreateSymbolicLink(target, path)) { |
| 253 // Double check the value in case symlink suceeded but we got an incorrect | 253 // Double check the value in case symlink suceeded but we got an incorrect |
| 254 // failure due to NFS packet loss & retry. | 254 // failure due to NFS packet loss & retry. |
| 255 int saved_errno = errno; | 255 int saved_errno = errno; |
| 256 if (ReadLink(path) != target) { | 256 if (ReadLink(path) != target) { |
| 257 // If we failed to create the lock, most likely another instance won the | 257 // If we failed to create the lock, most likely another instance won the |
| 258 // startup race. | 258 // startup race. |
| 259 errno = saved_errno; | 259 errno = saved_errno; |
| 260 PLOG(ERROR) << "Failed to create " << path.value(); | 260 PLOG(ERROR) << "Failed to create " << path.value(); |
| 261 return false; | 261 return false; |
| 262 } | 262 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 } | 340 } |
| 341 | 341 |
| 342 bool CheckCookie(const base::FilePath& path, const base::FilePath& cookie) { | 342 bool CheckCookie(const base::FilePath& path, const base::FilePath& cookie) { |
| 343 return (cookie == ReadLink(path)); | 343 return (cookie == ReadLink(path)); |
| 344 } | 344 } |
| 345 | 345 |
| 346 bool ConnectSocket(ScopedSocket* socket, | 346 bool ConnectSocket(ScopedSocket* socket, |
| 347 const base::FilePath& socket_path, | 347 const base::FilePath& socket_path, |
| 348 const base::FilePath& cookie_path) { | 348 const base::FilePath& cookie_path) { |
| 349 base::FilePath socket_target; | 349 base::FilePath socket_target; |
| 350 if (file_util::ReadSymbolicLink(socket_path, &socket_target)) { | 350 if (base::ReadSymbolicLink(socket_path, &socket_target)) { |
| 351 // It's a symlink. Read the cookie. | 351 // It's a symlink. Read the cookie. |
| 352 base::FilePath cookie = ReadLink(cookie_path); | 352 base::FilePath cookie = ReadLink(cookie_path); |
| 353 if (cookie.empty()) | 353 if (cookie.empty()) |
| 354 return false; | 354 return false; |
| 355 base::FilePath remote_cookie = socket_target.DirName(). | 355 base::FilePath remote_cookie = socket_target.DirName(). |
| 356 Append(chrome::kSingletonCookieFilename); | 356 Append(chrome::kSingletonCookieFilename); |
| 357 // Verify the cookie before connecting. | 357 // Verify the cookie before connecting. |
| 358 if (!CheckCookie(remote_cookie, cookie)) | 358 if (!CheckCookie(remote_cookie, cookie)) |
| 359 return false; | 359 return false; |
| 360 // Now we know the directory was (at that point) created by the profile | 360 // Now we know the directory was (at that point) created by the profile |
| (...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 974 } | 974 } |
| 975 | 975 |
| 976 void ProcessSingleton::KillProcess(int pid) { | 976 void ProcessSingleton::KillProcess(int pid) { |
| 977 // TODO(james.su@gmail.com): Is SIGKILL ok? | 977 // TODO(james.su@gmail.com): Is SIGKILL ok? |
| 978 int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL); | 978 int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL); |
| 979 // ESRCH = No Such Process (can happen if the other process is already in | 979 // ESRCH = No Such Process (can happen if the other process is already in |
| 980 // progress of shutting down and finishes before we try to kill it). | 980 // progress of shutting down and finishes before we try to kill it). |
| 981 DCHECK(rv == 0 || errno == ESRCH) << "Error killing process: " | 981 DCHECK(rv == 0 || errno == ESRCH) << "Error killing process: " |
| 982 << safe_strerror(errno); | 982 << safe_strerror(errno); |
| 983 } | 983 } |
| OLD | NEW |