| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/file_util.h" | 5 #include "base/file_util.h" |
| 6 | 6 |
| 7 #include <dirent.h> | 7 #include <dirent.h> |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <fcntl.h> | 9 #include <fcntl.h> |
| 10 #include <libgen.h> | 10 #include <libgen.h> |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 #include "base/chromeos/chromeos_version.h" | 58 #include "base/chromeos/chromeos_version.h" |
| 59 #endif | 59 #endif |
| 60 | 60 |
| 61 namespace base { | 61 namespace base { |
| 62 | 62 |
| 63 namespace { | 63 namespace { |
| 64 | 64 |
| 65 #if defined(OS_BSD) || defined(OS_MACOSX) | 65 #if defined(OS_BSD) || defined(OS_MACOSX) |
| 66 typedef struct stat stat_wrapper_t; | 66 typedef struct stat stat_wrapper_t; |
| 67 static int CallStat(const char *path, stat_wrapper_t *sb) { | 67 static int CallStat(const char *path, stat_wrapper_t *sb) { |
| 68 base::ThreadRestrictions::AssertIOAllowed(); | 68 ThreadRestrictions::AssertIOAllowed(); |
| 69 return stat(path, sb); | 69 return stat(path, sb); |
| 70 } | 70 } |
| 71 static int CallLstat(const char *path, stat_wrapper_t *sb) { | 71 static int CallLstat(const char *path, stat_wrapper_t *sb) { |
| 72 base::ThreadRestrictions::AssertIOAllowed(); | 72 ThreadRestrictions::AssertIOAllowed(); |
| 73 return lstat(path, sb); | 73 return lstat(path, sb); |
| 74 } | 74 } |
| 75 #else | 75 #else |
| 76 typedef struct stat64 stat_wrapper_t; | 76 typedef struct stat64 stat_wrapper_t; |
| 77 static int CallStat(const char *path, stat_wrapper_t *sb) { | 77 static int CallStat(const char *path, stat_wrapper_t *sb) { |
| 78 base::ThreadRestrictions::AssertIOAllowed(); | 78 ThreadRestrictions::AssertIOAllowed(); |
| 79 return stat64(path, sb); | 79 return stat64(path, sb); |
| 80 } | 80 } |
| 81 static int CallLstat(const char *path, stat_wrapper_t *sb) { | 81 static int CallLstat(const char *path, stat_wrapper_t *sb) { |
| 82 base::ThreadRestrictions::AssertIOAllowed(); | 82 ThreadRestrictions::AssertIOAllowed(); |
| 83 return lstat64(path, sb); | 83 return lstat64(path, sb); |
| 84 } | 84 } |
| 85 #endif | 85 #endif |
| 86 | 86 |
| 87 // Helper for NormalizeFilePath(), defined below. | 87 // Helper for NormalizeFilePath(), defined below. |
| 88 bool RealPath(const FilePath& path, FilePath* real_path) { | 88 bool RealPath(const FilePath& path, FilePath* real_path) { |
| 89 base::ThreadRestrictions::AssertIOAllowed(); // For realpath(). | 89 ThreadRestrictions::AssertIOAllowed(); // For realpath(). |
| 90 FilePath::CharType buf[PATH_MAX]; | 90 FilePath::CharType buf[PATH_MAX]; |
| 91 if (!realpath(path.value().c_str(), buf)) | 91 if (!realpath(path.value().c_str(), buf)) |
| 92 return false; | 92 return false; |
| 93 | 93 |
| 94 *real_path = FilePath(buf); | 94 *real_path = FilePath(buf); |
| 95 return true; | 95 return true; |
| 96 } | 96 } |
| 97 | 97 |
| 98 // Helper for VerifyPathControlledByUser. | 98 // Helper for VerifyPathControlledByUser. |
| 99 bool VerifySpecificPathControlledByUser(const FilePath& path, | 99 bool VerifySpecificPathControlledByUser(const FilePath& path, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 127 | 127 |
| 128 if (stat_info.st_mode & S_IWOTH) { | 128 if (stat_info.st_mode & S_IWOTH) { |
| 129 DLOG(ERROR) << "Path " << path.value() | 129 DLOG(ERROR) << "Path " << path.value() |
| 130 << " is writable by any user."; | 130 << " is writable by any user."; |
| 131 return false; | 131 return false; |
| 132 } | 132 } |
| 133 | 133 |
| 134 return true; | 134 return true; |
| 135 } | 135 } |
| 136 | 136 |
| 137 std::string TempFileName() { |
| 138 #if defined(OS_MACOSX) |
| 139 return StringPrintf(".%s.XXXXXX", base::mac::BaseBundleID()); |
| 140 #endif |
| 141 |
| 142 #if defined(GOOGLE_CHROME_BUILD) |
| 143 return std::string(".com.google.Chrome.XXXXXX"); |
| 144 #else |
| 145 return std::string(".org.chromium.Chromium.XXXXXX"); |
| 146 #endif |
| 147 } |
| 148 |
| 137 } // namespace | 149 } // namespace |
| 138 | 150 |
| 139 FilePath MakeAbsoluteFilePath(const FilePath& input) { | 151 FilePath MakeAbsoluteFilePath(const FilePath& input) { |
| 140 ThreadRestrictions::AssertIOAllowed(); | 152 ThreadRestrictions::AssertIOAllowed(); |
| 141 char full_path[PATH_MAX]; | 153 char full_path[PATH_MAX]; |
| 142 if (realpath(input.value().c_str(), full_path) == NULL) | 154 if (realpath(input.value().c_str(), full_path) == NULL) |
| 143 return FilePath(); | 155 return FilePath(); |
| 144 return FilePath(full_path); | 156 return FilePath(full_path); |
| 145 } | 157 } |
| 146 | 158 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 } | 190 } |
| 179 | 191 |
| 180 while (success && !directories.empty()) { | 192 while (success && !directories.empty()) { |
| 181 FilePath dir = FilePath(directories.top()); | 193 FilePath dir = FilePath(directories.top()); |
| 182 directories.pop(); | 194 directories.pop(); |
| 183 success = (rmdir(dir.value().c_str()) == 0); | 195 success = (rmdir(dir.value().c_str()) == 0); |
| 184 } | 196 } |
| 185 return success; | 197 return success; |
| 186 } | 198 } |
| 187 | 199 |
| 188 } // namespace base | |
| 189 | |
| 190 // ----------------------------------------------------------------------------- | |
| 191 | |
| 192 namespace file_util { | |
| 193 | |
| 194 using base::stat_wrapper_t; | |
| 195 using base::CallStat; | |
| 196 using base::CallLstat; | |
| 197 using base::FileEnumerator; | |
| 198 using base::FilePath; | |
| 199 using base::MakeAbsoluteFilePath; | |
| 200 using base::RealPath; | |
| 201 using base::VerifySpecificPathControlledByUser; | |
| 202 | |
| 203 static std::string TempFileName() { | |
| 204 #if defined(OS_MACOSX) | |
| 205 return base::StringPrintf(".%s.XXXXXX", base::mac::BaseBundleID()); | |
| 206 #endif | |
| 207 | |
| 208 #if defined(GOOGLE_CHROME_BUILD) | |
| 209 return std::string(".com.google.Chrome.XXXXXX"); | |
| 210 #else | |
| 211 return std::string(".org.chromium.Chromium.XXXXXX"); | |
| 212 #endif | |
| 213 } | |
| 214 | |
| 215 bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) { | 200 bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) { |
| 216 base::ThreadRestrictions::AssertIOAllowed(); | 201 ThreadRestrictions::AssertIOAllowed(); |
| 217 // Windows compatibility: if to_path exists, from_path and to_path | 202 // Windows compatibility: if to_path exists, from_path and to_path |
| 218 // must be the same type, either both files, or both directories. | 203 // must be the same type, either both files, or both directories. |
| 219 stat_wrapper_t to_file_info; | 204 stat_wrapper_t to_file_info; |
| 220 if (CallStat(to_path.value().c_str(), &to_file_info) == 0) { | 205 if (CallStat(to_path.value().c_str(), &to_file_info) == 0) { |
| 221 stat_wrapper_t from_file_info; | 206 stat_wrapper_t from_file_info; |
| 222 if (CallStat(from_path.value().c_str(), &from_file_info) == 0) { | 207 if (CallStat(from_path.value().c_str(), &from_file_info) == 0) { |
| 223 if (S_ISDIR(to_file_info.st_mode) != S_ISDIR(from_file_info.st_mode)) | 208 if (S_ISDIR(to_file_info.st_mode) != S_ISDIR(from_file_info.st_mode)) |
| 224 return false; | 209 return false; |
| 225 } else { | 210 } else { |
| 226 return false; | 211 return false; |
| 227 } | 212 } |
| 228 } | 213 } |
| 229 | 214 |
| 230 if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0) | 215 if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0) |
| 231 return true; | 216 return true; |
| 232 | 217 |
| 233 if (!CopyDirectory(from_path, to_path, true)) | 218 if (!file_util::CopyDirectory(from_path, to_path, true)) |
| 234 return false; | 219 return false; |
| 235 | 220 |
| 236 Delete(from_path, true); | 221 Delete(from_path, true); |
| 237 return true; | 222 return true; |
| 238 } | 223 } |
| 239 | 224 |
| 240 bool ReplaceFileAndGetError(const FilePath& from_path, | 225 bool ReplaceFile(const FilePath& from_path, |
| 241 const FilePath& to_path, | 226 const FilePath& to_path, |
| 242 base::PlatformFileError* error) { | 227 PlatformFileError* error) { |
| 243 base::ThreadRestrictions::AssertIOAllowed(); | 228 ThreadRestrictions::AssertIOAllowed(); |
| 244 if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0) | 229 if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0) |
| 245 return true; | 230 return true; |
| 246 if (error) | 231 if (error) |
| 247 *error = base::ErrnoToPlatformFileError(errno); | 232 *error = ErrnoToPlatformFileError(errno); |
| 248 return false; | 233 return false; |
| 249 } | 234 } |
| 250 | 235 |
| 236 } // namespace base |
| 237 |
| 238 // ----------------------------------------------------------------------------- |
| 239 |
| 240 namespace file_util { |
| 241 |
| 242 using base::stat_wrapper_t; |
| 243 using base::CallStat; |
| 244 using base::CallLstat; |
| 245 using base::FileEnumerator; |
| 246 using base::FilePath; |
| 247 using base::MakeAbsoluteFilePath; |
| 248 using base::RealPath; |
| 249 using base::VerifySpecificPathControlledByUser; |
| 250 |
| 251 bool CopyDirectory(const FilePath& from_path, | 251 bool CopyDirectory(const FilePath& from_path, |
| 252 const FilePath& to_path, | 252 const FilePath& to_path, |
| 253 bool recursive) { | 253 bool recursive) { |
| 254 base::ThreadRestrictions::AssertIOAllowed(); | 254 base::ThreadRestrictions::AssertIOAllowed(); |
| 255 // Some old callers of CopyDirectory want it to support wildcards. | 255 // Some old callers of CopyDirectory want it to support wildcards. |
| 256 // After some discussion, we decided to fix those callers. | 256 // After some discussion, we decided to fix those callers. |
| 257 // Break loudly here if anyone tries to do this. | 257 // Break loudly here if anyone tries to do this. |
| 258 // TODO(evanm): remove this once we're sure it's ok. | 258 // TODO(evanm): remove this once we're sure it's ok. |
| 259 DCHECK(to_path.value().find('*') == std::string::npos); | 259 DCHECK(to_path.value().find('*') == std::string::npos); |
| 260 DCHECK(from_path.value().find('*') == std::string::npos); | 260 DCHECK(from_path.value().find('*') == std::string::npos); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 return false; | 435 return false; |
| 436 | 436 |
| 437 return true; | 437 return true; |
| 438 } | 438 } |
| 439 | 439 |
| 440 // Creates and opens a temporary file in |directory|, returning the | 440 // Creates and opens a temporary file in |directory|, returning the |
| 441 // file descriptor. |path| is set to the temporary file path. | 441 // file descriptor. |path| is set to the temporary file path. |
| 442 // This function does NOT unlink() the file. | 442 // This function does NOT unlink() the file. |
| 443 int CreateAndOpenFdForTemporaryFile(FilePath directory, FilePath* path) { | 443 int CreateAndOpenFdForTemporaryFile(FilePath directory, FilePath* path) { |
| 444 base::ThreadRestrictions::AssertIOAllowed(); // For call to mkstemp(). | 444 base::ThreadRestrictions::AssertIOAllowed(); // For call to mkstemp(). |
| 445 *path = directory.Append(TempFileName()); | 445 *path = directory.Append(base::TempFileName()); |
| 446 const std::string& tmpdir_string = path->value(); | 446 const std::string& tmpdir_string = path->value(); |
| 447 // this should be OK since mkstemp just replaces characters in place | 447 // this should be OK since mkstemp just replaces characters in place |
| 448 char* buffer = const_cast<char*>(tmpdir_string.c_str()); | 448 char* buffer = const_cast<char*>(tmpdir_string.c_str()); |
| 449 | 449 |
| 450 return HANDLE_EINTR(mkstemp(buffer)); | 450 return HANDLE_EINTR(mkstemp(buffer)); |
| 451 } | 451 } |
| 452 | 452 |
| 453 bool CreateTemporaryFile(FilePath* path) { | 453 bool CreateTemporaryFile(FilePath* path) { |
| 454 base::ThreadRestrictions::AssertIOAllowed(); // For call to close(). | 454 base::ThreadRestrictions::AssertIOAllowed(); // For call to close(). |
| 455 FilePath directory; | 455 FilePath directory; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 mkdtemp_template.append(FILE_PATH_LITERAL("XXXXXX")); | 515 mkdtemp_template.append(FILE_PATH_LITERAL("XXXXXX")); |
| 516 return CreateTemporaryDirInDirImpl(base_dir, mkdtemp_template, new_dir); | 516 return CreateTemporaryDirInDirImpl(base_dir, mkdtemp_template, new_dir); |
| 517 } | 517 } |
| 518 | 518 |
| 519 bool CreateNewTempDirectory(const FilePath::StringType& prefix, | 519 bool CreateNewTempDirectory(const FilePath::StringType& prefix, |
| 520 FilePath* new_temp_path) { | 520 FilePath* new_temp_path) { |
| 521 FilePath tmpdir; | 521 FilePath tmpdir; |
| 522 if (!GetTempDir(&tmpdir)) | 522 if (!GetTempDir(&tmpdir)) |
| 523 return false; | 523 return false; |
| 524 | 524 |
| 525 return CreateTemporaryDirInDirImpl(tmpdir, TempFileName(), new_temp_path); | 525 return CreateTemporaryDirInDirImpl(tmpdir, base::TempFileName(), |
| 526 new_temp_path); |
| 526 } | 527 } |
| 527 | 528 |
| 528 bool CreateDirectoryAndGetError(const FilePath& full_path, | 529 bool CreateDirectoryAndGetError(const FilePath& full_path, |
| 529 base::PlatformFileError* error) { | 530 base::PlatformFileError* error) { |
| 530 base::ThreadRestrictions::AssertIOAllowed(); // For call to mkdir(). | 531 base::ThreadRestrictions::AssertIOAllowed(); // For call to mkdir(). |
| 531 std::vector<FilePath> subpaths; | 532 std::vector<FilePath> subpaths; |
| 532 | 533 |
| 533 // Collect a list of all parent directories. | 534 // Collect a list of all parent directories. |
| 534 FilePath last_path = full_path; | 535 FilePath last_path = full_path; |
| 535 subpaths.push_back(full_path); | 536 subpaths.push_back(full_path); |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 938 kFileSystemRoot, path, kRootUid, allowed_group_ids); | 939 kFileSystemRoot, path, kRootUid, allowed_group_ids); |
| 939 } | 940 } |
| 940 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | 941 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| 941 | 942 |
| 942 int GetMaximumPathComponentLength(const FilePath& path) { | 943 int GetMaximumPathComponentLength(const FilePath& path) { |
| 943 base::ThreadRestrictions::AssertIOAllowed(); | 944 base::ThreadRestrictions::AssertIOAllowed(); |
| 944 return pathconf(path.value().c_str(), _PC_NAME_MAX); | 945 return pathconf(path.value().c_str(), _PC_NAME_MAX); |
| 945 } | 946 } |
| 946 | 947 |
| 947 } // namespace file_util | 948 } // namespace file_util |
| OLD | NEW |