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_MACOS) | 6 #if defined(TARGET_OS_MACOS) |
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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 if (!listing->follow_links()) { | 122 if (!listing->follow_links()) { |
123 return kListLink; | 123 return kListLink; |
124 } | 124 } |
125 // Else fall through to next case. | 125 // Else fall through to next case. |
126 // Fall through. | 126 // Fall through. |
127 case DT_UNKNOWN: { | 127 case DT_UNKNOWN: { |
128 // On some file systems the entry type is not determined by | 128 // On some file systems the entry type is not determined by |
129 // readdir_r. For those and for links we use stat to determine | 129 // readdir_r. For those and for links we use stat to determine |
130 // the actual entry type. Notice that stat returns the type of | 130 // the actual entry type. Notice that stat returns the type of |
131 // the file pointed to. | 131 // the file pointed to. |
132 struct stat64 entry_info; | 132 struct stat entry_info; |
133 int stat_success; | 133 int stat_success; |
134 stat_success = TEMP_FAILURE_RETRY( | 134 stat_success = TEMP_FAILURE_RETRY( |
135 lstat64(listing->path_buffer().AsString(), &entry_info)); | 135 lstat(listing->path_buffer().AsString(), &entry_info)); |
136 if (stat_success == -1) { | 136 if (stat_success == -1) { |
137 return kListError; | 137 return kListError; |
138 } | 138 } |
139 if (listing->follow_links() && S_ISLNK(entry_info.st_mode)) { | 139 if (listing->follow_links() && S_ISLNK(entry_info.st_mode)) { |
140 // Check to see if we are in a loop created by a symbolic link. | 140 // Check to see if we are in a loop created by a symbolic link. |
141 LinkList current_link = { entry_info.st_dev, | 141 LinkList current_link = { entry_info.st_dev, |
142 entry_info.st_ino, | 142 entry_info.st_ino, |
143 link_ }; | 143 link_ }; |
144 LinkList* previous = link_; | 144 LinkList* previous = link_; |
145 while (previous != NULL) { | 145 while (previous != NULL) { |
146 if (previous->dev == current_link.dev && | 146 if (previous->dev == current_link.dev && |
147 previous->ino == current_link.ino) { | 147 previous->ino == current_link.ino) { |
148 // Report the looping link as a link, rather than following it. | 148 // Report the looping link as a link, rather than following it. |
149 return kListLink; | 149 return kListLink; |
150 } | 150 } |
151 previous = previous->next; | 151 previous = previous->next; |
152 } | 152 } |
153 stat_success = TEMP_FAILURE_RETRY( | 153 stat_success = TEMP_FAILURE_RETRY( |
154 stat64(listing->path_buffer().AsString(), &entry_info)); | 154 stat(listing->path_buffer().AsString(), &entry_info)); |
155 if (stat_success == -1) { | 155 if (stat_success == -1) { |
156 // Report a broken link as a link, even if follow_links is true. | 156 // Report a broken link as a link, even if follow_links is true. |
157 return kListLink; | 157 return kListLink; |
158 } | 158 } |
159 if (S_ISDIR(entry_info.st_mode)) { | 159 if (S_ISDIR(entry_info.st_mode)) { |
160 // Recurse into the subdirectory with current_link added to the | 160 // Recurse into the subdirectory with current_link added to the |
161 // linked list of seen file system links. | 161 // linked list of seen file system links. |
162 link_ = new LinkList(current_link); | 162 link_ = new LinkList(current_link); |
163 if (strcmp(entry.d_name, ".") == 0) return Next(listing); | 163 if (strcmp(entry.d_name, ".") == 0) return Next(listing); |
164 if (strcmp(entry.d_name, "..") == 0) return Next(listing); | 164 if (strcmp(entry.d_name, "..") == 0) return Next(listing); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 PathBuffer* path) { | 223 PathBuffer* path) { |
224 if (strcmp(dir_name, ".") == 0) return true; | 224 if (strcmp(dir_name, ".") == 0) return true; |
225 if (strcmp(dir_name, "..") == 0) return true; | 225 if (strcmp(dir_name, "..") == 0) return true; |
226 return path->Add(dir_name) && DeleteRecursively(path); | 226 return path->Add(dir_name) && DeleteRecursively(path); |
227 } | 227 } |
228 | 228 |
229 | 229 |
230 static bool DeleteRecursively(PathBuffer* path) { | 230 static bool DeleteRecursively(PathBuffer* path) { |
231 // Do not recurse into links for deletion. Instead delete the link. | 231 // Do not recurse into links for deletion. Instead delete the link. |
232 // If it's a file, delete it. | 232 // If it's a file, delete it. |
233 struct stat64 st; | 233 struct stat st; |
234 if (TEMP_FAILURE_RETRY(lstat64(path->AsString(), &st)) == -1) { | 234 if (TEMP_FAILURE_RETRY(lstat(path->AsString(), &st)) == -1) { |
235 return false; | 235 return false; |
236 } else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) { | 236 } else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) { |
237 return (unlink(path->AsString()) == 0); | 237 return (unlink(path->AsString()) == 0); |
238 } | 238 } |
239 | 239 |
240 if (!path->Add(File::PathSeparator())) return false; | 240 if (!path->Add(File::PathSeparator())) return false; |
241 | 241 |
242 // Not a link. Attempt to open as a directory and recurse into the | 242 // Not a link. Attempt to open as a directory and recurse into the |
243 // directory. | 243 // directory. |
244 DIR* dir_pointer; | 244 DIR* dir_pointer; |
(...skipping 24 matching lines...) Expand all Loading... |
269 case DT_LNK: | 269 case DT_LNK: |
270 // Treat all links as files. This will delete the link which | 270 // Treat all links as files. This will delete the link which |
271 // is what we want no matter if the link target is a file or a | 271 // is what we want no matter if the link target is a file or a |
272 // directory. | 272 // directory. |
273 success = success && DeleteFile(entry.d_name, path); | 273 success = success && DeleteFile(entry.d_name, path); |
274 break; | 274 break; |
275 case DT_UNKNOWN: { | 275 case DT_UNKNOWN: { |
276 // On some file systems the entry type is not determined by | 276 // On some file systems the entry type is not determined by |
277 // readdir_r. For those we use lstat to determine the entry | 277 // readdir_r. For those we use lstat to determine the entry |
278 // type. | 278 // type. |
279 struct stat64 entry_info; | 279 struct stat entry_info; |
280 if (!path->Add(entry.d_name)) { | 280 if (!path->Add(entry.d_name)) { |
281 success = false; | 281 success = false; |
282 break; | 282 break; |
283 } | 283 } |
284 int lstat_success = TEMP_FAILURE_RETRY( | 284 int lstat_success = TEMP_FAILURE_RETRY( |
285 lstat64(path->AsString(), &entry_info)); | 285 lstat(path->AsString(), &entry_info)); |
286 if (lstat_success == -1) { | 286 if (lstat_success == -1) { |
287 success = false; | 287 success = false; |
288 break; | 288 break; |
289 } | 289 } |
290 path->Reset(path_length); | 290 path->Reset(path_length); |
291 if (S_ISDIR(entry_info.st_mode)) { | 291 if (S_ISDIR(entry_info.st_mode)) { |
292 success = success && DeleteDir(entry.d_name, path); | 292 success = success && DeleteDir(entry.d_name, path); |
293 } else if (S_ISREG(entry_info.st_mode) || S_ISLNK(entry_info.st_mode)) { | 293 } else if (S_ISREG(entry_info.st_mode) || S_ISLNK(entry_info.st_mode)) { |
294 // Treat links as files. This will delete the link which is | 294 // Treat links as files. This will delete the link which is |
295 // what we want no matter if the link target is a file or a | 295 // what we want no matter if the link target is a file or a |
(...skipping 11 matching lines...) Expand all Loading... |
307 if ((read != 0) || | 307 if ((read != 0) || |
308 (closedir(dir_pointer) == -1) || | 308 (closedir(dir_pointer) == -1) || |
309 (remove(path->AsString()) == -1)) { | 309 (remove(path->AsString()) == -1)) { |
310 return false; | 310 return false; |
311 } | 311 } |
312 return success; | 312 return success; |
313 } | 313 } |
314 | 314 |
315 | 315 |
316 Directory::ExistsResult Directory::Exists(const char* dir_name) { | 316 Directory::ExistsResult Directory::Exists(const char* dir_name) { |
317 struct stat64 entry_info; | 317 struct stat entry_info; |
318 int success = TEMP_FAILURE_RETRY(stat64(dir_name, &entry_info)); | 318 int success = TEMP_FAILURE_RETRY(stat(dir_name, &entry_info)); |
319 if (success == 0) { | 319 if (success == 0) { |
320 if (S_ISDIR(entry_info.st_mode)) { | 320 if (S_ISDIR(entry_info.st_mode)) { |
321 return EXISTS; | 321 return EXISTS; |
322 } else { | 322 } else { |
323 return DOES_NOT_EXIST; | 323 return DOES_NOT_EXIST; |
324 } | 324 } |
325 } else { | 325 } else { |
326 if (errno == EACCES || | 326 if (errno == EACCES || |
327 errno == EBADF || | 327 errno == EBADF || |
328 errno == EFAULT || | 328 errno == EFAULT || |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 bool Directory::Rename(const char* path, const char* new_path) { | 425 bool Directory::Rename(const char* path, const char* new_path) { |
426 ExistsResult exists = Exists(path); | 426 ExistsResult exists = Exists(path); |
427 if (exists != EXISTS) return false; | 427 if (exists != EXISTS) return false; |
428 return (TEMP_FAILURE_RETRY(rename(path, new_path)) == 0); | 428 return (TEMP_FAILURE_RETRY(rename(path, new_path)) == 0); |
429 } | 429 } |
430 | 430 |
431 } // namespace bin | 431 } // namespace bin |
432 } // namespace dart | 432 } // namespace dart |
433 | 433 |
434 #endif // defined(TARGET_OS_MACOS) | 434 #endif // defined(TARGET_OS_MACOS) |
OLD | NEW |