OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <fnmatch.h> | 10 #include <fnmatch.h> |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 Lock lock_; | 75 Lock lock_; |
76 friend struct DefaultSingletonTraits<LocaleAwareComparator>; | 76 friend struct DefaultSingletonTraits<LocaleAwareComparator>; |
77 | 77 |
78 DISALLOW_COPY_AND_ASSIGN(LocaleAwareComparator); | 78 DISALLOW_COPY_AND_ASSIGN(LocaleAwareComparator); |
79 }; | 79 }; |
80 | 80 |
81 } // namespace | 81 } // namespace |
82 | 82 |
83 namespace file_util { | 83 namespace file_util { |
84 | 84 |
| 85 #if defined(OS_FREEBSD) |
| 86 typedef struct stat stat_wrapper_t; |
| 87 static int CallStat(const char *path, stat_wrapper_t *sb) { |
| 88 return stat(path, sb); |
| 89 } |
| 90 #else |
| 91 typedef struct stat64 stat_wrapper_t; |
| 92 static int CallStat(const char *path, stat_wrapper_t *sb) { |
| 93 return stat64(path, sb); |
| 94 } |
| 95 #endif |
| 96 |
| 97 |
85 #if defined(GOOGLE_CHROME_BUILD) | 98 #if defined(GOOGLE_CHROME_BUILD) |
86 static const char* kTempFileName = "com.google.chrome.XXXXXX"; | 99 static const char* kTempFileName = "com.google.chrome.XXXXXX"; |
87 #else | 100 #else |
88 static const char* kTempFileName = "org.chromium.XXXXXX"; | 101 static const char* kTempFileName = "org.chromium.XXXXXX"; |
89 #endif | 102 #endif |
90 | 103 |
91 std::wstring GetDirectoryFromPath(const std::wstring& path) { | 104 std::wstring GetDirectoryFromPath(const std::wstring& path) { |
92 if (EndsWithSeparator(path)) { | 105 if (EndsWithSeparator(path)) { |
93 std::wstring dir = path; | 106 std::wstring dir = path; |
94 TrimTrailingSeparator(&dir); | 107 TrimTrailingSeparator(&dir); |
(...skipping 12 matching lines...) Expand all Loading... |
107 *path = FilePath(full_path); | 120 *path = FilePath(full_path); |
108 return true; | 121 return true; |
109 } | 122 } |
110 | 123 |
111 int CountFilesCreatedAfter(const FilePath& path, | 124 int CountFilesCreatedAfter(const FilePath& path, |
112 const base::Time& comparison_time) { | 125 const base::Time& comparison_time) { |
113 int file_count = 0; | 126 int file_count = 0; |
114 | 127 |
115 DIR* dir = opendir(path.value().c_str()); | 128 DIR* dir = opendir(path.value().c_str()); |
116 if (dir) { | 129 if (dir) { |
117 #if !defined(OS_LINUX) && !defined(OS_MACOSX) | 130 #if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_FREEBSD) |
118 #error Depending on the definition of struct dirent, additional space for \ | 131 #error Depending on the definition of struct dirent, additional space for \ |
119 pathname may be needed | 132 pathname may be needed |
120 #endif | 133 #endif |
121 struct dirent ent_buf; | 134 struct dirent ent_buf; |
122 struct dirent* ent; | 135 struct dirent* ent; |
123 while (readdir_r(dir, &ent_buf, &ent) == 0 && ent) { | 136 while (readdir_r(dir, &ent_buf, &ent) == 0 && ent) { |
124 if ((strcmp(ent->d_name, ".") == 0) || | 137 if ((strcmp(ent->d_name, ".") == 0) || |
125 (strcmp(ent->d_name, "..") == 0)) | 138 (strcmp(ent->d_name, "..") == 0)) |
126 continue; | 139 continue; |
127 | 140 |
128 struct stat64 st; | 141 stat_wrapper_t st; |
129 int test = stat64(path.Append(ent->d_name).value().c_str(), &st); | 142 int test = CallStat(path.Append(ent->d_name).value().c_str(), &st); |
130 if (test != 0) { | 143 if (test != 0) { |
131 LOG(ERROR) << "stat64 failed: " << strerror(errno); | 144 LOG(ERROR) << "stat64 failed: " << strerror(errno); |
132 continue; | 145 continue; |
133 } | 146 } |
134 // Here, we use Time::TimeT(), which discards microseconds. This | 147 // Here, we use Time::TimeT(), which discards microseconds. This |
135 // means that files which are newer than |comparison_time| may | 148 // means that files which are newer than |comparison_time| may |
136 // be considered older. If we don't discard microseconds, it | 149 // be considered older. If we don't discard microseconds, it |
137 // introduces another issue. Suppose the following case: | 150 // introduces another issue. Suppose the following case: |
138 // | 151 // |
139 // 1. Get |comparison_time| by Time::Now() and the value is 10.1 (secs). | 152 // 1. Get |comparison_time| by Time::Now() and the value is 10.1 (secs). |
(...skipping 13 matching lines...) Expand all Loading... |
153 } | 166 } |
154 return file_count; | 167 return file_count; |
155 } | 168 } |
156 | 169 |
157 // TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*" | 170 // TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*" |
158 // which works both with and without the recursive flag. I'm not sure we need | 171 // which works both with and without the recursive flag. I'm not sure we need |
159 // that functionality. If not, remove from file_util_win.cc, otherwise add it | 172 // that functionality. If not, remove from file_util_win.cc, otherwise add it |
160 // here. | 173 // here. |
161 bool Delete(const FilePath& path, bool recursive) { | 174 bool Delete(const FilePath& path, bool recursive) { |
162 const char* path_str = path.value().c_str(); | 175 const char* path_str = path.value().c_str(); |
163 struct stat64 file_info; | 176 stat_wrapper_t file_info; |
164 int test = stat64(path_str, &file_info); | 177 int test = CallStat(path_str, &file_info); |
165 if (test != 0) { | 178 if (test != 0) { |
166 // The Windows version defines this condition as success. | 179 // The Windows version defines this condition as success. |
167 bool ret = (errno == ENOENT || errno == ENOTDIR); | 180 bool ret = (errno == ENOENT || errno == ENOTDIR); |
168 return ret; | 181 return ret; |
169 } | 182 } |
170 if (!S_ISDIR(file_info.st_mode)) | 183 if (!S_ISDIR(file_info.st_mode)) |
171 return (unlink(path_str) == 0); | 184 return (unlink(path_str) == 0); |
172 if (!recursive) | 185 if (!recursive) |
173 return (rmdir(path_str) == 0); | 186 return (rmdir(path_str) == 0); |
174 | 187 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 } | 308 } |
296 | 309 |
297 current = traversal.Next(); | 310 current = traversal.Next(); |
298 traversal.GetFindInfo(&info); | 311 traversal.GetFindInfo(&info); |
299 } | 312 } |
300 | 313 |
301 return success; | 314 return success; |
302 } | 315 } |
303 | 316 |
304 bool PathExists(const FilePath& path) { | 317 bool PathExists(const FilePath& path) { |
305 struct stat64 file_info; | 318 stat_wrapper_t file_info; |
306 return (stat64(path.value().c_str(), &file_info) == 0); | 319 return CallStat(path.value().c_str(), &file_info) == 0; |
307 } | 320 } |
308 | 321 |
309 bool PathIsWritable(const FilePath& path) { | 322 bool PathIsWritable(const FilePath& path) { |
310 FilePath test_path(path); | 323 FilePath test_path(path); |
311 struct stat64 file_info; | 324 stat_wrapper_t file_info; |
312 if (stat64(test_path.value().c_str(), &file_info) != 0) { | 325 if (CallStat(test_path.value().c_str(), &file_info) != 0) { |
313 // If the path doesn't exist, test the parent dir. | 326 // If the path doesn't exist, test the parent dir. |
314 test_path = test_path.DirName(); | 327 test_path = test_path.DirName(); |
315 // If the parent dir doesn't exist, then return false (the path is not | 328 // If the parent dir doesn't exist, then return false (the path is not |
316 // directly writable). | 329 // directly writable). |
317 if (stat64(test_path.value().c_str(), &file_info) != 0) | 330 if (CallStat(test_path.value().c_str(), &file_info) != 0) |
318 return false; | 331 return false; |
319 } | 332 } |
320 if (S_IWOTH & file_info.st_mode) | 333 if (S_IWOTH & file_info.st_mode) |
321 return true; | 334 return true; |
322 if (getegid() == file_info.st_gid && (S_IWGRP & file_info.st_mode)) | 335 if (getegid() == file_info.st_gid && (S_IWGRP & file_info.st_mode)) |
323 return true; | 336 return true; |
324 if (geteuid() == file_info.st_uid && (S_IWUSR & file_info.st_mode)) | 337 if (geteuid() == file_info.st_uid && (S_IWUSR & file_info.st_mode)) |
325 return true; | 338 return true; |
326 return false; | 339 return false; |
327 } | 340 } |
328 | 341 |
329 bool DirectoryExists(const FilePath& path) { | 342 bool DirectoryExists(const FilePath& path) { |
330 struct stat64 file_info; | 343 stat_wrapper_t file_info; |
331 if (stat64(path.value().c_str(), &file_info) == 0) | 344 if (CallStat(path.value().c_str(), &file_info) == 0) |
332 return S_ISDIR(file_info.st_mode); | 345 return S_ISDIR(file_info.st_mode); |
333 return false; | 346 return false; |
334 } | 347 } |
335 | 348 |
336 // TODO(erikkay): implement | 349 // TODO(erikkay): implement |
337 #if 0 | 350 #if 0 |
338 bool GetFileCreationLocalTimeFromHandle(int fd, | 351 bool GetFileCreationLocalTimeFromHandle(int fd, |
339 LPSYSTEMTIME creation_time) { | 352 LPSYSTEMTIME creation_time) { |
340 if (!file_handle) | 353 if (!file_handle) |
341 return false; | 354 return false; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 i != subpaths.rend(); ++i) { | 466 i != subpaths.rend(); ++i) { |
454 if (!DirectoryExists(*i)) { | 467 if (!DirectoryExists(*i)) { |
455 if (mkdir(i->value().c_str(), 0700) != 0) | 468 if (mkdir(i->value().c_str(), 0700) != 0) |
456 return false; | 469 return false; |
457 } | 470 } |
458 } | 471 } |
459 return true; | 472 return true; |
460 } | 473 } |
461 | 474 |
462 bool GetFileInfo(const FilePath& file_path, FileInfo* results) { | 475 bool GetFileInfo(const FilePath& file_path, FileInfo* results) { |
463 struct stat64 file_info; | 476 stat_wrapper_t file_info; |
464 if (stat64(file_path.value().c_str(), &file_info) != 0) | 477 if (CallStat(file_path.value().c_str(), &file_info) != 0) |
465 return false; | 478 return false; |
466 results->is_directory = S_ISDIR(file_info.st_mode); | 479 results->is_directory = S_ISDIR(file_info.st_mode); |
467 results->size = file_info.st_size; | 480 results->size = file_info.st_size; |
468 results->last_modified = base::Time::FromTimeT(file_info.st_mtime); | 481 results->last_modified = base::Time::FromTimeT(file_info.st_mtime); |
469 return true; | 482 return true; |
470 } | 483 } |
471 | 484 |
472 bool GetInode(const FilePath& path, ino_t* inode) { | 485 bool GetInode(const FilePath& path, ino_t* inode) { |
473 struct stat buffer; | 486 struct stat buffer; |
474 int result = stat(path.value().c_str(), &buffer); | 487 int result = stat(path.value().c_str(), &buffer); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 return root_path_.Append(directory_entries_[current_directory_entry_ | 643 return root_path_.Append(directory_entries_[current_directory_entry_ |
631 ].filename); | 644 ].filename); |
632 } | 645 } |
633 | 646 |
634 bool FileEnumerator::ReadDirectory(std::vector<DirectoryEntryInfo>* entries, | 647 bool FileEnumerator::ReadDirectory(std::vector<DirectoryEntryInfo>* entries, |
635 const FilePath& source, bool show_links) { | 648 const FilePath& source, bool show_links) { |
636 DIR* dir = opendir(source.value().c_str()); | 649 DIR* dir = opendir(source.value().c_str()); |
637 if (!dir) | 650 if (!dir) |
638 return false; | 651 return false; |
639 | 652 |
640 #if !defined(OS_LINUX) && !defined(OS_MACOSX) | 653 #if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_FREEBSD) |
641 #error Depending on the definition of struct dirent, additional space for \ | 654 #error Depending on the definition of struct dirent, additional space for \ |
642 pathname may be needed | 655 pathname may be needed |
643 #endif | 656 #endif |
644 struct dirent dent_buf; | 657 struct dirent dent_buf; |
645 struct dirent* dent; | 658 struct dirent* dent; |
646 while (readdir_r(dir, &dent_buf, &dent) == 0 && dent) { | 659 while (readdir_r(dir, &dent_buf, &dent) == 0 && dent) { |
647 DirectoryEntryInfo info; | 660 DirectoryEntryInfo info; |
648 info.filename = FilePath(dent->d_name); | 661 info.filename = FilePath(dent->d_name); |
649 | 662 |
650 FilePath full_name = source.Append(dent->d_name); | 663 FilePath full_name = source.Append(dent->d_name); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 munmap(data_, length_); | 737 munmap(data_, length_); |
725 if (file_ != -1) | 738 if (file_ != -1) |
726 close(file_); | 739 close(file_); |
727 | 740 |
728 data_ = NULL; | 741 data_ = NULL; |
729 length_ = 0; | 742 length_ = 0; |
730 file_ = -1; | 743 file_ = -1; |
731 } | 744 } |
732 | 745 |
733 } // namespace file_util | 746 } // namespace file_util |
OLD | NEW |