| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #if defined(TARGET_OS_ANDROID) | 6 #if defined(TARGET_OS_ANDROID) |
| 7 | 7 |
| 8 #include "bin/directory.h" | 8 #include "bin/directory.h" |
| 9 | 9 |
| 10 #include <dirent.h> // NOLINT | 10 #include <dirent.h> // NOLINT |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 void Reset(int new_length) { | 50 void Reset(int new_length) { |
| 51 length = new_length; | 51 length = new_length; |
| 52 data[length] = '\0'; | 52 data[length] = '\0'; |
| 53 } | 53 } |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 | 56 |
| 57 // Forward declarations. | 57 // Forward declarations. |
| 58 static bool ListRecursively(PathBuffer* path, | 58 static bool ListRecursively(PathBuffer* path, |
| 59 bool recursive, | 59 bool recursive, |
| 60 bool follow_links, |
| 60 DirectoryListing* listing); | 61 DirectoryListing* listing); |
| 61 static bool DeleteRecursively(PathBuffer* path); | 62 static bool DeleteRecursively(PathBuffer* path); |
| 62 | 63 |
| 63 | 64 |
| 64 static void PostError(DirectoryListing *listing, | 65 static void PostError(DirectoryListing *listing, |
| 65 const char* dir_name) { | 66 const char* dir_name) { |
| 66 listing->HandleError(dir_name); | 67 listing->HandleError(dir_name); |
| 67 } | 68 } |
| 68 | 69 |
| 69 | 70 |
| 70 static bool HandleDir(char* dir_name, | 71 static bool HandleDir(char* dir_name, |
| 71 PathBuffer* path, | 72 PathBuffer* path, |
| 72 bool recursive, | 73 bool recursive, |
| 74 bool follow_links, |
| 73 DirectoryListing *listing) { | 75 DirectoryListing *listing) { |
| 74 if (strcmp(dir_name, ".") == 0) return true; | 76 if (strcmp(dir_name, ".") == 0) return true; |
| 75 if (strcmp(dir_name, "..") == 0) return true; | 77 if (strcmp(dir_name, "..") == 0) return true; |
| 76 if (!path->Add(dir_name)) { | 78 if (!path->Add(dir_name)) { |
| 77 PostError(listing, path->data); | 79 PostError(listing, path->data); |
| 78 return false; | 80 return false; |
| 81 } |
| 79 return listing->HandleDirectory(path->data) && | 82 return listing->HandleDirectory(path->data) && |
| 80 (!recursive || ListRecursively(path, recursive, listing)); | 83 (!recursive || ListRecursively(path, recursive, follow_links, listing)); |
| 81 } | 84 } |
| 82 | 85 |
| 83 | 86 |
| 84 static bool HandleFile(char* file_name, | 87 static bool HandleFile(char* file_name, |
| 85 PathBuffer* path, | 88 PathBuffer* path, |
| 86 DirectoryListing *listing) { | 89 DirectoryListing *listing) { |
| 87 if (!path->Add(file_name)) { | 90 if (!path->Add(file_name)) { |
| 88 PostError(listing, path->data); | 91 PostError(listing, path->data); |
| 89 return false; | 92 return false; |
| 90 } | 93 } |
| 91 return listing->HandleFile(path->data); | 94 return listing->HandleFile(path->data); |
| 92 } | 95 } |
| 93 | 96 |
| 94 | 97 |
| 98 static bool HandleLink(char* link_name, |
| 99 PathBuffer* path, |
| 100 DirectoryListing *listing) { |
| 101 if (!path->Add(link_name)) { |
| 102 PostError(listing, path->data); |
| 103 return false; |
| 104 } |
| 105 return listing->HandleLink(path->data); |
| 106 } |
| 107 |
| 108 |
| 95 static bool ListRecursively(PathBuffer* path, | 109 static bool ListRecursively(PathBuffer* path, |
| 96 bool recursive, | 110 bool recursive, |
| 111 bool follow_links, |
| 97 DirectoryListing *listing) { | 112 DirectoryListing *listing) { |
| 98 if (!path->Add(File::PathSeparator())) { | 113 if (!path->Add(File::PathSeparator())) { |
| 99 PostError(listing, path->data); | 114 PostError(listing, path->data); |
| 100 return false; | 115 return false; |
| 101 } | 116 } |
| 102 DIR* dir_pointer; | 117 DIR* dir_pointer; |
| 103 do { | 118 do { |
| 104 dir_pointer = opendir(path->data); | 119 dir_pointer = opendir(path->data); |
| 105 } while (dir_pointer == NULL && errno == EINTR); | 120 } while (dir_pointer == NULL && errno == EINTR); |
| 106 if (dir_pointer == NULL) { | 121 if (dir_pointer == NULL) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 117 dirent* result; | 132 dirent* result; |
| 118 while ((status = TEMP_FAILURE_RETRY(readdir_r(dir_pointer, | 133 while ((status = TEMP_FAILURE_RETRY(readdir_r(dir_pointer, |
| 119 &entry, | 134 &entry, |
| 120 &result))) == 0 && | 135 &result))) == 0 && |
| 121 result != NULL) { | 136 result != NULL) { |
| 122 switch (entry.d_type) { | 137 switch (entry.d_type) { |
| 123 case DT_DIR: | 138 case DT_DIR: |
| 124 success = HandleDir(entry.d_name, | 139 success = HandleDir(entry.d_name, |
| 125 path, | 140 path, |
| 126 recursive, | 141 recursive, |
| 142 follow_links, |
| 127 listing) && success; | 143 listing) && success; |
| 128 break; | 144 break; |
| 129 case DT_REG: | 145 case DT_REG: |
| 130 success = HandleFile(entry.d_name, | 146 success = HandleFile(entry.d_name, |
| 131 path, | 147 path, |
| 132 listing) && success; | 148 listing) && success; |
| 133 break; | 149 break; |
| 134 case DT_LNK: | 150 case DT_LNK: |
| 151 if (!follow_links) { |
| 152 success = HandleLink(entry.d_name, |
| 153 path, |
| 154 listing) && success; |
| 155 break; |
| 156 } |
| 157 // Else fall through to next case. |
| 158 // Fall through. |
| 135 case DT_UNKNOWN: { | 159 case DT_UNKNOWN: { |
| 136 // On some file systems the entry type is not determined by | 160 // On some file systems the entry type is not determined by |
| 137 // readdir_r. For those and for links we use stat to determine | 161 // readdir_r. For those and for links we use stat to determine |
| 138 // the actual entry type. Notice that stat returns the type of | 162 // the actual entry type. Notice that stat returns the type of |
| 139 // the file pointed to. | 163 // the file pointed to. |
| 140 struct stat entry_info; | 164 struct stat entry_info; |
| 141 if (!path->Add(entry.d_name)) { | 165 if (!path->Add(entry.d_name)) { |
| 142 success = false; | 166 success = false; |
| 143 break; | 167 break; |
| 144 } | 168 } |
| 145 int stat_success = TEMP_FAILURE_RETRY(stat(path->data, &entry_info)); | 169 int stat_success; |
| 170 if (follow_links) { |
| 171 stat_success = TEMP_FAILURE_RETRY(stat(path->data, &entry_info)); |
| 172 } else { |
| 173 stat_success = TEMP_FAILURE_RETRY(lstat(path->data, &entry_info)); |
| 174 } |
| 146 if (stat_success == -1) { | 175 if (stat_success == -1) { |
| 147 success = false; | 176 success = false; |
| 148 PostError(listing, path->data); | 177 PostError(listing, path->data); |
| 149 break; | 178 break; |
| 150 } | 179 } |
| 151 path->Reset(path_length); | 180 path->Reset(path_length); |
| 152 if (S_ISDIR(entry_info.st_mode)) { | 181 if (S_ISDIR(entry_info.st_mode)) { |
| 153 success = HandleDir(entry.d_name, | 182 success = HandleDir(entry.d_name, |
| 154 path, | 183 path, |
| 155 recursive, | 184 recursive, |
| 185 follow_links, |
| 156 listing) && success; | 186 listing) && success; |
| 157 } else if (S_ISREG(entry_info.st_mode)) { | 187 } else if (S_ISREG(entry_info.st_mode)) { |
| 158 success = HandleFile(entry.d_name, | 188 success = HandleFile(entry.d_name, |
| 159 path, | 189 path, |
| 160 listing) && success; | 190 listing) && success; |
| 191 } else if (S_ISLNK(entry_info.st_mode)) { |
| 192 ASSERT(!follow_links); |
| 193 success = HandleLink(entry.d_name, |
| 194 path, |
| 195 listing) && success; |
| 161 } | 196 } |
| 162 ASSERT(!S_ISLNK(entry_info.st_mode)); | |
| 163 break; | 197 break; |
| 164 } | 198 } |
| 165 default: | 199 default: |
| 166 break; | 200 break; |
| 167 } | 201 } |
| 168 path->Reset(path_length); | 202 path->Reset(path_length); |
| 169 } | 203 } |
| 170 | 204 |
| 171 if (status != 0) { | 205 if (status != 0) { |
| 172 errno = status; | 206 errno = status; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 (closedir(dir_pointer) == -1) || | 309 (closedir(dir_pointer) == -1) || |
| 276 (remove(path->data) == -1)) { | 310 (remove(path->data) == -1)) { |
| 277 return false; | 311 return false; |
| 278 } | 312 } |
| 279 return success; | 313 return success; |
| 280 } | 314 } |
| 281 | 315 |
| 282 | 316 |
| 283 bool Directory::List(const char* dir_name, | 317 bool Directory::List(const char* dir_name, |
| 284 bool recursive, | 318 bool recursive, |
| 319 bool follow_links, |
| 285 DirectoryListing *listing) { | 320 DirectoryListing *listing) { |
| 286 PathBuffer path; | 321 PathBuffer path; |
| 287 if (!path.Add(dir_name)) { | 322 if (!path.Add(dir_name)) { |
| 288 PostError(listing, dir_name); | 323 PostError(listing, dir_name); |
| 289 return false; | 324 return false; |
| 290 } | 325 } |
| 291 return ListRecursively(&path, recursive, listing); | 326 return ListRecursively(&path, recursive, follow_links, listing); |
| 292 } | 327 } |
| 293 | 328 |
| 294 | 329 |
| 295 Directory::ExistsResult Directory::Exists(const char* dir_name) { | 330 Directory::ExistsResult Directory::Exists(const char* dir_name) { |
| 296 struct stat entry_info; | 331 struct stat entry_info; |
| 297 int success = TEMP_FAILURE_RETRY(stat(dir_name, &entry_info)); | 332 int success = TEMP_FAILURE_RETRY(stat(dir_name, &entry_info)); |
| 298 if (success == 0) { | 333 if (success == 0) { |
| 299 if (S_ISDIR(entry_info.st_mode)) { | 334 if (S_ISDIR(entry_info.st_mode)) { |
| 300 return EXISTS; | 335 return EXISTS; |
| 301 } else { | 336 } else { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 } | 449 } |
| 415 | 450 |
| 416 | 451 |
| 417 bool Directory::Rename(const char* path, const char* new_path) { | 452 bool Directory::Rename(const char* path, const char* new_path) { |
| 418 ExistsResult exists = Exists(path); | 453 ExistsResult exists = Exists(path); |
| 419 if (exists != EXISTS) return false; | 454 if (exists != EXISTS) return false; |
| 420 return (TEMP_FAILURE_RETRY(rename(path, new_path)) == 0); | 455 return (TEMP_FAILURE_RETRY(rename(path, new_path)) == 0); |
| 421 } | 456 } |
| 422 | 457 |
| 423 #endif // defined(TARGET_OS_ANDROID) | 458 #endif // defined(TARGET_OS_ANDROID) |
| OLD | NEW |