summaryrefslogtreecommitdiffstats
path: root/chromium/base/file_util_posix.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/base/file_util_posix.cc')
-rw-r--r--chromium/base/file_util_posix.cc215
1 files changed, 80 insertions, 135 deletions
diff --git a/chromium/base/file_util_posix.cc b/chromium/base/file_util_posix.cc
index ddcd5ddb912..92e8cad1605 100644
--- a/chromium/base/file_util_posix.cc
+++ b/chromium/base/file_util_posix.cc
@@ -33,6 +33,7 @@
#include "base/basictypes.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
+#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
@@ -60,8 +61,7 @@ namespace base {
namespace {
-#if defined(OS_BSD) || defined(OS_MACOSX)
-typedef struct stat stat_wrapper_t;
+#if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL)
static int CallStat(const char *path, stat_wrapper_t *sb) {
ThreadRestrictions::AssertIOAllowed();
return stat(path, sb);
@@ -70,8 +70,7 @@ static int CallLstat(const char *path, stat_wrapper_t *sb) {
ThreadRestrictions::AssertIOAllowed();
return lstat(path, sb);
}
-#else
-typedef struct stat64 stat_wrapper_t;
+#else // defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL)
static int CallStat(const char *path, stat_wrapper_t *sb) {
ThreadRestrictions::AssertIOAllowed();
return stat64(path, sb);
@@ -80,13 +79,7 @@ static int CallLstat(const char *path, stat_wrapper_t *sb) {
ThreadRestrictions::AssertIOAllowed();
return lstat64(path, sb);
}
-#if defined(OS_ANDROID)
-static int CallFstat(int fd, stat_wrapper_t *sb) {
- ThreadRestrictions::AssertIOAllowed();
- return fstat64(fd, sb);
-}
-#endif
-#endif
+#endif // !(defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL))
// Helper for NormalizeFilePath(), defined below.
bool RealPath(const FilePath& path, FilePath* real_path) {
@@ -172,15 +165,15 @@ int CreateAndOpenFdForTemporaryFile(FilePath directory, FilePath* path) {
bool DetermineDevShmExecutable() {
bool result = false;
FilePath path;
- int fd = CreateAndOpenFdForTemporaryFile(FilePath("/dev/shm"), &path);
- if (fd >= 0) {
- file_util::ScopedFD shm_fd_closer(&fd);
+
+ ScopedFD fd(CreateAndOpenFdForTemporaryFile(FilePath("/dev/shm"), &path));
+ if (fd.is_valid()) {
DeleteFile(path, false);
long sysconf_result = sysconf(_SC_PAGESIZE);
CHECK_GE(sysconf_result, 0);
size_t pagesize = static_cast<size_t>(sysconf_result);
CHECK_GE(sizeof(pagesize), sizeof(sysconf_result));
- void *mapping = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd, 0);
+ void* mapping = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd.get(), 0);
if (mapping != MAP_FAILED) {
if (mprotect(mapping, pagesize, PROT_READ | PROT_EXEC) == 0)
result = true;
@@ -244,12 +237,12 @@ bool DeleteFile(const FilePath& path, bool recursive) {
bool ReplaceFile(const FilePath& from_path,
const FilePath& to_path,
- PlatformFileError* error) {
+ File::Error* error) {
ThreadRestrictions::AssertIOAllowed();
if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0)
return true;
if (error)
- *error = ErrnoToPlatformFileError(errno);
+ *error = File::OSErrorToFileError(errno);
return false;
}
@@ -260,13 +253,10 @@ bool CopyDirectory(const FilePath& from_path,
// Some old callers of CopyDirectory want it to support wildcards.
// After some discussion, we decided to fix those callers.
// Break loudly here if anyone tries to do this.
- // TODO(evanm): remove this once we're sure it's ok.
DCHECK(to_path.value().find('*') == std::string::npos);
DCHECK(from_path.value().find('*') == std::string::npos);
- char top_dir[PATH_MAX];
- if (strlcpy(top_dir, from_path.value().c_str(),
- arraysize(top_dir)) >= arraysize(top_dir)) {
+ if (from_path.value().size() >= PATH_MAX) {
return false;
}
@@ -286,10 +276,10 @@ bool CopyDirectory(const FilePath& from_path,
return false;
if (real_to_path.value().size() >= real_from_path.value().size() &&
real_to_path.value().compare(0, real_from_path.value().size(),
- real_from_path.value()) == 0)
+ real_from_path.value()) == 0) {
return false;
+ }
- bool success = true;
int traverse_type = FileEnumerator::FILES | FileEnumerator::SHOW_SYM_LINKS;
if (recursive)
traverse_type |= FileEnumerator::DIRECTORIES;
@@ -302,7 +292,7 @@ bool CopyDirectory(const FilePath& from_path,
if (stat(from_path.value().c_str(), &from_stat) < 0) {
DLOG(ERROR) << "CopyDirectory() couldn't stat source directory: "
<< from_path.value() << " errno = " << errno;
- success = false;
+ return false;
}
struct stat to_path_stat;
FilePath from_path_base = from_path;
@@ -315,8 +305,10 @@ bool CopyDirectory(const FilePath& from_path,
// The Windows version of this function assumes that non-recursive calls
// will always have a directory for from_path.
+ // TODO(maruel): This is not necessary anymore.
DCHECK(recursive || S_ISDIR(from_stat.st_mode));
+ bool success = true;
while (success && !current.empty()) {
// current is the source path, including from_path, so append
// the suffix after from_path to to_path to create the target_path.
@@ -463,30 +455,14 @@ bool GetTempDir(FilePath* path) {
}
#endif // !defined(OS_MACOSX)
-#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
-// This is implemented in file_util_mac.mm and file_util_android.cc for those
-// platforms.
-bool GetShmemTempDir(bool executable, FilePath* path) {
-#if defined(OS_LINUX)
- bool use_dev_shm = true;
- if (executable) {
- static const bool s_dev_shm_executable = DetermineDevShmExecutable();
- use_dev_shm = s_dev_shm_executable;
- }
- if (use_dev_shm) {
- *path = FilePath("/dev/shm");
- return true;
- }
-#endif
- return GetTempDir(path);
-}
-#endif // !defined(OS_MACOSX) && !defined(OS_ANDROID)
-
-#if !defined(OS_MACOSX)
+#if !defined(OS_MACOSX) // Mac implementation is in file_util_mac.mm.
FilePath GetHomeDir() {
#if defined(OS_CHROMEOS)
- if (SysInfo::IsRunningOnChromeOS())
- return FilePath("/home/chronos/user");
+ if (SysInfo::IsRunningOnChromeOS()) {
+ // On Chrome OS chrome::DIR_USER_DATA is overridden with a primary user
+ // homedir once it becomes available. Return / as the safe option.
+ return FilePath("/");
+ }
#endif
const char* home_dir = getenv("HOME");
@@ -496,9 +472,12 @@ FilePath GetHomeDir() {
#if defined(OS_ANDROID)
DLOG(WARNING) << "OS_ANDROID: Home directory lookup not yet implemented.";
#elif defined(USE_GLIB) && !defined(OS_CHROMEOS)
- // g_get_home_dir calls getpwent, which can fall through to LDAP calls.
- ThreadRestrictions::AssertIOAllowed();
-
+ // g_get_home_dir calls getpwent, which can fall through to LDAP calls so
+ // this may do I/O. However, it should be rare that $HOME is not defined and
+ // this is typically called from the path service which has no threading
+ // restrictions. The path service will cache the result which limits the
+ // badness of blocking on I/O. As a result, we don't have a thread
+ // restriction here.
home_dir = g_get_home_dir();
if (home_dir && home_dir[0])
return FilePath(home_dir);
@@ -525,14 +504,6 @@ bool CreateTemporaryFile(FilePath* path) {
return true;
}
-FILE* CreateAndOpenTemporaryShmemFile(FilePath* path, bool executable) {
- FilePath directory;
- if (!GetShmemTempDir(executable, &directory))
- return NULL;
-
- return CreateAndOpenTemporaryFileInDir(directory, path);
-}
-
FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path) {
int fd = CreateAndOpenFdForTemporaryFile(dir, path);
if (fd < 0)
@@ -589,7 +560,7 @@ bool CreateNewTempDirectory(const FilePath::StringType& prefix,
}
bool CreateDirectoryAndGetError(const FilePath& full_path,
- PlatformFileError* error) {
+ File::Error* error) {
ThreadRestrictions::AssertIOAllowed(); // For call to mkdir().
std::vector<FilePath> subpaths;
@@ -616,7 +587,7 @@ bool CreateDirectoryAndGetError(const FilePath& full_path,
int saved_errno = errno;
if (!DirectoryExists(*i)) {
if (error)
- *error = ErrnoToPlatformFileError(saved_errno);
+ *error = File::OSErrorToFileError(saved_errno);
return false;
}
}
@@ -654,16 +625,14 @@ bool IsLink(const FilePath& file_path) {
return false;
}
-bool GetFileInfo(const FilePath& file_path, PlatformFileInfo* results) {
+bool GetFileInfo(const FilePath& file_path, File::Info* results) {
stat_wrapper_t file_info;
#if defined(OS_ANDROID)
if (file_path.IsContentUri()) {
- int fd = OpenContentUriForRead(file_path);
- if (fd < 0)
- return false;
- file_util::ScopedFD scoped_fd(&fd);
- if (CallFstat(fd, &file_info) != 0)
+ File file = OpenContentUriForRead(file_path);
+ if (!file.IsValid())
return false;
+ return file.GetInfo(results);
} else {
#endif // defined(OS_ANDROID)
if (CallStat(file_path.value().c_str(), &file_info) != 0)
@@ -671,21 +640,8 @@ bool GetFileInfo(const FilePath& file_path, PlatformFileInfo* results) {
#if defined(OS_ANDROID)
}
#endif // defined(OS_ANDROID)
- results->is_directory = S_ISDIR(file_info.st_mode);
- results->size = file_info.st_size;
-#if defined(OS_MACOSX)
- results->last_modified = Time::FromTimeSpec(file_info.st_mtimespec);
- results->last_accessed = Time::FromTimeSpec(file_info.st_atimespec);
- results->creation_time = Time::FromTimeSpec(file_info.st_ctimespec);
-#elif defined(OS_ANDROID)
- results->last_modified = Time::FromTimeT(file_info.st_mtime);
- results->last_accessed = Time::FromTimeT(file_info.st_atime);
- results->creation_time = Time::FromTimeT(file_info.st_ctime);
-#else
- results->last_modified = Time::FromTimeSpec(file_info.st_mtim);
- results->last_accessed = Time::FromTimeSpec(file_info.st_atim);
- results->creation_time = Time::FromTimeSpec(file_info.st_ctim);
-#endif
+
+ results->FromStat(file_info);
return true;
}
@@ -698,65 +654,37 @@ FILE* OpenFile(const FilePath& filename, const char* mode) {
return result;
}
-int ReadFile(const FilePath& filename, char* data, int size) {
+// NaCl doesn't implement system calls to open files directly.
+#if !defined(OS_NACL)
+FILE* FileToFILE(File file, const char* mode) {
+ FILE* stream = fdopen(file.GetPlatformFile(), mode);
+ if (stream)
+ file.TakePlatformFile();
+ return stream;
+}
+#endif // !defined(OS_NACL)
+
+int ReadFile(const FilePath& filename, char* data, int max_size) {
ThreadRestrictions::AssertIOAllowed();
int fd = HANDLE_EINTR(open(filename.value().c_str(), O_RDONLY));
if (fd < 0)
return -1;
- ssize_t bytes_read = HANDLE_EINTR(read(fd, data, size));
- if (int ret = IGNORE_EINTR(close(fd)) < 0)
- return ret;
+ ssize_t bytes_read = HANDLE_EINTR(read(fd, data, max_size));
+ if (IGNORE_EINTR(close(fd)) < 0)
+ return -1;
return bytes_read;
}
-} // namespace base
-
-// -----------------------------------------------------------------------------
-
-namespace file_util {
-
-using base::stat_wrapper_t;
-using base::CallStat;
-using base::CallLstat;
-using base::CreateAndOpenFdForTemporaryFile;
-using base::DirectoryExists;
-using base::FileEnumerator;
-using base::FilePath;
-using base::MakeAbsoluteFilePath;
-using base::VerifySpecificPathControlledByUser;
-
-base::FilePath MakeUniqueDirectory(const base::FilePath& path) {
- const int kMaxAttempts = 20;
- for (int attempts = 0; attempts < kMaxAttempts; attempts++) {
- int uniquifier =
- GetUniquePathNumber(path, base::FilePath::StringType());
- if (uniquifier < 0)
- break;
- base::FilePath test_path = (uniquifier == 0) ? path :
- path.InsertBeforeExtensionASCII(
- base::StringPrintf(" (%d)", uniquifier));
- if (mkdir(test_path.value().c_str(), 0777) == 0)
- return test_path;
- else if (errno != EEXIST)
- break;
- }
- return base::FilePath();
-}
-
-FILE* OpenFile(const std::string& filename, const char* mode) {
- return OpenFile(FilePath(filename), mode);
-}
-
int WriteFile(const FilePath& filename, const char* data, int size) {
- base::ThreadRestrictions::AssertIOAllowed();
- int fd = HANDLE_EINTR(creat(filename.value().c_str(), 0666));
+ ThreadRestrictions::AssertIOAllowed();
+ int fd = HANDLE_EINTR(creat(filename.value().c_str(), 0640));
if (fd < 0)
return -1;
int bytes_written = WriteFileDescriptor(fd, data, size);
- if (int ret = IGNORE_EINTR(close(fd)) < 0)
- return ret;
+ if (IGNORE_EINTR(close(fd)) < 0)
+ return -1;
return bytes_written;
}
@@ -776,21 +704,21 @@ int WriteFileDescriptor(const int fd, const char* data, int size) {
}
int AppendToFile(const FilePath& filename, const char* data, int size) {
- base::ThreadRestrictions::AssertIOAllowed();
+ ThreadRestrictions::AssertIOAllowed();
int fd = HANDLE_EINTR(open(filename.value().c_str(), O_WRONLY | O_APPEND));
if (fd < 0)
return -1;
int bytes_written = WriteFileDescriptor(fd, data, size);
- if (int ret = IGNORE_EINTR(close(fd)) < 0)
- return ret;
+ if (IGNORE_EINTR(close(fd)) < 0)
+ return -1;
return bytes_written;
}
// Gets the current working directory for the process.
bool GetCurrentDirectory(FilePath* dir) {
// getcwd can return ENOENT, which implies it checks against the disk.
- base::ThreadRestrictions::AssertIOAllowed();
+ ThreadRestrictions::AssertIOAllowed();
char system_buffer[PATH_MAX] = "";
if (!getcwd(system_buffer, sizeof(system_buffer))) {
@@ -803,7 +731,7 @@ bool GetCurrentDirectory(FilePath* dir) {
// Sets the current working directory for the process.
bool SetCurrentDirectory(const FilePath& path) {
- base::ThreadRestrictions::AssertIOAllowed();
+ ThreadRestrictions::AssertIOAllowed();
int ret = chdir(path.value().c_str());
return !ret;
}
@@ -859,7 +787,7 @@ bool VerifyPathControlledByAdmin(const FilePath& path) {
};
// Reading the groups database may touch the file system.
- base::ThreadRestrictions::AssertIOAllowed();
+ ThreadRestrictions::AssertIOAllowed();
std::set<gid_t> allowed_group_ids;
for (int i = 0, ie = arraysize(kAdminGroupNames); i < ie; ++i) {
@@ -879,13 +807,30 @@ bool VerifyPathControlledByAdmin(const FilePath& path) {
#endif // defined(OS_MACOSX) && !defined(OS_IOS)
int GetMaximumPathComponentLength(const FilePath& path) {
- base::ThreadRestrictions::AssertIOAllowed();
+ ThreadRestrictions::AssertIOAllowed();
return pathconf(path.value().c_str(), _PC_NAME_MAX);
}
-} // namespace file_util
+#if !defined(OS_ANDROID)
+// This is implemented in file_util_android.cc for that platform.
+bool GetShmemTempDir(bool executable, FilePath* path) {
+#if defined(OS_LINUX)
+ bool use_dev_shm = true;
+ if (executable) {
+ static const bool s_dev_shm_executable = DetermineDevShmExecutable();
+ use_dev_shm = s_dev_shm_executable;
+ }
+ if (use_dev_shm) {
+ *path = FilePath("/dev/shm");
+ return true;
+ }
+#endif
+ return GetTempDir(path);
+}
+#endif // !defined(OS_ANDROID)
+
+// -----------------------------------------------------------------------------
-namespace base {
namespace internal {
bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) {