| 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 |