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

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: whitespace Created 6 years, 11 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 | « no previous file | base/file_util_unittest.cc » ('j') | base/file_util_win.cc » ('J')
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 (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
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
OLDNEW
« no previous file with comments | « no previous file | base/file_util_unittest.cc » ('j') | base/file_util_win.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698