summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-03 17:37:54 +0000
committergspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-03 17:37:54 +0000
commit723571af3c1a86aa14a68bce2511f3dad399287f (patch)
treec77043d78d5eb7eb1437071561fce7c8ad9b4a5d
parent0868ee7ae6d7fbb63ab85dfeafa34d724f9a1b45 (diff)
downloadchromium_src-723571af3c1a86aa14a68bce2511f3dad399287f.zip
chromium_src-723571af3c1a86aa14a68bce2511f3dad399287f.tar.gz
chromium_src-723571af3c1a86aa14a68bce2511f3dad399287f.tar.bz2
Start using file_util symlink code, now that it's available.
In CL http://codereview.chromium.org/5349007 I added some base API for manipulating symlinks (since I needed it for some ChromeOS code and noticed that other places could use it too), and this just starts using that API. BUG=none TEST=Ran ui_tests, passed trybots. Review URL: http://codereview.chromium.org/5286010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68181 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/base_paths_linux.cc8
-rw-r--r--base/command_line.cc11
-rw-r--r--base/file_util_posix.cc5
-rw-r--r--base/process_util_linux.cc7
-rw-r--r--chrome/browser/process_singleton_linux.cc97
-rw-r--r--chrome/common/logging_chrome.cc12
6 files changed, 59 insertions, 81 deletions
diff --git a/base/base_paths_linux.cc b/base/base_paths_linux.cc
index 24f86b4..bdf540c 100644
--- a/base/base_paths_linux.cc
+++ b/base/base_paths_linux.cc
@@ -37,14 +37,12 @@ bool PathProviderPosix(int key, FilePath* result) {
case base::FILE_EXE:
case base::FILE_MODULE: { // TODO(evanm): is this correct?
#if defined(OS_LINUX)
- char bin_dir[PATH_MAX + 1];
- int bin_dir_size = readlink(kSelfExe, bin_dir, PATH_MAX);
- if (bin_dir_size < 0 || bin_dir_size > PATH_MAX) {
+ FilePath bin_dir;
+ if (!file_util::ReadSymbolicLink(FilePath(kSelfExe), &bin_dir)) {
NOTREACHED() << "Unable to resolve " << kSelfExe << ".";
return false;
}
- bin_dir[bin_dir_size] = 0;
- *result = FilePath(bin_dir);
+ *result = bin_dir;
return true;
#elif defined(OS_FREEBSD)
int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
diff --git a/base/command_line.cc b/base/command_line.cc
index b335e7c..427bed4 100644
--- a/base/command_line.cc
+++ b/base/command_line.cc
@@ -19,6 +19,7 @@
#include <algorithm>
#include "base/file_path.h"
+#include "base/file_util.h"
#include "base/logging.h"
#include "base/singleton.h"
#include "base/string_split.h"
@@ -237,13 +238,11 @@ void CommandLine::SetProcTitle() {
// show up as "exe" in process listings. Read the symlink /proc/self/exe and
// use the path it points at for our process title. Note that this is only for
// display purposes and has no TOCTTOU security implications.
- char buffer[PATH_MAX];
- // Note: readlink() does not append a null byte to terminate the string.
- ssize_t length = readlink("/proc/self/exe", buffer, sizeof(buffer));
- DCHECK(length <= static_cast<ssize_t>(sizeof(buffer)));
- if (length > 0) {
+ FilePath target;
+ FilePath self_exe("/proc/self/exe");
+ if (file_util::ReadSymbolicLink(self_exe, &target)) {
have_argv0 = true;
- title.assign(buffer, length);
+ title = target.value();
// If the binary has since been deleted, Linux appends " (deleted)" to the
// symlink target. Remove it, since this is not really part of our name.
const std::string kDeletedSuffix = " (deleted)";
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index e71051e..92527c8 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -388,11 +388,12 @@ bool ReadSymbolicLink(const FilePath& symlink_path,
char buf[PATH_MAX];
ssize_t count = ::readlink(symlink_path.value().c_str(), buf, arraysize(buf));
- if (count <= 0)
+ if (count <= 0) {
+ target_path->clear();
return false;
+ }
*target_path = FilePath(FilePath::StringType(buf, count));
-
return true;
}
diff --git a/base/process_util_linux.cc b/base/process_util_linux.cc
index 6138c07..4627aa5 100644
--- a/base/process_util_linux.cc
+++ b/base/process_util_linux.cc
@@ -111,13 +111,12 @@ FilePath GetProcessExecutablePath(ProcessHandle process) {
FilePath stat_file("/proc");
stat_file = stat_file.Append(base::IntToString(process));
stat_file = stat_file.Append("exe");
- char exename[2048];
- ssize_t len = readlink(stat_file.value().c_str(), exename, sizeof(exename));
- if (len < 1) {
+ FilePath exe_name;
+ if (!file_util::ReadSymbolicLink(stat_file, &exe_name)) {
// No such process. Happens frequently in e.g. TerminateAllChromeProcesses
return FilePath();
}
- return FilePath(std::string(exename, len));
+ return exe_name;
}
ProcessIterator::ProcessIterator(const ProcessFilter* filter)
diff --git a/chrome/browser/process_singleton_linux.cc b/chrome/browser/process_singleton_linux.cc
index dcf2281..8418ee9 100644
--- a/chrome/browser/process_singleton_linux.cc
+++ b/chrome/browser/process_singleton_linux.cc
@@ -60,6 +60,7 @@
#include "base/command_line.h"
#include "base/eintr_wrapper.h"
#include "base/file_path.h"
+#include "base/file_util.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/path_service.h"
@@ -229,43 +230,29 @@ void SetupSocket(const std::string& path, int* sock, struct sockaddr_un* addr) {
SetupSockAddr(path, addr);
}
-// Read a symbolic link, return empty string if given path is not a
-// symbol link. This version does not interpret the errno, leaving
-// the caller to do so.
-bool ReadLinkSilent(const std::string& path, std::string* output) {
- char buf[PATH_MAX];
- ssize_t len = readlink(path.c_str(), buf, PATH_MAX);
- if (len >= 0) {
- output->assign(buf, len);
- return true;
- }
- output->clear();
- return false;
-}
-
// Read a symbolic link, return empty string if given path is not a symbol link.
-std::string ReadLink(const std::string& path) {
- std::string target;
- if (!ReadLinkSilent(path, &target)) {
+FilePath ReadLink(const FilePath& path) {
+ FilePath target;
+ if (!file_util::ReadSymbolicLink(path, &target)) {
// The only errno that should occur is ENOENT.
if (errno != 0 && errno != ENOENT)
- PLOG(ERROR) << "readlink(" << path << ") failed";
+ PLOG(ERROR) << "readlink(" << path.value() << ") failed";
}
return target;
}
// Unlink a path. Return true on success.
-bool UnlinkPath(const std::string& path) {
- int rv = unlink(path.c_str());
+bool UnlinkPath(const FilePath& path) {
+ int rv = unlink(path.value().c_str());
if (rv < 0 && errno != ENOENT)
- PLOG(ERROR) << "Failed to unlink " << path;
+ PLOG(ERROR) << "Failed to unlink " << path.value();
return rv == 0;
}
// Create a symlink. Returns true on success.
-bool SymlinkPath(const std::string& target, const std::string& path) {
- if (symlink(target.c_str(), path.c_str()) < 0) {
+bool SymlinkPath(const FilePath& target, const FilePath& path) {
+ if (!file_util::CreateSymbolicLink(target, path)) {
// Double check the value in case symlink suceeded but we got an incorrect
// failure due to NFS packet loss & retry.
int saved_errno = errno;
@@ -273,7 +260,7 @@ bool SymlinkPath(const std::string& target, const std::string& path) {
// If we failed to create the lock, most likely another instance won the
// startup race.
errno = saved_errno;
- PLOG(ERROR) << "Failed to create " << path;
+ PLOG(ERROR) << "Failed to create " << path.value();
return false;
}
}
@@ -282,10 +269,10 @@ bool SymlinkPath(const std::string& target, const std::string& path) {
// Extract the hostname and pid from the lock symlink.
// Returns true if the lock existed.
-bool ParseLockPath(const std::string& path,
+bool ParseLockPath(const FilePath& path,
std::string* hostname,
int* pid) {
- std::string real_path = ReadLink(path);
+ std::string real_path = ReadLink(path).value();
if (real_path.empty())
return false;
@@ -350,13 +337,13 @@ bool IsSameChromeInstance(pid_t pid) {
// If the process is part of the same chrome instance, unlink the lock file and
// return true without killing it.
// If the process is on a different host, return false.
-bool KillProcessByLockPath(const std::string& path) {
+bool KillProcessByLockPath(const FilePath& path) {
std::string hostname;
int pid;
ParseLockPath(path, &hostname, &pid);
if (!hostname.empty() && hostname != net::GetHostName()) {
- DisplayProfileInUseError(path, hostname, pid);
+ DisplayProfileInUseError(path.value(), hostname, pid);
return false;
}
UnlinkPath(path);
@@ -374,7 +361,7 @@ bool KillProcessByLockPath(const std::string& path) {
return true;
}
- LOG(ERROR) << "Failed to extract pid from path: " << path;
+ LOG(ERROR) << "Failed to extract pid from path: " << path.value();
return true;
}
@@ -402,21 +389,21 @@ std::string GenerateCookie() {
return base::Uint64ToString(base::RandUint64());
}
-bool CheckCookie(const FilePath& path, const std::string& cookie) {
- return (cookie == ReadLink(path.value()));
+bool CheckCookie(const FilePath& path, const FilePath& cookie) {
+ return (cookie == ReadLink(path));
}
bool ConnectSocket(ScopedSocket* socket,
const FilePath& socket_path,
const FilePath& cookie_path) {
- std::string socket_target;
- if (ReadLinkSilent(socket_path.value(), &socket_target)) {
+ FilePath socket_target;
+ if (file_util::ReadSymbolicLink(socket_path, &socket_target)) {
// It's a symlink. Read the cookie.
- std::string cookie = ReadLink(cookie_path.value());
+ FilePath cookie = ReadLink(cookie_path);
if (cookie.empty())
return false;
- FilePath remote_cookie = FilePath(socket_target).DirName().
- Append(chrome::kSingletonCookieFilename);
+ FilePath remote_cookie = socket_target.DirName().
+ Append(chrome::kSingletonCookieFilename);
// Verify the cookie before connecting.
if (!CheckCookie(remote_cookie, cookie))
return false;
@@ -794,14 +781,14 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
std::string hostname;
int pid;
- if (!ParseLockPath(lock_path_.value(), &hostname, &pid)) {
+ if (!ParseLockPath(lock_path_, &hostname, &pid)) {
// No lockfile exists.
return PROCESS_NONE;
}
if (hostname.empty()) {
// Invalid lockfile.
- UnlinkPath(lock_path_.value());
+ UnlinkPath(lock_path_);
return PROCESS_NONE;
}
@@ -813,20 +800,20 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
if (!IsChromeProcess(pid)) {
// Orphaned lockfile (no process with pid, or non-chrome process.)
- UnlinkPath(lock_path_.value());
+ UnlinkPath(lock_path_);
return PROCESS_NONE;
}
if (IsSameChromeInstance(pid)) {
// Orphaned lockfile (pid is part of same chrome instance we are, even
// though we haven't tried to create a lockfile yet).
- UnlinkPath(lock_path_.value());
+ UnlinkPath(lock_path_);
return PROCESS_NONE;
}
if (retries == timeout_seconds) {
// Retries failed. Kill the unresponsive chrome process and continue.
- if (!kill_unresponsive || !KillProcessByLockPath(lock_path_.value()))
+ if (!kill_unresponsive || !KillProcessByLockPath(lock_path_))
return PROFILE_IN_USE;
return PROCESS_NONE;
}
@@ -857,7 +844,7 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
// Send the message
if (!WriteToSocket(socket.fd(), to_send.data(), to_send.length())) {
// Try to kill the other process, because it might have been dead.
- if (!kill_unresponsive || !KillProcessByLockPath(lock_path_.value()))
+ if (!kill_unresponsive || !KillProcessByLockPath(lock_path_))
return PROFILE_IN_USE;
return PROCESS_NONE;
}
@@ -873,7 +860,7 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
// Failed to read ACK, the other process might have been frozen.
if (len <= 0) {
- if (!kill_unresponsive || !KillProcessByLockPath(lock_path_.value()))
+ if (!kill_unresponsive || !KillProcessByLockPath(lock_path_))
return PROFILE_IN_USE;
return PROCESS_NONE;
}
@@ -928,15 +915,15 @@ bool ProcessSingleton::Create() {
// The symlink lock is pointed to the hostname and process id, so other
// processes can find it out.
- std::string symlink_content = StringPrintf(
+ FilePath symlink_content(StringPrintf(
"%s%c%u",
net::GetHostName().c_str(),
kLockDelimiter,
- base::GetCurrentProcId());
+ base::GetCurrentProcId()));
// Create symbol link before binding the socket, to ensure only one instance
// can have the socket open.
- if (!SymlinkPath(symlink_content, lock_path_.value())) {
+ if (!SymlinkPath(symlink_content, lock_path_)) {
// If we failed to create the lock, most likely another instance won the
// startup race.
return false;
@@ -952,14 +939,14 @@ bool ProcessSingleton::Create() {
// Setup the socket symlink and the two cookies.
FilePath socket_target_path =
socket_dir_.path().Append(chrome::kSingletonSocketFilename);
- std::string cookie = GenerateCookie();
+ FilePath cookie(GenerateCookie());
FilePath remote_cookie_path =
socket_dir_.path().Append(chrome::kSingletonCookieFilename);
- UnlinkPath(socket_path_.value());
- UnlinkPath(cookie_path_.value());
- if (!SymlinkPath(socket_target_path.value(), socket_path_.value()) ||
- !SymlinkPath(cookie, cookie_path_.value()) ||
- !SymlinkPath(cookie, remote_cookie_path.value())) {
+ UnlinkPath(socket_path_);
+ UnlinkPath(cookie_path_);
+ if (!SymlinkPath(socket_target_path, socket_path_) ||
+ !SymlinkPath(cookie, cookie_path_) ||
+ !SymlinkPath(cookie, remote_cookie_path)) {
// We've already locked things, so we can't have lost the startup race,
// but something doesn't like us.
LOG(ERROR) << "Failed to create symlinks.";
@@ -992,7 +979,7 @@ bool ProcessSingleton::Create() {
}
void ProcessSingleton::Cleanup() {
- UnlinkPath(socket_path_.value());
- UnlinkPath(cookie_path_.value());
- UnlinkPath(lock_path_.value());
+ UnlinkPath(socket_path_);
+ UnlinkPath(cookie_path_);
+ UnlinkPath(lock_path_);
}
diff --git a/chrome/common/logging_chrome.cc b/chrome/common/logging_chrome.cc
index 196c581..e5d442c 100644
--- a/chrome/common/logging_chrome.cc
+++ b/chrome/common/logging_chrome.cc
@@ -164,23 +164,17 @@ FilePath SetUpSymlinkIfNeeded(const FilePath& symlink_path, bool new_log) {
target_path = GenerateTimestampedName(symlink_path, base::Time::Now());
// We don't care if the unlink fails; we're going to continue anyway.
- if (unlink(symlink_path.value().c_str()) == -1) {
+ if (::unlink(symlink_path.value().c_str()) == -1) {
if (symlink_exists) // only warn if we might expect it to succeed.
PLOG(WARNING) << "Unable to unlink " << symlink_path.value();
}
- if (symlink(target_path.value().c_str(),
- symlink_path.value().c_str()) == -1) {
+ if (!file_util::CreateSymbolicLink(target_path, symlink_path)) {
PLOG(ERROR) << "Unable to create symlink " << symlink_path.value()
<< " pointing at " << target_path.value();
}
} else {
- char buf[PATH_MAX];
- ssize_t count = readlink(symlink_path.value().c_str(), buf, arraysize(buf));
- if (count > 0) {
- target_path = FilePath(FilePath::StringType(buf, count));
- } else {
+ if (!file_util::ReadSymbolicLink(symlink_path, &target_path))
PLOG(ERROR) << "Unable to read symlink " << symlink_path.value();
- }
}
return target_path;
}