Index: trunk/src/base/test/test_file_util_posix.cc |
=================================================================== |
--- trunk/src/base/test/test_file_util_posix.cc (revision 193252) |
+++ trunk/src/base/test/test_file_util_posix.cc (working copy) |
@@ -78,6 +78,82 @@ |
return file_util::Delete(file, recurse); |
} |
+// Mostly a verbatim copy of CopyDirectory |
+bool CopyRecursiveDirNoCache(const base::FilePath& source_dir, |
+ const base::FilePath& dest_dir) { |
+ char top_dir[PATH_MAX]; |
+ if (base::strlcpy(top_dir, source_dir.value().c_str(), |
+ arraysize(top_dir)) >= arraysize(top_dir)) { |
+ return false; |
+ } |
+ |
+ // This function does not properly handle destinations within the source |
+ base::FilePath real_to_path = dest_dir; |
+ if (PathExists(real_to_path)) { |
+ if (!AbsolutePath(&real_to_path)) |
+ return false; |
+ } else { |
+ real_to_path = real_to_path.DirName(); |
+ if (!AbsolutePath(&real_to_path)) |
+ return false; |
+ } |
+ if (real_to_path.value().compare(0, source_dir.value().size(), |
+ source_dir.value()) == 0) |
+ return false; |
+ |
+ bool success = true; |
+ int traverse_type = FileEnumerator::FILES | |
+ FileEnumerator::SHOW_SYM_LINKS | FileEnumerator::DIRECTORIES; |
+ FileEnumerator traversal(source_dir, true, traverse_type); |
+ |
+ // dest_dir may not exist yet, start the loop with dest_dir |
+ FileEnumerator::FindInfo info; |
+ base::FilePath current = source_dir; |
+ if (stat(source_dir.value().c_str(), &info.stat) < 0) { |
+ DLOG(ERROR) << "CopyRecursiveDirNoCache() couldn't stat source directory: " |
+ << source_dir.value() << " errno = " << errno; |
+ success = false; |
+ } |
+ |
+ while (success && !current.empty()) { |
+ // |current| is the source path, including source_dir, so paste |
+ // the suffix after source_dir onto dest_dir to create the target_path. |
+ std::string suffix(¤t.value().c_str()[source_dir.value().size()]); |
+ // Strip the leading '/' (if any). |
+ if (!suffix.empty()) { |
+ DCHECK_EQ('/', suffix[0]); |
+ suffix.erase(0, 1); |
+ } |
+ const base::FilePath target_path = dest_dir.Append(suffix); |
+ |
+ if (S_ISDIR(info.stat.st_mode)) { |
+ if (mkdir(target_path.value().c_str(), info.stat.st_mode & 01777) != 0 && |
+ errno != EEXIST) { |
+ DLOG(ERROR) << "CopyRecursiveDirNoCache() couldn't create directory: " |
+ << target_path.value() << " errno = " << errno; |
+ success = false; |
+ } |
+ } else if (S_ISREG(info.stat.st_mode)) { |
+ if (CopyFile(current, target_path)) { |
+ success = EvictFileFromSystemCache(target_path); |
+ DCHECK(success); |
+ } else { |
+ DLOG(ERROR) << "CopyRecursiveDirNoCache() couldn't create file: " |
+ << target_path.value(); |
+ success = false; |
+ } |
+ } else { |
+ DLOG(WARNING) << "CopyRecursiveDirNoCache() skipping non-regular file: " |
+ << current.value(); |
+ } |
+ |
+ current = traversal.Next(); |
+ traversal.GetFindInfo(&info); |
+ } |
+ |
+ return success; |
+} |
+ |
#if !defined(OS_LINUX) && !defined(OS_MACOSX) |
bool EvictFileFromSystemCache(const base::FilePath& file) { |
// There doesn't seem to be a POSIX way to cool the disk cache. |