summaryrefslogtreecommitdiffstats
path: root/base/file_util_posix.cc
diff options
context:
space:
mode:
authoryuzo@chromium.org <yuzo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-09 05:57:38 +0000
committeryuzo@chromium.org <yuzo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-09 05:57:38 +0000
commit8199b3ae54cd41ff1012a4cae3640028043b0bb4 (patch)
tree5718d8e8cdc3889a7c82271f0beb8094b0914531 /base/file_util_posix.cc
parent9c0b3e3a30ab2246a9385b978e86003d4fc8ceb9 (diff)
downloadchromium_src-8199b3ae54cd41ff1012a4cae3640028043b0bb4.zip
chromium_src-8199b3ae54cd41ff1012a4cae3640028043b0bb4.tar.gz
chromium_src-8199b3ae54cd41ff1012a4cae3640028043b0bb4.tar.bz2
Include a parent directory link in the file list for file:///somepath
Also, order files/directories lexicographically. TEST=on linux, type file:///usr/ in the address bar and make sure the contents are sorted and include an entry for '..', which is [parent directory]. On windows, type file:///C:/Users/ . BUG=12621, 12812 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17933 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/file_util_posix.cc')
-rw-r--r--base/file_util_posix.cc24
1 files changed, 22 insertions, 2 deletions
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index 7f40c17..92b9d00 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -522,6 +522,8 @@ FileEnumerator::FileEnumerator(const FilePath& root_path,
file_type_(file_type),
is_in_find_op_(false),
fts_(NULL) {
+ // INCLUDE_DOT_DOT must not be specified if recursive.
+ DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_)));
pending_paths_.push(root_path);
}
@@ -534,6 +536,8 @@ FileEnumerator::FileEnumerator(const FilePath& root_path,
pattern_(root_path.value()),
is_in_find_op_(false),
fts_(NULL) {
+ // INCLUDE_DOT_DOT must not be specified if recursive.
+ DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_)));
// The Windows version of this code only matches against items in the top-most
// directory, and we're comparing fnmatch against full paths, so this is the
// easiest way to get the right pattern.
@@ -556,6 +560,14 @@ void FileEnumerator::GetFindInfo(FindInfo* info) {
info->filename.assign(fts_ent_->fts_name);
}
+int CompareFiles(const FTSENT** a, const FTSENT** b) {
+ // Order lexicographically, ignoring case and whether they are files or
+ // directories.
+ // TODO(yuzo): make this case-sensitive, directories-then-files, and
+ // internationalized.
+ return base::strcasecmp((*a)->fts_name, (*b)->fts_name);
+}
+
// As it stands, this method calls itself recursively when the next item of
// the fts enumeration doesn't match (type, pattern, etc.). In the case of
// large directories with many files this can be quite deep.
@@ -571,11 +583,11 @@ FilePath FileEnumerator::Next() {
pending_paths_.pop();
// Start a new find operation.
- int ftsflags = FTS_LOGICAL;
+ int ftsflags = FTS_LOGICAL | FTS_SEEDOT;
char top_dir[PATH_MAX];
base::strlcpy(top_dir, root_path_.value().c_str(), arraysize(top_dir));
char* dir_list[2] = { top_dir, NULL };
- fts_ = fts_open(dir_list, ftsflags, NULL);
+ fts_ = fts_open(dir_list, ftsflags, CompareFiles);
if (!fts_)
return Next();
is_in_find_op_ = true;
@@ -604,6 +616,9 @@ FilePath FileEnumerator::Next() {
}
FilePath cur_file(fts_ent_->fts_path);
+ if (ShouldSkip(cur_file))
+ return Next();
+
if (fts_ent_->fts_info == FTS_D) {
// If not recursive, then prune children.
if (!recursive_)
@@ -611,6 +626,11 @@ FilePath FileEnumerator::Next() {
return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next();
} else if (fts_ent_->fts_info == FTS_F) {
return (file_type_ & FileEnumerator::FILES) ? cur_file : Next();
+ } else if (fts_ent_->fts_info == FTS_DOT) {
+ if ((file_type_ & FileEnumerator::DIRECTORIES) && IsDotDot(cur_file)) {
+ return cur_file;
+ }
+ return Next();
}
// TODO(erikkay) - verify that the other fts_info types aren't interesting
return Next();