summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/file_util.h9
-rw-r--r--base/file_util_posix.cc30
-rw-r--r--base/file_util_unittest.cc9
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 <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
@@ -14,7 +15,9 @@
#include <sys/errno.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <time.h>
+#include <unistd.h>
#include <fstream>
@@ -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.