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