Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <libgen.h> | 10 #include <libgen.h> |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 return false; | 253 return false; |
| 254 } | 254 } |
| 255 | 255 |
| 256 bool CopyDirectory(const FilePath& from_path, | 256 bool CopyDirectory(const FilePath& from_path, |
| 257 const FilePath& to_path, | 257 const FilePath& to_path, |
| 258 bool recursive) { | 258 bool recursive) { |
| 259 ThreadRestrictions::AssertIOAllowed(); | 259 ThreadRestrictions::AssertIOAllowed(); |
| 260 // Some old callers of CopyDirectory want it to support wildcards. | 260 // Some old callers of CopyDirectory want it to support wildcards. |
| 261 // After some discussion, we decided to fix those callers. | 261 // After some discussion, we decided to fix those callers. |
| 262 // Break loudly here if anyone tries to do this. | 262 // Break loudly here if anyone tries to do this. |
| 263 // TODO(evanm): remove this once we're sure it's ok. | |
| 264 DCHECK(to_path.value().find('*') == std::string::npos); | 263 DCHECK(to_path.value().find('*') == std::string::npos); |
| 265 DCHECK(from_path.value().find('*') == std::string::npos); | 264 DCHECK(from_path.value().find('*') == std::string::npos); |
| 266 | 265 |
| 267 char top_dir[PATH_MAX]; | 266 if (strlen(from_path.value().c_str()) >= PATH_MAX) { |
|
grt (UTC plus 2)
2014/01/24 20:50:07
no need for strlen, either, is there?
if (from_p
M-A Ruel
2014/01/24 21:32:57
Done.
| |
| 268 if (strlcpy(top_dir, from_path.value().c_str(), | |
|
M-A Ruel
2014/01/24 19:52:31
There was no point in doing a strlcpy just to get
| |
| 269 arraysize(top_dir)) >= arraysize(top_dir)) { | |
| 270 return false; | 267 return false; |
| 271 } | 268 } |
| 272 | 269 |
| 273 // This function does not properly handle destinations within the source | 270 // This function does not properly handle destinations within the source |
| 274 FilePath real_to_path = to_path; | 271 FilePath real_to_path = to_path; |
| 275 if (PathExists(real_to_path)) { | 272 if (PathExists(real_to_path)) { |
| 276 real_to_path = MakeAbsoluteFilePath(real_to_path); | 273 real_to_path = MakeAbsoluteFilePath(real_to_path); |
| 277 if (real_to_path.empty()) | 274 if (real_to_path.empty()) |
| 278 return false; | 275 return false; |
| 279 } else { | 276 } else { |
| 280 real_to_path = MakeAbsoluteFilePath(real_to_path.DirName()); | 277 real_to_path = MakeAbsoluteFilePath(real_to_path.DirName()); |
| 281 if (real_to_path.empty()) | 278 if (real_to_path.empty()) |
| 282 return false; | 279 return false; |
| 283 } | 280 } |
| 284 FilePath real_from_path = MakeAbsoluteFilePath(from_path); | 281 FilePath real_from_path = MakeAbsoluteFilePath(from_path); |
| 285 if (real_from_path.empty()) | 282 if (real_from_path.empty()) |
| 286 return false; | 283 return false; |
| 287 if (real_to_path.value().size() >= real_from_path.value().size() && | 284 if (real_to_path.value().size() >= real_from_path.value().size() && |
| 288 real_to_path.value().compare(0, real_from_path.value().size(), | 285 real_to_path.value().compare(0, real_from_path.value().size(), |
| 289 real_from_path.value()) == 0) | 286 real_from_path.value()) == 0) |
| 290 return false; | 287 return false; |
| 291 | 288 |
| 292 bool success = true; | |
| 293 int traverse_type = FileEnumerator::FILES | FileEnumerator::SHOW_SYM_LINKS; | 289 int traverse_type = FileEnumerator::FILES | FileEnumerator::SHOW_SYM_LINKS; |
| 294 if (recursive) | 290 if (recursive) |
| 295 traverse_type |= FileEnumerator::DIRECTORIES; | 291 traverse_type |= FileEnumerator::DIRECTORIES; |
| 296 FileEnumerator traversal(from_path, recursive, traverse_type); | 292 FileEnumerator traversal(from_path, recursive, traverse_type); |
| 297 | 293 |
| 298 // We have to mimic windows behavior here. |to_path| may not exist yet, | 294 // We have to mimic windows behavior here. |to_path| may not exist yet, |
| 299 // start the loop with |to_path|. | 295 // start the loop with |to_path|. |
| 300 struct stat from_stat; | 296 struct stat from_stat; |
| 301 FilePath current = from_path; | 297 FilePath current = from_path; |
| 302 if (stat(from_path.value().c_str(), &from_stat) < 0) { | 298 if (stat(from_path.value().c_str(), &from_stat) < 0) { |
| 303 DLOG(ERROR) << "CopyDirectory() couldn't stat source directory: " | 299 DLOG(ERROR) << "CopyDirectory() couldn't stat source directory: " |
| 304 << from_path.value() << " errno = " << errno; | 300 << from_path.value() << " errno = " << errno; |
| 305 success = false; | 301 return false; |
| 306 } | 302 } |
| 307 struct stat to_path_stat; | 303 struct stat to_path_stat; |
| 308 FilePath from_path_base = from_path; | 304 FilePath from_path_base = from_path; |
| 309 if (recursive && stat(to_path.value().c_str(), &to_path_stat) == 0 && | 305 if (recursive && stat(to_path.value().c_str(), &to_path_stat) == 0 && |
| 310 S_ISDIR(to_path_stat.st_mode)) { | 306 S_ISDIR(to_path_stat.st_mode)) { |
| 311 // If the destination already exists and is a directory, then the | 307 // If the destination already exists and is a directory, then the |
| 312 // top level of source needs to be copied. | 308 // top level of source needs to be copied. |
| 313 from_path_base = from_path.DirName(); | 309 from_path_base = from_path.DirName(); |
| 314 } | 310 } |
| 315 | 311 |
| 316 // The Windows version of this function assumes that non-recursive calls | 312 // The Windows version of this function assumes that non-recursive calls |
| 317 // will always have a directory for from_path. | 313 // will always have a directory for from_path. |
| 314 // TODO(maruel): This is not necessary anymore. | |
| 318 DCHECK(recursive || S_ISDIR(from_stat.st_mode)); | 315 DCHECK(recursive || S_ISDIR(from_stat.st_mode)); |
| 319 | 316 |
| 317 bool success = true; | |
| 320 while (success && !current.empty()) { | 318 while (success && !current.empty()) { |
| 321 // current is the source path, including from_path, so append | 319 // current is the source path, including from_path, so append |
| 322 // the suffix after from_path to to_path to create the target_path. | 320 // the suffix after from_path to to_path to create the target_path. |
| 323 FilePath target_path(to_path); | 321 FilePath target_path(to_path); |
| 324 if (from_path_base != current) { | 322 if (from_path_base != current) { |
| 325 if (!from_path_base.AppendRelativePath(current, &target_path)) { | 323 if (!from_path_base.AppendRelativePath(current, &target_path)) { |
| 326 success = false; | 324 success = false; |
| 327 break; | 325 break; |
| 328 } | 326 } |
| 329 } | 327 } |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 958 result = false; | 956 result = false; |
| 959 if (IGNORE_EINTR(close(outfile)) < 0) | 957 if (IGNORE_EINTR(close(outfile)) < 0) |
| 960 result = false; | 958 result = false; |
| 961 | 959 |
| 962 return result; | 960 return result; |
| 963 } | 961 } |
| 964 #endif // !defined(OS_MACOSX) | 962 #endif // !defined(OS_MACOSX) |
| 965 | 963 |
| 966 } // namespace internal | 964 } // namespace internal |
| 967 } // namespace base | 965 } // namespace base |
| OLD | NEW |