1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_util.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <dirent.h> 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <errno.h> 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <fcntl.h> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <fnmatch.h> 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <libgen.h> 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <limits.h> 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdio.h> 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <stdlib.h> 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string.h> 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/errno.h> 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/mman.h> 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <sys/param.h> 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/stat.h> 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <sys/time.h> 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/types.h> 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <time.h> 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <unistd.h> 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_MACOSX) 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <AvailabilityMacros.h> 2700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#elif !defined(ANDROID) 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <glib.h> 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <fstream> 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/eintr_wrapper.h" 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_path.h" 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h" 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/sys_string_conversions.h" 413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread_restrictions.h" 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/time.h" 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/utf_string_conversions.h" 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace file_util { 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Helper for NormalizeFilePath(), defined below. 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool RealPath(const FilePath& path, FilePath* real_path) { 51513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); // For realpath(). 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath::CharType buf[PATH_MAX]; 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!realpath(path.value().c_str(), buf)) 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *real_path = FilePath(buf); 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_OPENBSD) || defined(OS_FREEBSD) || \ 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (defined(OS_MACOSX) && \ 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef struct stat stat_wrapper_t; 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int CallStat(const char *path, stat_wrapper_t *sb) { 67513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return stat(path, sb); 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef struct stat64 stat_wrapper_t; 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int CallStat(const char *path, stat_wrapper_t *sb) { 73513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return stat64(path, sb); 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(GOOGLE_CHROME_BUILD) 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char* kTempFileName = ".com.google.chrome.XXXXXX"; 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char* kTempFileName = ".org.chromium.XXXXXX"; 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool AbsolutePath(FilePath* path) { 86513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); // For realpath(). 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char full_path[PATH_MAX]; 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (realpath(path->value().c_str(), full_path) == NULL) 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *path = FilePath(full_path); 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint CountFilesCreatedAfter(const FilePath& path, 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const base::Time& comparison_time) { 96513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int file_count = 0; 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DIR* dir = opendir(path.value().c_str()); 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (dir) { 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_FREEBSD) && \ 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !defined(OS_OPENBSD) && !defined(OS_SOLARIS) 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott #error Port warning: depending on the definition of struct dirent, \ 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott additional space for pathname may be needed 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct dirent ent_buf; 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct dirent* ent; 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (readdir_r(dir, &ent_buf, &ent) == 0 && ent) { 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if ((strcmp(ent->d_name, ".") == 0) || 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (strcmp(ent->d_name, "..") == 0)) 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stat_wrapper_t st; 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int test = CallStat(path.Append(ent->d_name).value().c_str(), &st); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test != 0) { 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PLOG(ERROR) << "stat64 failed"; 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Here, we use Time::TimeT(), which discards microseconds. This 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // means that files which are newer than |comparison_time| may 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be considered older. If we don't discard microseconds, it 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // introduces another issue. Suppose the following case: 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 1. Get |comparison_time| by Time::Now() and the value is 10.1 (secs). 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 2. Create a file and the current time is 10.3 (secs). 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // As POSIX doesn't have microsecond precision for |st_ctime|, 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the creation time of the file created in the step 2 is 10 and 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the file is considered older than |comparison_time|. After 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // all, we may have to accept either of the two issues: 1. files 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // which are older than |comparison_time| are considered newer 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (current implementation) 2. files newer than 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |comparison_time| are considered older. 1344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (static_cast<time_t>(st.st_ctime) >= comparison_time.ToTimeT()) 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++file_count; 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott closedir(dir); 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return file_count; 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*" 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// which works both with and without the recursive flag. I'm not sure we need 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// that functionality. If not, remove from file_util_win.cc, otherwise add it 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// here. 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Delete(const FilePath& path, bool recursive) { 147513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* path_str = path.value().c_str(); 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stat_wrapper_t file_info; 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int test = CallStat(path_str, &file_info); 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test != 0) { 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The Windows version defines this condition as success. 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ret = (errno == ENOENT || errno == ENOTDIR); 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ret; 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!S_ISDIR(file_info.st_mode)) 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (unlink(path_str) == 0); 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!recursive) 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (rmdir(path_str) == 0); 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool success = true; 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::stack<std::string> directories; 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott directories.push(path.value()); 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FileEnumerator traversal(path, true, static_cast<FileEnumerator::FILE_TYPE>( 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FileEnumerator::FILES | FileEnumerator::DIRECTORIES | 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FileEnumerator::SHOW_SYM_LINKS)); 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (FilePath current = traversal.Next(); success && !current.empty(); 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott current = traversal.Next()) { 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FileEnumerator::FindInfo info; 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott traversal.GetFindInfo(&info); 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (S_ISDIR(info.stat.st_mode)) 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott directories.push(current.value()); 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott success = (unlink(current.value().c_str()) == 0); 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (success && !directories.empty()) { 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath dir = FilePath(directories.top()); 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott directories.pop(); 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott success = (rmdir(dir.value().c_str()) == 0); 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return success; 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Move(const FilePath& from_path, const FilePath& to_path) { 187513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Windows compatibility: if to_path exists, from_path and to_path 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // must be the same type, either both files, or both directories. 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stat_wrapper_t to_file_info; 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (CallStat(to_path.value().c_str(), &to_file_info) == 0) { 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stat_wrapper_t from_file_info; 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (CallStat(from_path.value().c_str(), &from_file_info) == 0) { 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (S_ISDIR(to_file_info.st_mode) != S_ISDIR(from_file_info.st_mode)) 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0) 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!CopyDirectory(from_path, to_path, true)) 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Delete(from_path, true); 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ReplaceFile(const FilePath& from_path, const FilePath& to_path) { 212513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (rename(from_path.value().c_str(), to_path.value().c_str()) == 0); 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool CopyDirectory(const FilePath& from_path, 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const FilePath& to_path, 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool recursive) { 219513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Some old callers of CopyDirectory want it to support wildcards. 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After some discussion, we decided to fix those callers. 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Break loudly here if anyone tries to do this. 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(evanm): remove this once we're sure it's ok. 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(to_path.value().find('*') == std::string::npos); 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(from_path.value().find('*') == std::string::npos); 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char top_dir[PATH_MAX]; 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (base::strlcpy(top_dir, from_path.value().c_str(), 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott arraysize(top_dir)) >= arraysize(top_dir)) { 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This function does not properly handle destinations within the source 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath real_to_path = to_path; 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (PathExists(real_to_path)) { 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!AbsolutePath(&real_to_path)) 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott real_to_path = real_to_path.DirName(); 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!AbsolutePath(&real_to_path)) 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath real_from_path = from_path; 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!AbsolutePath(&real_from_path)) 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (real_to_path.value().size() >= real_from_path.value().size() && 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott real_to_path.value().compare(0, real_from_path.value().size(), 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott real_from_path.value()) == 0) 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool success = true; 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FileEnumerator::FILE_TYPE traverse_type = 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static_cast<FileEnumerator::FILE_TYPE>(FileEnumerator::FILES | 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FileEnumerator::SHOW_SYM_LINKS); 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (recursive) 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott traverse_type = static_cast<FileEnumerator::FILE_TYPE>( 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott traverse_type | FileEnumerator::DIRECTORIES); 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FileEnumerator traversal(from_path, recursive, traverse_type); 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We have to mimic windows behavior here. |to_path| may not exist yet, 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // start the loop with |to_path|. 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FileEnumerator::FindInfo info; 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath current = from_path; 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (stat(from_path.value().c_str(), &info.stat) < 0) { 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "CopyDirectory() couldn't stat source directory: " << 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott from_path.value() << " errno = " << errno; 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott success = false; 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct stat to_path_stat; 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath from_path_base = from_path; 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (recursive && stat(to_path.value().c_str(), &to_path_stat) == 0 && 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott S_ISDIR(to_path_stat.st_mode)) { 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the destination already exists and is a directory, then the 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // top level of source needs to be copied. 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott from_path_base = from_path.DirName(); 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The Windows version of this function assumes that non-recursive calls 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // will always have a directory for from_path. 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(recursive || S_ISDIR(info.stat.st_mode)); 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (success && !current.empty()) { 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // current is the source path, including from_path, so paste 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the suffix after from_path onto to_path to create the target_path. 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string suffix(¤t.value().c_str()[from_path_base.value().size()]); 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Strip the leading '/' (if any). 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!suffix.empty()) { 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK_EQ('/', suffix[0]); 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott suffix.erase(0, 1); 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const FilePath target_path = to_path.Append(suffix); 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (S_ISDIR(info.stat.st_mode)) { 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (mkdir(target_path.value().c_str(), info.stat.st_mode & 01777) != 0 && 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott errno != EEXIST) { 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "CopyDirectory() couldn't create directory: " << 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott target_path.value() << " errno = " << errno; 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott success = false; 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (S_ISREG(info.stat.st_mode)) { 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!CopyFile(current, target_path)) { 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "CopyDirectory() couldn't create file: " << 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott target_path.value(); 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott success = false; 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(WARNING) << "CopyDirectory() skipping non-regular file: " << 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott current.value(); 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott current = traversal.Next(); 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott traversal.GetFindInfo(&info); 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return success; 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool PathExists(const FilePath& path) { 319513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return access(path.value().c_str(), F_OK) == 0; 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool PathIsWritable(const FilePath& path) { 324513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return access(path.value().c_str(), W_OK) == 0; 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool DirectoryExists(const FilePath& path) { 329513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stat_wrapper_t file_info; 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (CallStat(path.value().c_str(), &file_info) == 0) 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return S_ISDIR(file_info.st_mode); 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// TODO(erikkay): implement 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if 0 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool GetFileCreationLocalTimeFromHandle(int fd, 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LPSYSTEMTIME creation_time) { 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file_handle) 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILETIME utc_filetime; 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!GetFileTime(file_handle, &utc_filetime, NULL, NULL)) 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILETIME local_filetime; 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!FileTimeToLocalFileTime(&utc_filetime, &local_filetime)) 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return !!FileTimeToSystemTime(&local_filetime, creation_time); 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool GetFileCreationLocalTime(const std::string& filename, 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LPSYSTEMTIME creation_time) { 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ScopedHandle file_handle( 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CreateFile(filename.c_str(), GENERIC_READ, 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return GetFileCreationLocalTimeFromHandle(file_handle.Get(), creation_time); 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ReadFromFD(int fd, char* buffer, size_t bytes) { 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t total_read = 0; 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (total_read < bytes) { 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ssize_t bytes_read = 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HANDLE_EINTR(read(fd, buffer + total_read, bytes - total_read)); 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (bytes_read <= 0) 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott total_read += bytes_read; 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return total_read == bytes; 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 376201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool CreateSymbolicLink(const FilePath& target_path, 377201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const FilePath& symlink_path) { 378201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(!symlink_path.empty()); 379201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(!target_path.empty()); 380201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return ::symlink(target_path.value().c_str(), 381201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch symlink_path.value().c_str()) != -1; 382201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 383201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 384201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool ReadSymbolicLink(const FilePath& symlink_path, 385201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch FilePath* target_path) { 386201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(!symlink_path.empty()); 387201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(target_path); 388201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch char buf[PATH_MAX]; 389201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ssize_t count = ::readlink(symlink_path.value().c_str(), buf, arraysize(buf)); 390201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 39121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (count <= 0) { 39221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen target_path->clear(); 393201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return false; 39421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 395201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 396201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch *target_path = FilePath(FilePath::StringType(buf, count)); 397201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return true; 398201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 399201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Creates and opens a temporary file in |directory|, returning the 401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// file descriptor. |path| is set to the temporary file path. 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This function does NOT unlink() the file. 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint CreateAndOpenFdForTemporaryFile(FilePath directory, FilePath* path) { 404513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); // For call to mkstemp(). 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *path = directory.Append(kTempFileName); 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& tmpdir_string = path->value(); 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // this should be OK since mkstemp just replaces characters in place 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char* buffer = const_cast<char*>(tmpdir_string.c_str()); 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return HANDLE_EINTR(mkstemp(buffer)); 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool CreateTemporaryFile(FilePath* path) { 414513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); // For call to close(). 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath directory; 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!GetTempDir(&directory)) 417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd = CreateAndOpenFdForTemporaryFile(directory, path); 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (fd < 0) 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ignore_result(HANDLE_EINTR(close(fd))); 422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFILE* CreateAndOpenTemporaryShmemFile(FilePath* path) { 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath directory; 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!GetShmemTempDir(&directory)) 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return CreateAndOpenTemporaryFileInDir(directory, path); 431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path) { 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd = CreateAndOpenFdForTemporaryFile(dir, path); 435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (fd < 0) 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FILE* file = fdopen(fd, "a+"); 439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!file) 440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ignore_result(HANDLE_EINTR(close(fd))); 441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return file; 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool CreateTemporaryFileInDir(const FilePath& dir, FilePath* temp_file) { 445513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); // For call to close(). 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd = CreateAndOpenFdForTemporaryFile(dir, temp_file); 447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ((fd >= 0) && !HANDLE_EINTR(close(fd))); 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic bool CreateTemporaryDirInDirImpl(const FilePath& base_dir, 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FilePath::StringType& name_tmpl, 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath* new_dir) { 453513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); // For call to mkdtemp(). 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(name_tmpl.find("XXXXXX") != FilePath::StringType::npos) 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "Directory name template must contain \"XXXXXX\"."; 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath sub_dir = base_dir.Append(name_tmpl); 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string sub_dir_string = sub_dir.value(); 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // this should be OK since mkdtemp just replaces characters in place 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* buffer = const_cast<char*>(sub_dir_string.c_str()); 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char* dtemp = mkdtemp(buffer); 4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!dtemp) { 4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DPLOG(ERROR) << "mkdtemp"; 465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *new_dir = FilePath(dtemp); 468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CreateTemporaryDirInDir(const FilePath& base_dir, 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FilePath::StringType& prefix, 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath* new_dir) { 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath::StringType mkdtemp_template = prefix; 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mkdtemp_template.append(FILE_PATH_LITERAL("XXXXXX")); 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return CreateTemporaryDirInDirImpl(base_dir, mkdtemp_template, new_dir); 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CreateNewTempDirectory(const FilePath::StringType& prefix, 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath* new_temp_path) { 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath tmpdir; 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!GetTempDir(&tmpdir)) 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return CreateTemporaryDirInDirImpl(tmpdir, kTempFileName, new_temp_path); 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool CreateDirectory(const FilePath& full_path) { 489513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); // For call to mkdir(). 490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::vector<FilePath> subpaths; 491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Collect a list of all parent directories. 493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath last_path = full_path; 494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott subpaths.push_back(full_path); 495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (FilePath path = full_path.DirName(); 496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott path.value() != last_path.value(); path = path.DirName()) { 497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott subpaths.push_back(path); 498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott last_path = path; 499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Iterate through the parents and create the missing ones. 502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (std::vector<FilePath>::reverse_iterator i = subpaths.rbegin(); 503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott i != subpaths.rend(); ++i) { 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (DirectoryExists(*i)) 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch continue; 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (mkdir(i->value().c_str(), 0700) == 0) 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch continue; 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Mkdir failed, but it might have failed with EEXIST, or some other error 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // due to the the directory appearing out of thin air. This can occur if 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // two processes are trying to create the same file system tree at the same 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // time. Check to see if it exists and make sure it is a directory. 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!DirectoryExists(*i)) 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool GetFileInfo(const FilePath& file_path, base::PlatformFileInfo* results) { 519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stat_wrapper_t file_info; 520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (CallStat(file_path.value().c_str(), &file_info) != 0) 521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott results->is_directory = S_ISDIR(file_info.st_mode); 523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott results->size = file_info.st_size; 524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott results->last_modified = base::Time::FromTimeT(file_info.st_mtime); 5253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick results->last_accessed = base::Time::FromTimeT(file_info.st_atime); 5263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick results->creation_time = base::Time::FromTimeT(file_info.st_ctime); 527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool GetInode(const FilePath& path, ino_t* inode) { 531513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); // For call to stat(). 532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct stat buffer; 533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int result = stat(path.value().c_str(), &buffer); 534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result < 0) 535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *inode = buffer.st_ino; 538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFILE* OpenFile(const std::string& filename, const char* mode) { 542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return OpenFile(FilePath(filename), mode); 543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFILE* OpenFile(const FilePath& filename, const char* mode) { 546513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 547ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FILE* result = NULL; 548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen do { 549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result = fopen(filename.value().c_str(), mode); 550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } while (!result && errno == EINTR); 551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result; 552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint ReadFile(const FilePath& filename, char* data, int size) { 555513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int fd = HANDLE_EINTR(open(filename.value().c_str(), O_RDONLY)); 557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (fd < 0) 558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ssize_t bytes_read = HANDLE_EINTR(read(fd, data, size)); 561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (int ret = HANDLE_EINTR(close(fd)) < 0) 562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ret; 563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return bytes_read; 564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint WriteFile(const FilePath& filename, const char* data, int size) { 567513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int fd = HANDLE_EINTR(creat(filename.value().c_str(), 0666)); 569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (fd < 0) 570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int bytes_written = WriteFileDescriptor(fd, data, size); 573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (int ret = HANDLE_EINTR(close(fd)) < 0) 574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ret; 575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return bytes_written; 576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint WriteFileDescriptor(const int fd, const char* data, int size) { 579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Allow for partial writes. 580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ssize_t bytes_written_total = 0; 581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (ssize_t bytes_written_partial = 0; bytes_written_total < size; 582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bytes_written_total += bytes_written_partial) { 583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bytes_written_partial = 584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HANDLE_EINTR(write(fd, data + bytes_written_total, 585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size - bytes_written_total)); 586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (bytes_written_partial < 0) 587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return bytes_written_total; 591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Gets the current working directory for the process. 594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool GetCurrentDirectory(FilePath* dir) { 595513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // getcwd can return ENOENT, which implies it checks against the disk. 596513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 597513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char system_buffer[PATH_MAX] = ""; 599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!getcwd(system_buffer, sizeof(system_buffer))) { 600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *dir = FilePath(system_buffer); 604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Sets the current working directory for the process. 608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool SetCurrentDirectory(const FilePath& path) { 609513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int ret = chdir(path.value().c_str()); 611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return !ret; 612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/////////////////////////////////////////////// 615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// FileEnumerator 616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFileEnumerator::FileEnumerator(const FilePath& root_path, 618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool recursive, 619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FileEnumerator::FILE_TYPE file_type) 620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : current_directory_entry_(0), 621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott root_path_(root_path), 622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott recursive_(recursive), 623731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick file_type_(file_type) { 624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // INCLUDE_DOT_DOT must not be specified if recursive. 625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_))); 626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_paths_.push(root_path); 627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFileEnumerator::FileEnumerator(const FilePath& root_path, 630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool recursive, 631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FileEnumerator::FILE_TYPE file_type, 632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const FilePath::StringType& pattern) 633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : current_directory_entry_(0), 634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott root_path_(root_path), 635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott recursive_(recursive), 636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file_type_(file_type), 637731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pattern_(root_path.Append(pattern).value()) { 638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // INCLUDE_DOT_DOT must not be specified if recursive. 639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_))); 640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The Windows version of this code appends the pattern to the root_path, 641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // potentially only matching against items in the top-most directory. 642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Do the same here. 643dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (pattern.empty()) 644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pattern_ = FilePath::StringType(); 645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_paths_.push(root_path); 646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFileEnumerator::~FileEnumerator() { 649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFilePath FileEnumerator::Next() { 652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++current_directory_entry_; 653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // While we've exhausted the entries in the current directory, do the next 655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (current_directory_entry_ >= directory_entries_.size()) { 656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (pending_paths_.empty()) 657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return FilePath(); 658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott root_path_ = pending_paths_.top(); 660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott root_path_ = root_path_.StripTrailingSeparators(); 661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_paths_.pop(); 662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::vector<DirectoryEntryInfo> entries; 664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ReadDirectory(&entries, root_path_, file_type_ & SHOW_SYM_LINKS)) 665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott directory_entries_.clear(); 668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott current_directory_entry_ = 0; 669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (std::vector<DirectoryEntryInfo>::const_iterator 670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott i = entries.begin(); i != entries.end(); ++i) { 671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath full_path = root_path_.Append(i->filename); 672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ShouldSkip(full_path)) 673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (pattern_.size() && 676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fnmatch(pattern_.c_str(), full_path.value().c_str(), FNM_NOESCAPE)) 677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (recursive_ && S_ISDIR(i->stat.st_mode)) 680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_paths_.push(full_path); 681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if ((S_ISDIR(i->stat.st_mode) && (file_type_ & DIRECTORIES)) || 683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (!S_ISDIR(i->stat.st_mode) && (file_type_ & FILES))) 684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott directory_entries_.push_back(*i); 685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return root_path_.Append(directory_entries_[current_directory_entry_ 689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ].filename); 690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 69272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid FileEnumerator::GetFindInfo(FindInfo* info) { 69372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(info); 69472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 69572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (current_directory_entry_ >= directory_entries_.size()) 69672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 69772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 69872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DirectoryEntryInfo* cur_entry = &directory_entries_[current_directory_entry_]; 69972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen memcpy(&(info->stat), &(cur_entry->stat), sizeof(info->stat)); 70072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen info->filename.assign(cur_entry->filename.value()); 70172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 70272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 70372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool FileEnumerator::IsDirectory(const FindInfo& info) { 70472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return S_ISDIR(info.stat.st_mode); 70572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 70672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 70772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static 70872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenFilePath FileEnumerator::GetFilename(const FindInfo& find_info) { 70972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return FilePath(find_info.filename); 71072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 71172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool FileEnumerator::ReadDirectory(std::vector<DirectoryEntryInfo>* entries, 713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const FilePath& source, bool show_links) { 714513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DIR* dir = opendir(source.value().c_str()); 716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!dir) 717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_FREEBSD) && \ 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !defined(OS_OPENBSD) && !defined(OS_SOLARIS) 721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott #error Port warning: depending on the definition of struct dirent, \ 722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott additional space for pathname may be needed 723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct dirent dent_buf; 726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct dirent* dent; 727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (readdir_r(dir, &dent_buf, &dent) == 0 && dent) { 728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DirectoryEntryInfo info; 729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott info.filename = FilePath(dent->d_name); 730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath full_name = source.Append(dent->d_name); 732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int ret; 733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (show_links) 734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ret = lstat(full_name.value().c_str(), &info.stat); 735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ret = stat(full_name.value().c_str(), &info.stat); 737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ret < 0) { 738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Print the stat() error message unless it was ENOENT and we're 739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // following symlinks. 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!(errno == ENOENT && !show_links)) { 741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PLOG(ERROR) << "Couldn't stat " 742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott << source.Append(dent->d_name).value(); 743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&info.stat, 0, sizeof(info.stat)); 745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entries->push_back(info); 747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott closedir(dir); 750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/////////////////////////////////////////////// 754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MemoryMappedFile 755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottMemoryMappedFile::MemoryMappedFile() 757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : file_(base::kInvalidPlatformFileValue), 758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_(NULL), 759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott length_(0) { 760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MemoryMappedFile::MapFileToMemoryInternal() { 763513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 764513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct stat file_stat; 766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (fstat(file_, &file_stat) == base::kInvalidPlatformFileValue) { 767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Couldn't fstat " << file_ << ", errno " << errno; 768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott length_ = file_stat.st_size; 771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_ = static_cast<uint8*>( 773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mmap(NULL, length_, PROT_READ, MAP_SHARED, file_, 0)); 774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data_ == MAP_FAILED) 775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Couldn't mmap " << file_ << ", errno " << errno; 776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return data_ != MAP_FAILED; 778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MemoryMappedFile::CloseHandles() { 781513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 782513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data_ != NULL) 784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott munmap(data_, length_); 785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (file_ != base::kInvalidPlatformFileValue) 786ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ignore_result(HANDLE_EINTR(close(file_))); 787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_ = NULL; 789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott length_ = 0; 790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file_ = base::kInvalidPlatformFileValue; 791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info, 794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const base::Time& cutoff_time) { 7954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return static_cast<time_t>(find_info.stat.st_mtime) >= cutoff_time.ToTimeT(); 796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NormalizeFilePath(const FilePath& path, FilePath* normalized_path) { 799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath real_path_result; 800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!RealPath(path, &real_path_result)) 801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // To be consistant with windows, fail if |real_path_result| is a 804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // directory. 805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch stat_wrapper_t file_info; 806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (CallStat(real_path_result.value().c_str(), &file_info) != 0 || 807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch S_ISDIR(file_info.st_mode)) 808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *normalized_path = real_path_result; 811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_MACOSX) 815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool GetTempDir(FilePath* path) { 816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* tmp = getenv("TMPDIR"); 817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tmp) 818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *path = FilePath(tmp); 819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *path = FilePath("/tmp"); 821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool GetShmemTempDir(FilePath* path) { 825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *path = FilePath("/dev/shm"); 826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 829c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFilePath GetHomeDir() { 83000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#ifndef ANDROID 831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* home_dir = getenv("HOME"); 832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (home_dir && home_dir[0]) 833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FilePath(home_dir); 834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 835513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // g_get_home_dir calls getpwent, which can fall through to LDAP calls. 836513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 837513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch home_dir = g_get_home_dir(); 839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (home_dir && home_dir[0]) 840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FilePath(home_dir); 841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath rv; 843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (file_util::GetTempDir(&rv)) 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return rv; 84500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#endif 846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Last resort. 847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FilePath("/tmp"); 848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CopyFile(const FilePath& from_path, const FilePath& to_path) { 851513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 852ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int infile = HANDLE_EINTR(open(from_path.value().c_str(), O_RDONLY)); 853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (infile < 0) 854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 856ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int outfile = HANDLE_EINTR(creat(to_path.value().c_str(), 0666)); 857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (outfile < 0) { 858ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ignore_result(HANDLE_EINTR(close(infile))); 859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t kBufferSize = 32768; 863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<char> buffer(kBufferSize); 864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool result = true; 865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (result) { 867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssize_t bytes_read = HANDLE_EINTR(read(infile, &buffer[0], buffer.size())); 868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bytes_read < 0) { 869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result = false; 870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bytes_read == 0) 873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Allow for partial writes 875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssize_t bytes_written_per_read = 0; 876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch do { 877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssize_t bytes_written_partial = HANDLE_EINTR(write( 878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch outfile, 879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &buffer[bytes_written_per_read], 880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bytes_read - bytes_written_per_read)); 881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bytes_written_partial < 0) { 882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result = false; 883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bytes_written_per_read += bytes_written_partial; 886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (bytes_written_per_read < bytes_read); 887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (HANDLE_EINTR(close(infile)) < 0) 890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result = false; 891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (HANDLE_EINTR(close(outfile)) < 0) 892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result = false; 893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result; 895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // defined(OS_MACOSX) 897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 898201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} // namespace file_util 899