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_EQ('/', suffix[0]); | 145 DCHECK(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. | |
161 if (mkdir(target_path.value().c_str(), 0777) != 0) { | 160 if (mkdir(target_path.value().c_str(), 0777) != 0) { |
162 if (errno != EEXIST) | 161 if (errno != EEXIST) |
163 error = errno; | 162 error = errno; |
164 } | 163 } |
165 break; | 164 break; |
166 case FTS_F: // Regular file. | 165 case FTS_F: // Regular file. |
167 case FTS_NSOK: // File, no stat info requested. | 166 case FTS_NSOK: // File, no stat info requested. |
168 errno = 0; | 167 errno = 0; |
169 if (!CopyFile(FilePath(ent->fts_path), target_path)) | 168 if (!CopyFile(FilePath(ent->fts_path), target_path)) |
170 error = errno ? errno : EINVAL; | 169 error = errno ? errno : EINVAL; |
171 break; | 170 break; |
172 case FTS_DP: // Postorder directory. | 171 case FTS_DP: // Postorder directory. |
173 case FTS_DOT: // "." or ".." | 172 case FTS_DOT: // "." or ".." |
174 // Skip it. | 173 // Skip it. |
175 continue; | 174 continue; |
176 case FTS_DC: // Directory causing a cycle. | 175 case FTS_DC: // Directory causing a cycle. |
177 // Skip this branch. | 176 // Skip this branch. |
178 if (fts_set(fts, ent, FTS_SKIP) != 0) | 177 if (fts_set(fts, ent, FTS_SKIP) != 0) |
179 error = errno; | 178 error = errno; |
180 break; | 179 break; |
181 case FTS_DNR: // Directory cannot be read. | 180 case FTS_DNR: // Directory cannot be read. |
182 case FTS_ERR: // Error. | 181 case FTS_ERR: // Error. |
183 case FTS_NS: // Stat failed. | 182 case FTS_NS: // Stat failed. |
184 // Abort with the error. | 183 // Abort with the error. |
185 error = ent->fts_errno; | 184 error = ent->fts_errno; |
186 break; | 185 break; |
187 case FTS_SL: // Symlink. | 186 case FTS_SL: // Symlink. |
188 case FTS_SLNONE: // Symlink with broken target. | 187 case FTS_SLNONE: // Symlink with broken target. |
189 LOG(WARNING) << "CopyDirectory() skipping symbolic link: " << | 188 LOG(WARNING) << "CopyDirectory() skipping symbolic link."; |
190 ent->fts_path; | |
191 continue; | 189 continue; |
192 case FTS_DEFAULT: // Some other sort of file. | 190 case FTS_DEFAULT: // Some other sort of file. |
193 LOG(WARNING) << "CopyDirectory() skipping file of unknown type: " << | 191 LOG(WARNING) << "CopyDirectory() skipping weird file."; |
194 ent->fts_path; | |
195 continue; | 192 continue; |
196 default: | 193 default: |
197 NOTREACHED(); | 194 NOTREACHED(); |
198 continue; // Hope for the best! | 195 continue; // Hope for the best! |
199 } | 196 } |
200 } | 197 } |
201 // fts_read may have returned NULL and set errno to indicate an error. | 198 // fts_read may have returned NULL and set errno to indicate an error. |
202 if (!error && errno != 0) | 199 if (!error && errno != 0) |
203 error = errno; | 200 error = errno; |
204 | 201 |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 munmap(data_, length_); | 571 munmap(data_, length_); |
575 if (file_ != -1) | 572 if (file_ != -1) |
576 close(file_); | 573 close(file_); |
577 | 574 |
578 data_ = NULL; | 575 data_ = NULL; |
579 length_ = 0; | 576 length_ = 0; |
580 file_ = -1; | 577 file_ = -1; |
581 } | 578 } |
582 | 579 |
583 } // namespace file_util | 580 } // namespace file_util |
OLD | NEW |