OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <fnmatch.h> | 9 #include <fnmatch.h> |
10 #include <fts.h> | 10 #include <fts.h> |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 } | 135 } |
136 | 136 |
137 int error = 0; | 137 int error = 0; |
138 FTSENT* ent; | 138 FTSENT* ent; |
139 while (!error && (ent = fts_read(fts)) != NULL) { | 139 while (!error && (ent = fts_read(fts)) != NULL) { |
140 // ent->fts_path is the source path, including from_path, so paste | 140 // ent->fts_path is the source path, including from_path, so paste |
141 // the suffix after from_path onto to_path to create the target_path. | 141 // the suffix after from_path onto to_path to create the target_path. |
142 std::string suffix(&ent->fts_path[from_path.value().size()]); | 142 std::string suffix(&ent->fts_path[from_path.value().size()]); |
143 // Strip the leading '/' (if any). | 143 // Strip the leading '/' (if any). |
144 if (!suffix.empty()) { | 144 if (!suffix.empty()) { |
145 DCHECK(suffix[0] == '/'); | 145 DCHECK_EQ('/', suffix[0]); |
146 suffix.erase(0, 1); | 146 suffix.erase(0, 1); |
147 } | 147 } |
148 const FilePath target_path = to_path.Append(suffix); | 148 const FilePath target_path = to_path.Append(suffix); |
149 switch (ent->fts_info) { | 149 switch (ent->fts_info) { |
150 case FTS_D: // Preorder directory. | 150 case FTS_D: // Preorder directory. |
151 // If we encounter a subdirectory in a non-recursive copy, prune it | 151 // If we encounter a subdirectory in a non-recursive copy, prune it |
152 // from the traversal. | 152 // from the traversal. |
153 if (!recursive && ent->fts_level > 0) { | 153 if (!recursive && ent->fts_level > 0) { |
154 if (fts_set(fts, ent, FTS_SKIP) != 0) | 154 if (fts_set(fts, ent, FTS_SKIP) != 0) |
155 error = errno; | 155 error = errno; |
156 continue; | 156 continue; |
157 } | 157 } |
158 | 158 |
159 // Try creating the target dir, continuing on it if it exists already. | 159 // Try creating the target dir, continuing on it if it exists already. |
| 160 // Rely on the user's umask to produce correct permissions. |
160 if (mkdir(target_path.value().c_str(), 0777) != 0) { | 161 if (mkdir(target_path.value().c_str(), 0777) != 0) { |
161 if (errno != EEXIST) | 162 if (errno != EEXIST) |
162 error = errno; | 163 error = errno; |
163 } | 164 } |
164 break; | 165 break; |
165 case FTS_F: // Regular file. | 166 case FTS_F: // Regular file. |
166 case FTS_NSOK: // File, no stat info requested. | 167 case FTS_NSOK: // File, no stat info requested. |
167 errno = 0; | 168 errno = 0; |
168 if (!CopyFile(FilePath(ent->fts_path), target_path)) | 169 if (!CopyFile(FilePath(ent->fts_path), target_path)) |
169 error = errno ? errno : EINVAL; | 170 error = errno ? errno : EINVAL; |
170 break; | 171 break; |
171 case FTS_DP: // Postorder directory. | 172 case FTS_DP: // Postorder directory. |
172 case FTS_DOT: // "." or ".." | 173 case FTS_DOT: // "." or ".." |
173 // Skip it. | 174 // Skip it. |
174 continue; | 175 continue; |
175 case FTS_DC: // Directory causing a cycle. | 176 case FTS_DC: // Directory causing a cycle. |
176 // Skip this branch. | 177 // Skip this branch. |
177 if (fts_set(fts, ent, FTS_SKIP) != 0) | 178 if (fts_set(fts, ent, FTS_SKIP) != 0) |
178 error = errno; | 179 error = errno; |
179 break; | 180 break; |
180 case FTS_DNR: // Directory cannot be read. | 181 case FTS_DNR: // Directory cannot be read. |
181 case FTS_ERR: // Error. | 182 case FTS_ERR: // Error. |
182 case FTS_NS: // Stat failed. | 183 case FTS_NS: // Stat failed. |
183 // Abort with the error. | 184 // Abort with the error. |
184 error = ent->fts_errno; | 185 error = ent->fts_errno; |
185 break; | 186 break; |
186 case FTS_SL: // Symlink. | 187 case FTS_SL: // Symlink. |
187 case FTS_SLNONE: // Symlink with broken target. | 188 case FTS_SLNONE: // Symlink with broken target. |
188 LOG(WARNING) << "CopyDirectory() skipping symbolic link."; | 189 LOG(WARNING) << "CopyDirectory() skipping symbolic link: " << |
| 190 ent->fts_path; |
189 continue; | 191 continue; |
190 case FTS_DEFAULT: // Some other sort of file. | 192 case FTS_DEFAULT: // Some other sort of file. |
191 LOG(WARNING) << "CopyDirectory() skipping weird file."; | 193 LOG(WARNING) << "CopyDirectory() skipping file of unknown type: " << |
| 194 ent->fts_path; |
192 continue; | 195 continue; |
193 default: | 196 default: |
194 NOTREACHED(); | 197 NOTREACHED(); |
195 continue; // Hope for the best! | 198 continue; // Hope for the best! |
196 } | 199 } |
197 } | 200 } |
198 // fts_read may have returned NULL and set errno to indicate an error. | 201 // fts_read may have returned NULL and set errno to indicate an error. |
199 if (!error && errno != 0) | 202 if (!error && errno != 0) |
200 error = errno; | 203 error = errno; |
201 | 204 |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 munmap(data_, length_); | 574 munmap(data_, length_); |
572 if (file_ != -1) | 575 if (file_ != -1) |
573 close(file_); | 576 close(file_); |
574 | 577 |
575 data_ = NULL; | 578 data_ = NULL; |
576 length_ = 0; | 579 length_ = 0; |
577 file_ = -1; | 580 file_ = -1; |
578 } | 581 } |
579 | 582 |
580 } // namespace file_util | 583 } // namespace file_util |
OLD | NEW |