Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: base/file_util_posix.cc

Issue 13247008: base: Extract FileEnumerator out of file_util.h (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: file_enumerator_posix.cc should not compile on win Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/file_util.cc ('k') | base/file_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <fnmatch.h> 10 #include <fnmatch.h>
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 return true; 702 return true;
703 } 703 }
704 704
705 // Sets the current working directory for the process. 705 // Sets the current working directory for the process.
706 bool SetCurrentDirectory(const FilePath& path) { 706 bool SetCurrentDirectory(const FilePath& path) {
707 base::ThreadRestrictions::AssertIOAllowed(); 707 base::ThreadRestrictions::AssertIOAllowed();
708 int ret = chdir(path.value().c_str()); 708 int ret = chdir(path.value().c_str());
709 return !ret; 709 return !ret;
710 } 710 }
711 711
712 ///////////////////////////////////////////////
713 // FileEnumerator
714
715 FileEnumerator::FileEnumerator(const FilePath& root_path,
716 bool recursive,
717 int file_type)
718 : current_directory_entry_(0),
719 root_path_(root_path),
720 recursive_(recursive),
721 file_type_(file_type) {
722 // INCLUDE_DOT_DOT must not be specified if recursive.
723 DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_)));
724 pending_paths_.push(root_path);
725 }
726
727 FileEnumerator::FileEnumerator(const FilePath& root_path,
728 bool recursive,
729 int file_type,
730 const FilePath::StringType& pattern)
731 : current_directory_entry_(0),
732 root_path_(root_path),
733 recursive_(recursive),
734 file_type_(file_type),
735 pattern_(root_path.Append(pattern).value()) {
736 // INCLUDE_DOT_DOT must not be specified if recursive.
737 DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_)));
738 // The Windows version of this code appends the pattern to the root_path,
739 // potentially only matching against items in the top-most directory.
740 // Do the same here.
741 if (pattern.empty())
742 pattern_ = FilePath::StringType();
743 pending_paths_.push(root_path);
744 }
745
746 FileEnumerator::~FileEnumerator() {
747 }
748
749 FilePath FileEnumerator::Next() {
750 ++current_directory_entry_;
751
752 // While we've exhausted the entries in the current directory, do the next
753 while (current_directory_entry_ >= directory_entries_.size()) {
754 if (pending_paths_.empty())
755 return FilePath();
756
757 root_path_ = pending_paths_.top();
758 root_path_ = root_path_.StripTrailingSeparators();
759 pending_paths_.pop();
760
761 std::vector<DirectoryEntryInfo> entries;
762 if (!ReadDirectory(&entries, root_path_, file_type_ & SHOW_SYM_LINKS))
763 continue;
764
765 directory_entries_.clear();
766 current_directory_entry_ = 0;
767 for (std::vector<DirectoryEntryInfo>::const_iterator
768 i = entries.begin(); i != entries.end(); ++i) {
769 FilePath full_path = root_path_.Append(i->filename);
770 if (ShouldSkip(full_path))
771 continue;
772
773 if (pattern_.size() &&
774 fnmatch(pattern_.c_str(), full_path.value().c_str(), FNM_NOESCAPE))
775 continue;
776
777 if (recursive_ && S_ISDIR(i->stat.st_mode))
778 pending_paths_.push(full_path);
779
780 if ((S_ISDIR(i->stat.st_mode) && (file_type_ & DIRECTORIES)) ||
781 (!S_ISDIR(i->stat.st_mode) && (file_type_ & FILES)))
782 directory_entries_.push_back(*i);
783 }
784 }
785
786 return root_path_.Append(directory_entries_[current_directory_entry_
787 ].filename);
788 }
789
790 void FileEnumerator::GetFindInfo(FindInfo* info) {
791 DCHECK(info);
792
793 if (current_directory_entry_ >= directory_entries_.size())
794 return;
795
796 DirectoryEntryInfo* cur_entry = &directory_entries_[current_directory_entry_];
797 memcpy(&(info->stat), &(cur_entry->stat), sizeof(info->stat));
798 info->filename.assign(cur_entry->filename.value());
799 }
800
801 // static
802 bool FileEnumerator::IsDirectory(const FindInfo& info) {
803 return S_ISDIR(info.stat.st_mode);
804 }
805
806 // static
807 FilePath FileEnumerator::GetFilename(const FindInfo& find_info) {
808 return FilePath(find_info.filename);
809 }
810
811 // static
812 int64 FileEnumerator::GetFilesize(const FindInfo& find_info) {
813 return find_info.stat.st_size;
814 }
815
816 // static
817 base::Time FileEnumerator::GetLastModifiedTime(const FindInfo& find_info) {
818 return base::Time::FromTimeT(find_info.stat.st_mtime);
819 }
820
821 bool FileEnumerator::ReadDirectory(std::vector<DirectoryEntryInfo>* entries,
822 const FilePath& source, bool show_links) {
823 base::ThreadRestrictions::AssertIOAllowed();
824 DIR* dir = opendir(source.value().c_str());
825 if (!dir)
826 return false;
827
828 #if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_BSD) && \
829 !defined(OS_SOLARIS) && !defined(OS_ANDROID)
830 #error Port warning: depending on the definition of struct dirent, \
831 additional space for pathname may be needed
832 #endif
833
834 struct dirent dent_buf;
835 struct dirent* dent;
836 while (readdir_r(dir, &dent_buf, &dent) == 0 && dent) {
837 DirectoryEntryInfo info;
838 info.filename = FilePath(dent->d_name);
839
840 FilePath full_name = source.Append(dent->d_name);
841 int ret;
842 if (show_links)
843 ret = lstat(full_name.value().c_str(), &info.stat);
844 else
845 ret = stat(full_name.value().c_str(), &info.stat);
846 if (ret < 0) {
847 // Print the stat() error message unless it was ENOENT and we're
848 // following symlinks.
849 if (!(errno == ENOENT && !show_links)) {
850 DPLOG(ERROR) << "Couldn't stat "
851 << source.Append(dent->d_name).value();
852 }
853 memset(&info.stat, 0, sizeof(info.stat));
854 }
855 entries->push_back(info);
856 }
857
858 closedir(dir);
859 return true;
860 }
861
862 bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info, 712 bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info,
863 const base::Time& cutoff_time) { 713 const base::Time& cutoff_time) {
864 return static_cast<time_t>(find_info.stat.st_mtime) >= cutoff_time.ToTimeT(); 714 return static_cast<time_t>(find_info.stat.st_mtime) >= cutoff_time.ToTimeT();
865 } 715 }
866 716
867 bool NormalizeFilePath(const FilePath& path, FilePath* normalized_path) { 717 bool NormalizeFilePath(const FilePath& path, FilePath* normalized_path) {
868 FilePath real_path_result; 718 FilePath real_path_result;
869 if (!RealPath(path, &real_path_result)) 719 if (!RealPath(path, &real_path_result))
870 return false; 720 return false;
871 721
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 kFileSystemRoot, path, kRootUid, allowed_group_ids); 941 kFileSystemRoot, path, kRootUid, allowed_group_ids);
1092 } 942 }
1093 #endif // defined(OS_MACOSX) && !defined(OS_IOS) 943 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
1094 944
1095 int GetMaximumPathComponentLength(const FilePath& path) { 945 int GetMaximumPathComponentLength(const FilePath& path) {
1096 base::ThreadRestrictions::AssertIOAllowed(); 946 base::ThreadRestrictions::AssertIOAllowed();
1097 return pathconf(path.value().c_str(), _PC_NAME_MAX); 947 return pathconf(path.value().c_str(), _PC_NAME_MAX);
1098 } 948 }
1099 949
1100 } // namespace file_util 950 } // namespace file_util
OLDNEW
« no previous file with comments | « base/file_util.cc ('k') | base/file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698