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 |