Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: base/file_util_posix.cc

Issue 141273010: Make CopyDirectory() not copy the read only bit on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Revert change to CopyFileUnsafe Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/file_util.h ('k') | base/file_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 (from_path.value().size() >= PATH_MAX) {
268 if (strlcpy(top_dir, from_path.value().c_str(),
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;
288 }
291 289
292 bool success = true;
293 int traverse_type = FileEnumerator::FILES | FileEnumerator::SHOW_SYM_LINKS; 290 int traverse_type = FileEnumerator::FILES | FileEnumerator::SHOW_SYM_LINKS;
294 if (recursive) 291 if (recursive)
295 traverse_type |= FileEnumerator::DIRECTORIES; 292 traverse_type |= FileEnumerator::DIRECTORIES;
296 FileEnumerator traversal(from_path, recursive, traverse_type); 293 FileEnumerator traversal(from_path, recursive, traverse_type);
297 294
298 // We have to mimic windows behavior here. |to_path| may not exist yet, 295 // We have to mimic windows behavior here. |to_path| may not exist yet,
299 // start the loop with |to_path|. 296 // start the loop with |to_path|.
300 struct stat from_stat; 297 struct stat from_stat;
301 FilePath current = from_path; 298 FilePath current = from_path;
302 if (stat(from_path.value().c_str(), &from_stat) < 0) { 299 if (stat(from_path.value().c_str(), &from_stat) < 0) {
303 DLOG(ERROR) << "CopyDirectory() couldn't stat source directory: " 300 DLOG(ERROR) << "CopyDirectory() couldn't stat source directory: "
304 << from_path.value() << " errno = " << errno; 301 << from_path.value() << " errno = " << errno;
305 success = false; 302 return false;
306 } 303 }
307 struct stat to_path_stat; 304 struct stat to_path_stat;
308 FilePath from_path_base = from_path; 305 FilePath from_path_base = from_path;
309 if (recursive && stat(to_path.value().c_str(), &to_path_stat) == 0 && 306 if (recursive && stat(to_path.value().c_str(), &to_path_stat) == 0 &&
310 S_ISDIR(to_path_stat.st_mode)) { 307 S_ISDIR(to_path_stat.st_mode)) {
311 // If the destination already exists and is a directory, then the 308 // If the destination already exists and is a directory, then the
312 // top level of source needs to be copied. 309 // top level of source needs to be copied.
313 from_path_base = from_path.DirName(); 310 from_path_base = from_path.DirName();
314 } 311 }
315 312
316 // The Windows version of this function assumes that non-recursive calls 313 // The Windows version of this function assumes that non-recursive calls
317 // will always have a directory for from_path. 314 // will always have a directory for from_path.
315 // TODO(maruel): This is not necessary anymore.
318 DCHECK(recursive || S_ISDIR(from_stat.st_mode)); 316 DCHECK(recursive || S_ISDIR(from_stat.st_mode));
319 317
318 bool success = true;
320 while (success && !current.empty()) { 319 while (success && !current.empty()) {
321 // current is the source path, including from_path, so append 320 // current is the source path, including from_path, so append
322 // the suffix after from_path to to_path to create the target_path. 321 // the suffix after from_path to to_path to create the target_path.
323 FilePath target_path(to_path); 322 FilePath target_path(to_path);
324 if (from_path_base != current) { 323 if (from_path_base != current) {
325 if (!from_path_base.AppendRelativePath(current, &target_path)) { 324 if (!from_path_base.AppendRelativePath(current, &target_path)) {
326 success = false; 325 success = false;
327 break; 326 break;
328 } 327 }
329 } 328 }
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 result = false; 957 result = false;
959 if (IGNORE_EINTR(close(outfile)) < 0) 958 if (IGNORE_EINTR(close(outfile)) < 0)
960 result = false; 959 result = false;
961 960
962 return result; 961 return result;
963 } 962 }
964 #endif // !defined(OS_MACOSX) 963 #endif // !defined(OS_MACOSX)
965 964
966 } // namespace internal 965 } // namespace internal
967 } // namespace base 966 } // namespace base
OLDNEW
« no previous file with comments | « base/file_util.h ('k') | base/file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698