Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(373)

Side by Side Diff: runtime/bin/directory_linux.cc

Issue 63363010: Add support for working with large files, in dart:io. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698