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 <fnmatch.h> | 10 #include <fnmatch.h> |
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 |
OLD | NEW |