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 |