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 |