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

Side by Side Diff: chrome/installer/util/copy_tree_work_item.cc

Issue 6538025: Temp dir cleanup:... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/installer/util/copy_tree_work_item.h" 5 #include "chrome/installer/util/copy_tree_work_item.h"
6 6
7 #include <shlwapi.h> 7 #include <shlwapi.h>
8 8
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "chrome/installer/util/logging_installer.h" 11 #include "chrome/installer/util/logging_installer.h"
12 12
13 CopyTreeWorkItem::~CopyTreeWorkItem() { 13 CopyTreeWorkItem::~CopyTreeWorkItem() {
14 if (file_util::PathExists(backup_path_)) {
15 file_util::Delete(backup_path_, true);
16 }
17 } 14 }
18 15
19 CopyTreeWorkItem::CopyTreeWorkItem(const FilePath& source_path, 16 CopyTreeWorkItem::CopyTreeWorkItem(const FilePath& source_path,
20 const FilePath& dest_path, 17 const FilePath& dest_path,
21 const FilePath& temp_dir, 18 const FilePath& temp_dir,
22 CopyOverWriteOption overwrite_option, 19 CopyOverWriteOption overwrite_option,
23 const FilePath& alternative_path) 20 const FilePath& alternative_path)
24 : source_path_(source_path), 21 : source_path_(source_path),
25 dest_path_(dest_path), 22 dest_path_(dest_path),
26 temp_dir_(temp_dir), 23 temp_dir_(temp_dir),
27 overwrite_option_(overwrite_option), 24 overwrite_option_(overwrite_option),
28 alternative_path_(alternative_path), 25 alternative_path_(alternative_path),
29 copied_to_dest_path_(false), 26 copied_to_dest_path_(false),
30 moved_to_backup_(false), 27 moved_to_backup_(false),
31 copied_to_alternate_path_(false) { 28 copied_to_alternate_path_(false) {
32 } 29 }
33 30
34 bool CopyTreeWorkItem::Do() { 31 bool CopyTreeWorkItem::Do() {
35 if (!file_util::PathExists(source_path_)) { 32 if (!file_util::PathExists(source_path_)) {
36 LOG(ERROR) << source_path_.value() << " does not exist"; 33 LOG(ERROR) << source_path_.value() << " does not exist";
37 return false; 34 return false;
38 } 35 }
39 36
40 bool dest_exist = file_util::PathExists(dest_path_); 37 bool dest_exist = file_util::PathExists(dest_path_);
41 // handle overwrite_option_ = IF_DIFFERENT case. 38 // handle overwrite_option_ = IF_DIFFERENT case.
42 if ((dest_exist) && 39 if ((dest_exist) &&
43 (overwrite_option_ == WorkItem::IF_DIFFERENT) && // only for single file 40 (overwrite_option_ == WorkItem::IF_DIFFERENT) && // only for single file
44 (!file_util::DirectoryExists(source_path_)) && 41 (!file_util::DirectoryExists(source_path_)) &&
45 (!file_util::DirectoryExists(dest_path_)) && 42 (!file_util::DirectoryExists(dest_path_)) &&
46 (file_util::ContentsEqual(source_path_, dest_path_))) { 43 (file_util::ContentsEqual(source_path_, dest_path_))) {
47 VLOG(1) << "Source file " << source_path_.value() 44 VLOG(1) << "Source file " << source_path_.value()
48 << " and destination file " << dest_path_.value() 45 << " and destination file " << dest_path_.value()
49 << " are exactly same. Returning true."; 46 << " are exactly same. Returning true.";
50 return true; 47 return true;
51 } else if ((dest_exist) && 48 } else if ((dest_exist) &&
52 (overwrite_option_ == WorkItem::NEW_NAME_IF_IN_USE) && 49 (overwrite_option_ == WorkItem::NEW_NAME_IF_IN_USE) &&
53 (!file_util::DirectoryExists(source_path_)) && 50 (!file_util::DirectoryExists(source_path_)) &&
(...skipping 13 matching lines...) Expand all
67 return true; 64 return true;
68 } 65 }
69 } else if ((dest_exist) && 66 } else if ((dest_exist) &&
70 (overwrite_option_ == WorkItem::IF_NOT_PRESENT)) { 67 (overwrite_option_ == WorkItem::IF_NOT_PRESENT)) {
71 // handle overwrite_option_ = IF_NOT_PRESENT case. 68 // handle overwrite_option_ = IF_NOT_PRESENT case.
72 return true; 69 return true;
73 } 70 }
74 71
75 // In all cases that reach here, move dest to a backup path. 72 // In all cases that reach here, move dest to a backup path.
76 if (dest_exist) { 73 if (dest_exist) {
77 if (!GetBackupPath()) 74 if (!backup_path_.CreateUniqueTempDirUnderPath(temp_dir_)) {
75 PLOG(ERROR) << "Failed to get backup path in folder "
76 << temp_dir_.value();
78 return false; 77 return false;
78 }
79 79
80 if (file_util::Move(dest_path_, backup_path_)) { 80 FilePath backup = backup_path_.path().Append(dest_path_.BaseName());
81 if (file_util::Move(dest_path_, backup)) {
81 moved_to_backup_ = true; 82 moved_to_backup_ = true;
82 VLOG(1) << "Moved destination " << dest_path_.value() << 83 VLOG(1) << "Moved destination " << dest_path_.value() <<
83 " to backup path " << backup_path_.value(); 84 " to backup path " << backup.value();
84 } else { 85 } else {
85 LOG(ERROR) << "failed moving " << dest_path_.value() 86 LOG(ERROR) << "failed moving " << dest_path_.value()
86 << " to " << backup_path_.value(); 87 << " to " << backup.value();
87 return false; 88 return false;
88 } 89 }
89 } 90 }
90 91
91 // In all cases that reach here, copy source to destination. 92 // In all cases that reach here, copy source to destination.
92 if (file_util::CopyDirectory(source_path_, dest_path_, true)) { 93 if (file_util::CopyDirectory(source_path_, dest_path_, true)) {
93 copied_to_dest_path_ = true; 94 copied_to_dest_path_ = true;
94 VLOG(1) << "Copied source " << source_path_.value() 95 VLOG(1) << "Copied source " << source_path_.value()
95 << " to destination " << dest_path_.value(); 96 << " to destination " << dest_path_.value();
96 } else { 97 } else {
97 LOG(ERROR) << "failed copy " << source_path_.value() 98 LOG(ERROR) << "failed copy " << source_path_.value()
98 << " to " << dest_path_.value(); 99 << " to " << dest_path_.value();
99 return false; 100 return false;
100 } 101 }
101 102
102 return true; 103 return true;
103 } 104 }
104 105
105 void CopyTreeWorkItem::Rollback() { 106 void CopyTreeWorkItem::Rollback() {
106 // Normally the delete operations below should not fail unless some 107 // Normally the delete operations below should not fail unless some
107 // programs like anti-virus are inpecting the files we just copied. 108 // programs like anti-virus are inspecting the files we just copied.
108 // If this does happen sometimes, we may consider using Move instead of 109 // If this does happen sometimes, we may consider using Move instead of
109 // Delete here. For now we just log the error and continue with the 110 // Delete here. For now we just log the error and continue with the
110 // rest of rollback operation. 111 // rest of rollback operation.
111 if (copied_to_dest_path_ && !file_util::Delete(dest_path_, true)) { 112 if (copied_to_dest_path_ && !file_util::Delete(dest_path_, true)) {
112 LOG(ERROR) << "Can not delete " << dest_path_.value(); 113 LOG(ERROR) << "Can not delete " << dest_path_.value();
113 } 114 }
114 if (moved_to_backup_ && !file_util::Move(backup_path_, dest_path_)) { 115 if (moved_to_backup_) {
115 LOG(ERROR) << "failed move " << backup_path_.value() 116 FilePath backup(backup_path_.path().Append(dest_path_.BaseName()));
116 << " to " << dest_path_.value(); 117 if (!file_util::Move(backup, dest_path_)) {
118 LOG(ERROR) << "failed move " << backup.value()
119 << " to " << dest_path_.value();
120 }
117 } 121 }
118 if (copied_to_alternate_path_ && 122 if (copied_to_alternate_path_ &&
119 !file_util::Delete(alternative_path_, true)) { 123 !file_util::Delete(alternative_path_, true)) {
120 LOG(ERROR) << "Can not delete " << alternative_path_.value(); 124 LOG(ERROR) << "Can not delete " << alternative_path_.value();
121 } 125 }
122 } 126 }
123 127
124 bool CopyTreeWorkItem::IsFileInUse(const FilePath& path) { 128 bool CopyTreeWorkItem::IsFileInUse(const FilePath& path) {
125 if (!file_util::PathExists(path)) 129 if (!file_util::PathExists(path))
126 return false; 130 return false;
127 131
128 HANDLE handle = ::CreateFile(path.value().c_str(), FILE_ALL_ACCESS, 132 HANDLE handle = ::CreateFile(path.value().c_str(), FILE_ALL_ACCESS,
129 NULL, NULL, OPEN_EXISTING, NULL, NULL); 133 NULL, NULL, OPEN_EXISTING, NULL, NULL);
130 if (handle == INVALID_HANDLE_VALUE) 134 if (handle == INVALID_HANDLE_VALUE)
131 return true; 135 return true;
132 136
133 CloseHandle(handle); 137 CloseHandle(handle);
134 return false; 138 return false;
135 } 139 }
136
137 bool CopyTreeWorkItem::GetBackupPath() {
138 backup_path_ = temp_dir_.Append(dest_path_.BaseName());
139
140 if (file_util::PathExists(backup_path_)) {
141 // Ideally we should not fail immediately. Instead we could try some
142 // random paths under temp_dir_ until we reach certain limit.
143 // For now our caller always provides a good temporary directory so
144 // we don't bother.
145 LOG(ERROR) << "backup path " << backup_path_.value() << " already exists";
146 return false;
147 }
148
149 return true;
150 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698