From 4b7743de2632a9d226bd5494b90eee6baceb5855 Mon Sep 17 00:00:00 2001 From: "evan@chromium.org" Date: Tue, 21 Apr 2009 01:50:39 +0000 Subject: Implement file_util::CountFilesCreatedAfter() for posix environments. BUG=9833 Review URL: http://codereview.chromium.org/87003 Patch from Shinichiro Hamaji . git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14081 0039d316-1c4b-4281-b951-d872f2087c98 --- base/file_util.h | 9 ++++++--- base/file_util_posix.cc | 30 ++++++++++++++++++++++++++++++ base/file_util_unittest.cc | 9 ++++++--- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/base/file_util.h b/base/file_util.h index 20d98b0..f12d6f2 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -137,12 +137,15 @@ void ReplaceIllegalCharacters(std::wstring* file_name, int replace_char); //----------------------------------------------------------------------------- // Functions that involve filesystem access or modification: -#if defined(OS_WIN) -// Returns the number of files matching the current path that were // created on or after the given |file_time|. Doesn't count ".." or ".". +// +// Note for POSIX environments: a file created before |file_time| +// can be mis-detected as a newer file due to low precision of +// timestmap of file creation time. If you need to avoid such +// mis-detection perfectly, you should wait one second before +// obtaining |file_time|. int CountFilesCreatedAfter(const FilePath& path, const base::Time& file_time); -#endif // defined(OS_WIN) // Deletes the given path, whether it's a file or a directory. // If it's a directory, it's perfectly happy to delete all of the diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc index ad3fc581..6a36c62 100644 --- a/base/file_util_posix.cc +++ b/base/file_util_posix.cc @@ -4,6 +4,7 @@ #include "base/file_util.h" +#include #include #include #include @@ -14,7 +15,9 @@ #include #include #include +#include #include +#include #include @@ -22,6 +25,7 @@ #include "base/file_path.h" #include "base/logging.h" #include "base/string_util.h" +#include "base/time.h" namespace file_util { @@ -51,6 +55,32 @@ bool AbsolutePath(FilePath* path) { return true; } +int CountFilesCreatedAfter(const FilePath& path, + const base::Time& comparison_time) { + int file_count = 0; + + DIR* dir = opendir(path.value().c_str()); + if (dir) { + struct dirent* ent; + while ((ent = readdir(dir)) != NULL) { + if ((strcmp(ent->d_name, ".") == 0) || + (strcmp(ent->d_name, "..") == 0)) + continue; + + struct stat64 st; + int test = stat64(path.Append(ent->d_name).value().c_str(), &st); + if (test != 0) { + LOG(ERROR) << "stat64 failed: " << strerror(errno); + continue; + } + if (st.st_ctime >= comparison_time.ToTimeT()) + ++file_count; + } + closedir(dir); + } + return file_count; +} + // TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*" // which works both with and without the recursive flag. I'm not sure we need // that functionality. If not, remove from file_util_win.cc, otherwise add it diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc index 02ddc0a..7e0a5e5 100644 --- a/base/file_util_unittest.cc +++ b/base/file_util_unittest.cc @@ -313,15 +313,19 @@ TEST_F(FileUtilTest, GetDirectoryFromPath) { } } -// TODO(erikkay): implement -#if defined OS_WIN TEST_F(FileUtilTest, CountFilesCreatedAfter) { // Create old file (that we don't want to count) FilePath old_file_name = test_dir_.Append(FILE_PATH_LITERAL("Old File.txt")); CreateTextFile(old_file_name, L"Just call me Mr. Creakybits"); // Age to perfection +#if defined(OS_WIN) Sleep(100); +#elif defined(OS_POSIX) + // We need to wait at least one second here because the precision of + // file creation time is one second. + sleep(1); +#endif // Establish our cutoff time base::Time now(base::Time::NowFromSystemTime()); @@ -338,7 +342,6 @@ TEST_F(FileUtilTest, CountFilesCreatedAfter) { EXPECT_TRUE(file_util::Delete(new_file_name, false)); EXPECT_EQ(0, file_util::CountFilesCreatedAfter(test_dir_, now)); } -#endif // Tests that the Delete function works as expected, especially // the recursion flag. Also coincidentally tests PathExists. -- cgit v1.1