| 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 "bin/directory.h" | 5 #include "bin/directory.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <sys/stat.h> | 8 #include <sys/stat.h> |
| 9 | 9 |
| 10 #include "bin/platform.h" | 10 #include "bin/platform.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 snprintf(os_error_message, os_error_message_len, "OS Error %d", error_code); | 28 snprintf(os_error_message, os_error_message_len, "OS Error %d", error_code); |
| 29 } | 29 } |
| 30 os_error_message[os_error_message_len - 1] = '\0'; | 30 os_error_message[os_error_message_len - 1] = '\0'; |
| 31 return error_code; | 31 return error_code; |
| 32 } | 32 } |
| 33 | 33 |
| 34 | 34 |
| 35 // Forward declaration. | 35 // Forward declaration. |
| 36 static bool ListRecursively(const char* dir_name, | 36 static bool ListRecursively(const char* dir_name, |
| 37 bool recursive, | 37 bool recursive, |
| 38 Dart_Port dir_port, | 38 DirectoryListing* listing); |
| 39 Dart_Port file_port, | |
| 40 Dart_Port done_port, | |
| 41 Dart_Port error_port); | |
| 42 static bool DeleteRecursively(const char* dir_name); | 39 static bool DeleteRecursively(const char* dir_name); |
| 43 | 40 |
| 44 | 41 |
| 45 static bool HandleDir(char* dir_name, | 42 static bool HandleDir(char* dir_name, |
| 46 char* path, | 43 char* path, |
| 47 int path_length, | 44 int path_length, |
| 48 bool recursive, | 45 bool recursive, |
| 49 Dart_Port dir_port, | 46 DirectoryListing* listing) { |
| 50 Dart_Port file_port, | |
| 51 Dart_Port done_port, | |
| 52 Dart_Port error_port) { | |
| 53 if (strcmp(dir_name, ".") != 0 && | 47 if (strcmp(dir_name, ".") != 0 && |
| 54 strcmp(dir_name, "..") != 0) { | 48 strcmp(dir_name, "..") != 0) { |
| 55 size_t written = snprintf(path + path_length, | 49 size_t written = snprintf(path + path_length, |
| 56 MAX_PATH - path_length, | 50 MAX_PATH - path_length, |
| 57 "%s", | 51 "%s", |
| 58 dir_name); | 52 dir_name); |
| 59 if (written != strlen(dir_name)) { | 53 if (written != strlen(dir_name)) { |
| 60 return false; | 54 return false; |
| 61 } | 55 } |
| 62 if (dir_port != 0) { | 56 bool ok = listing->HandleDirectory(dir_name); |
| 63 Dart_Handle name = Dart_NewString(path); | 57 if (!ok) return ok; |
| 64 Dart_Post(dir_port, name); | |
| 65 } | |
| 66 if (recursive) { | 58 if (recursive) { |
| 67 return ListRecursively(path, | 59 return ListRecursively(path, recursive, listing); |
| 68 recursive, | |
| 69 dir_port, | |
| 70 file_port, | |
| 71 done_port, | |
| 72 error_port); | |
| 73 } | 60 } |
| 74 } | 61 } |
| 75 return true; | 62 return true; |
| 76 } | 63 } |
| 77 | 64 |
| 78 | 65 |
| 79 static bool HandleFile(char* file_name, | 66 static bool HandleFile(char* file_name, |
| 80 char* path, | 67 char* path, |
| 81 int path_length, | 68 int path_length, |
| 82 Dart_Port file_port) { | 69 DirectoryListing* listing) { |
| 83 if (file_port != 0) { | 70 size_t written = snprintf(path + path_length, |
| 84 size_t written = snprintf(path + path_length, | 71 MAX_PATH - path_length, |
| 85 MAX_PATH - path_length, | 72 "%s", |
| 86 "%s", | 73 file_name); |
| 87 file_name); | 74 if (written != strlen(file_name)) { |
| 88 if (written != strlen(file_name)) { | 75 return false; |
| 89 return false; | 76 }; |
| 90 }; | 77 return listing->HandleFile(file_name); |
| 91 Dart_Handle name = Dart_NewString(path); | |
| 92 Dart_Post(file_port, name); | |
| 93 } | |
| 94 return true; | |
| 95 } | 78 } |
| 96 | 79 |
| 97 | 80 |
| 98 static bool HandleEntry(LPWIN32_FIND_DATA find_file_data, | 81 static bool HandleEntry(LPWIN32_FIND_DATA find_file_data, |
| 99 char* path, | 82 char* path, |
| 100 int path_length, | 83 int path_length, |
| 101 bool recursive, | 84 bool recursive, |
| 102 Dart_Port dir_port, | 85 DirectoryListing* listing) { |
| 103 Dart_Port file_port, | |
| 104 Dart_Port done_port, | |
| 105 Dart_Port error_port) { | |
| 106 DWORD attributes = find_file_data->dwFileAttributes; | 86 DWORD attributes = find_file_data->dwFileAttributes; |
| 107 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 87 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
| 108 return HandleDir(find_file_data->cFileName, | 88 return HandleDir(find_file_data->cFileName, |
| 109 path, | 89 path, |
| 110 path_length, | 90 path_length, |
| 111 recursive, | 91 recursive, |
| 112 dir_port, | 92 listing); |
| 113 file_port, | |
| 114 done_port, | |
| 115 error_port); | |
| 116 } else { | 93 } else { |
| 117 return HandleFile(find_file_data->cFileName, path, path_length, file_port); | 94 return HandleFile(find_file_data->cFileName, path, path_length, listing); |
| 118 } | 95 } |
| 119 } | 96 } |
| 120 | 97 |
| 121 | 98 |
| 122 // ComputeFullSearchPath must be called with a path array of size at | 99 // ComputeFullSearchPath must be called with a path array of size at |
| 123 // least MAX_PATH. | 100 // least MAX_PATH. |
| 124 static bool ComputeFullSearchPath(const char* dir_name, | 101 static bool ComputeFullSearchPath(const char* dir_name, |
| 125 char* path, | 102 char* path, |
| 126 int* path_length) { | 103 int* path_length) { |
| 127 // GetFullPathName only works in a multi-threaded environment if | 104 // GetFullPathName only works in a multi-threaded environment if |
| (...skipping 11 matching lines...) Expand all Loading... |
| 139 MAX_PATH - *path_length, | 116 MAX_PATH - *path_length, |
| 140 "%s", | 117 "%s", |
| 141 "\\*"); | 118 "\\*"); |
| 142 if (written != 2) { | 119 if (written != 2) { |
| 143 return false; | 120 return false; |
| 144 } | 121 } |
| 145 *path_length += written; | 122 *path_length += written; |
| 146 return true; | 123 return true; |
| 147 } | 124 } |
| 148 | 125 |
| 149 static void PostError(Dart_Port error_port, | 126 static void PostError(DirectoryListing* listing, |
| 150 const char* prefix, | 127 const char* prefix, |
| 151 const char* suffix) { | 128 const char* suffix) { |
| 152 if (error_port != 0) { | 129 char* error_str = Platform::StrError(GetLastError()); |
| 153 char* error_str = Platform::StrError(GetLastError()); | 130 int error_message_size = |
| 154 int error_message_size = | 131 strlen(prefix) + strlen(suffix) + strlen(error_str) + 3; |
| 155 strlen(prefix) + strlen(suffix) + strlen(error_str) + 3; | 132 char* message = static_cast<char*>(malloc(error_message_size + 1)); |
| 156 char* message = static_cast<char*>(malloc(error_message_size + 1)); | 133 size_t written = snprintf(message, |
| 157 size_t written = snprintf(message, | 134 error_message_size + 1, |
| 158 error_message_size + 1, | 135 "%s%s (%s)", |
| 159 "%s%s (%s)", | 136 prefix, |
| 160 prefix, | 137 suffix, |
| 161 suffix, | 138 error_str); |
| 162 error_str); | 139 ASSERT(written == error_message_size); |
| 163 ASSERT(written == error_message_size); | 140 free(error_str); |
| 164 free(error_str); | 141 listing->HandleError(message); |
| 165 Dart_Post(error_port, Dart_NewString(message)); | 142 free(message); |
| 166 free(message); | |
| 167 } | |
| 168 } | 143 } |
| 169 | 144 |
| 170 | 145 |
| 171 static bool ListRecursively(const char* dir_name, | 146 static bool ListRecursively(const char* dir_name, |
| 172 bool recursive, | 147 bool recursive, |
| 173 Dart_Port dir_port, | 148 DirectoryListing* listing) { |
| 174 Dart_Port file_port, | |
| 175 Dart_Port done_port, | |
| 176 Dart_Port error_port) { | |
| 177 // Compute full path for the directory currently being listed. The | 149 // Compute full path for the directory currently being listed. The |
| 178 // path buffer will be used to construct the current path in the | 150 // path buffer will be used to construct the current path in the |
| 179 // recursive traversal. path_length does not always equal | 151 // recursive traversal. path_length does not always equal |
| 180 // strlen(path) but indicates the current prefix of path that is the | 152 // strlen(path) but indicates the current prefix of path that is the |
| 181 // path of the current directory in the traversal. | 153 // path of the current directory in the traversal. |
| 182 char* path = static_cast<char*>(malloc(MAX_PATH)); | 154 char* path = static_cast<char*>(malloc(MAX_PATH)); |
| 183 int path_length = 0; | 155 int path_length = 0; |
| 184 bool valid = ComputeFullSearchPath(dir_name, path, &path_length); | 156 bool valid = ComputeFullSearchPath(dir_name, path, &path_length); |
| 185 if (!valid) { | 157 if (!valid) { |
| 186 PostError(error_port, "Directory listing failed for: ", dir_name); | 158 PostError(listing, "Directory listing failed for: ", dir_name); |
| 187 free(path); | 159 free(path); |
| 188 return false; | 160 return false; |
| 189 } | 161 } |
| 190 | 162 |
| 191 WIN32_FIND_DATA find_file_data; | 163 WIN32_FIND_DATA find_file_data; |
| 192 HANDLE find_handle = FindFirstFile(path, &find_file_data); | 164 HANDLE find_handle = FindFirstFile(path, &find_file_data); |
| 193 | 165 |
| 194 // Adjust the path by removing the '*' used for the search. | 166 // Adjust the path by removing the '*' used for the search. |
| 195 path_length -= 1; | 167 path_length -= 1; |
| 196 path[path_length] = '\0'; | 168 path[path_length] = '\0'; |
| 197 | 169 |
| 198 if (find_handle == INVALID_HANDLE_VALUE) { | 170 if (find_handle == INVALID_HANDLE_VALUE) { |
| 199 PostError(error_port, "Directory listing failed for: ", path); | 171 PostError(listing, "Directory listing failed for: ", path); |
| 200 free(path); | 172 free(path); |
| 201 return false; | 173 return false; |
| 202 } | 174 } |
| 203 | 175 |
| 204 bool success = HandleEntry(&find_file_data, | 176 bool success = HandleEntry(&find_file_data, |
| 205 path, | 177 path, |
| 206 path_length, | 178 path_length, |
| 207 recursive, | 179 recursive, |
| 208 dir_port, | 180 listing); |
| 209 file_port, | |
| 210 done_port, | |
| 211 error_port); | |
| 212 | 181 |
| 213 while ((FindNextFile(find_handle, &find_file_data) != 0) && success) { | 182 while ((FindNextFile(find_handle, &find_file_data) != 0) && success) { |
| 214 success = success && HandleEntry(&find_file_data, | 183 success = success && HandleEntry(&find_file_data, |
| 215 path, | 184 path, |
| 216 path_length, | 185 path_length, |
| 217 recursive, | 186 recursive, |
| 218 dir_port, | 187 listing); |
| 219 file_port, | |
| 220 done_port, | |
| 221 error_port); | |
| 222 } | 188 } |
| 223 | 189 |
| 224 if (GetLastError() != ERROR_NO_MORE_FILES) { | 190 if (GetLastError() != ERROR_NO_MORE_FILES) { |
| 225 success = false; | 191 success = false; |
| 226 PostError(error_port, "Directory listing failed", ""); | 192 PostError(listing, "Directory listing failed", ""); |
| 227 } | 193 } |
| 228 | 194 |
| 229 if (FindClose(find_handle) == 0) { | 195 if (FindClose(find_handle) == 0) { |
| 230 PostError(error_port, "Failed to close directory", ""); | 196 PostError(listing, "Failed to close directory", ""); |
| 231 } | 197 } |
| 232 free(path); | 198 free(path); |
| 233 | 199 |
| 234 return success; | 200 return success; |
| 235 } | 201 } |
| 236 | 202 |
| 237 | 203 |
| 238 static bool DeleteFile(char* file_name, | 204 static bool DeleteFile(char* file_name, |
| 239 char* path, | 205 char* path, |
| 240 int path_length) { | 206 int path_length) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 if ((GetLastError() != ERROR_NO_MORE_FILES) || | 282 if ((GetLastError() != ERROR_NO_MORE_FILES) || |
| 317 (FindClose(find_handle) == 0) || | 283 (FindClose(find_handle) == 0) || |
| 318 (RemoveDirectory(dir_name) == 0)) { | 284 (RemoveDirectory(dir_name) == 0)) { |
| 319 return false; | 285 return false; |
| 320 } | 286 } |
| 321 | 287 |
| 322 return success; | 288 return success; |
| 323 } | 289 } |
| 324 | 290 |
| 325 | 291 |
| 326 void Directory::List(const char* dir_name, | 292 bool Directory::List(const char* dir_name, |
| 327 bool recursive, | 293 bool recursive, |
| 328 Dart_Port dir_port, | 294 DirectoryListing* listing) { |
| 329 Dart_Port file_port, | 295 bool completed = ListRecursively(dir_name, recursive, listing); |
| 330 Dart_Port done_port, | 296 return completed; |
| 331 Dart_Port error_port) { | |
| 332 bool result = ListRecursively(dir_name, | |
| 333 recursive, | |
| 334 dir_port, | |
| 335 file_port, | |
| 336 done_port, | |
| 337 error_port); | |
| 338 if (done_port != 0) { | |
| 339 Dart_Handle value = Dart_NewBoolean(result); | |
| 340 Dart_Post(done_port, value); | |
| 341 } | |
| 342 } | 297 } |
| 343 | 298 |
| 344 | 299 |
| 345 Directory::ExistsResult Directory::Exists(const char* dir_name) { | 300 Directory::ExistsResult Directory::Exists(const char* dir_name) { |
| 346 struct stat entry_info; | 301 struct stat entry_info; |
| 347 int stat_success = stat(dir_name, &entry_info); | 302 int stat_success = stat(dir_name, &entry_info); |
| 348 if (stat_success == 0) { | 303 if (stat_success == 0) { |
| 349 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) { | 304 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) { |
| 350 return EXISTS; | 305 return EXISTS; |
| 351 } else { | 306 } else { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 } | 395 } |
| 441 | 396 |
| 442 | 397 |
| 443 bool Directory::Delete(const char* dir_name, bool recursive) { | 398 bool Directory::Delete(const char* dir_name, bool recursive) { |
| 444 if (!recursive) { | 399 if (!recursive) { |
| 445 return (RemoveDirectory(dir_name) != 0); | 400 return (RemoveDirectory(dir_name) != 0); |
| 446 } else { | 401 } else { |
| 447 return DeleteRecursively(dir_name); | 402 return DeleteRecursively(dir_name); |
| 448 } | 403 } |
| 449 } | 404 } |
| OLD | NEW |