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