OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 *path = FilePath(full_path); | 54 *path = FilePath(full_path); |
55 return true; | 55 return true; |
56 } | 56 } |
57 | 57 |
58 int CountFilesCreatedAfter(const FilePath& path, | 58 int CountFilesCreatedAfter(const FilePath& path, |
59 const base::Time& comparison_time) { | 59 const base::Time& comparison_time) { |
60 int file_count = 0; | 60 int file_count = 0; |
61 | 61 |
62 DIR* dir = opendir(path.value().c_str()); | 62 DIR* dir = opendir(path.value().c_str()); |
63 if (dir) { | 63 if (dir) { |
| 64 struct dirent ent_buf; |
64 struct dirent* ent; | 65 struct dirent* ent; |
65 while ((ent = readdir(dir)) != NULL) { | 66 while (readdir_r(dir, &ent_buf, &ent) == 0 && ent) { |
66 if ((strcmp(ent->d_name, ".") == 0) || | 67 if ((strcmp(ent->d_name, ".") == 0) || |
67 (strcmp(ent->d_name, "..") == 0)) | 68 (strcmp(ent->d_name, "..") == 0)) |
68 continue; | 69 continue; |
69 | 70 |
70 struct stat64 st; | 71 struct stat64 st; |
71 int test = stat64(path.Append(ent->d_name).value().c_str(), &st); | 72 int test = stat64(path.Append(ent->d_name).value().c_str(), &st); |
72 if (test != 0) { | 73 if (test != 0) { |
73 LOG(ERROR) << "stat64 failed: " << strerror(errno); | 74 LOG(ERROR) << "stat64 failed: " << strerror(errno); |
74 continue; | 75 continue; |
75 } | 76 } |
| 77 // Here, we use Time::TimeT(), which discards microseconds. This |
| 78 // means that files which are newer than |comparison_time| may |
| 79 // be considered older. If we don't discard microseconds, it |
| 80 // introduces another issue. Suppose the following case: |
| 81 // |
| 82 // 1. Get |comparison_time| by Time::Now() and the value is 10.1 (secs). |
| 83 // 2. Create a file and the current time is 10.3 (secs). |
| 84 // |
| 85 // As POSIX doesn't have microsecond precision for |st_ctime|, |
| 86 // the creation time of the file created in the step 2 is 10 and |
| 87 // the file is considered older than |comparison_time|. After |
| 88 // all, we may have to accept either of the two issues: 1. files |
| 89 // which are older than |comparison_time| are considered newer |
| 90 // (current implementation) 2. files newer than |
| 91 // |comparison_time| are considered older. |
76 if (st.st_ctime >= comparison_time.ToTimeT()) | 92 if (st.st_ctime >= comparison_time.ToTimeT()) |
77 ++file_count; | 93 ++file_count; |
78 } | 94 } |
79 closedir(dir); | 95 closedir(dir); |
80 } | 96 } |
81 return file_count; | 97 return file_count; |
82 } | 98 } |
83 | 99 |
84 // TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*" | 100 // TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*" |
85 // which works both with and without the recursive flag. I'm not sure we need | 101 // which works both with and without the recursive flag. I'm not sure we need |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 munmap(data_, length_); | 630 munmap(data_, length_); |
615 if (file_ != -1) | 631 if (file_ != -1) |
616 close(file_); | 632 close(file_); |
617 | 633 |
618 data_ = NULL; | 634 data_ = NULL; |
619 length_ = 0; | 635 length_ = 0; |
620 file_ = -1; | 636 file_ = -1; |
621 } | 637 } |
622 | 638 |
623 } // namespace file_util | 639 } // namespace file_util |
OLD | NEW |