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

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

Issue 600273004: Remove the assumption that stat64 and lstat64 cannot return EINTR on Linux (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 months 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
« no previous file with comments | « no previous file | runtime/bin/file_linux.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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)
OLDNEW
« no previous file with comments | « no previous file | runtime/bin/file_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698