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

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

Issue 12638039: dart:io | Add "followLinks" optional parameter to Directory.list, let it return Link objects when f… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Switch from Stream.reduce to Completer in link_test. Created 7 years, 9 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 | « runtime/bin/directory.cc ('k') | runtime/bin/directory_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_ANDROID) 6 #if defined(TARGET_OS_ANDROID)
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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 void Reset(int new_length) { 50 void Reset(int new_length) {
51 length = new_length; 51 length = new_length;
52 data[length] = '\0'; 52 data[length] = '\0';
53 } 53 }
54 }; 54 };
55 55
56 56
57 // Forward declarations. 57 // Forward declarations.
58 static bool ListRecursively(PathBuffer* path, 58 static bool ListRecursively(PathBuffer* path,
59 bool recursive, 59 bool recursive,
60 bool follow_links,
60 DirectoryListing* listing); 61 DirectoryListing* listing);
61 static bool DeleteRecursively(PathBuffer* path); 62 static bool DeleteRecursively(PathBuffer* path);
62 63
63 64
64 static void PostError(DirectoryListing *listing, 65 static void PostError(DirectoryListing *listing,
65 const char* dir_name) { 66 const char* dir_name) {
66 listing->HandleError(dir_name); 67 listing->HandleError(dir_name);
67 } 68 }
68 69
69 70
70 static bool HandleDir(char* dir_name, 71 static bool HandleDir(char* dir_name,
71 PathBuffer* path, 72 PathBuffer* path,
72 bool recursive, 73 bool recursive,
74 bool follow_links,
73 DirectoryListing *listing) { 75 DirectoryListing *listing) {
74 if (strcmp(dir_name, ".") == 0) return true; 76 if (strcmp(dir_name, ".") == 0) return true;
75 if (strcmp(dir_name, "..") == 0) return true; 77 if (strcmp(dir_name, "..") == 0) return true;
76 if (!path->Add(dir_name)) { 78 if (!path->Add(dir_name)) {
77 PostError(listing, path->data); 79 PostError(listing, path->data);
78 return false; 80 return false;
81 }
79 return listing->HandleDirectory(path->data) && 82 return listing->HandleDirectory(path->data) &&
80 (!recursive || ListRecursively(path, recursive, listing)); 83 (!recursive || ListRecursively(path, recursive, follow_links, listing));
81 } 84 }
82 85
83 86
84 static bool HandleFile(char* file_name, 87 static bool HandleFile(char* file_name,
85 PathBuffer* path, 88 PathBuffer* path,
86 DirectoryListing *listing) { 89 DirectoryListing *listing) {
87 if (!path->Add(file_name)) { 90 if (!path->Add(file_name)) {
88 PostError(listing, path->data); 91 PostError(listing, path->data);
89 return false; 92 return false;
90 } 93 }
91 return listing->HandleFile(path->data); 94 return listing->HandleFile(path->data);
92 } 95 }
93 96
94 97
98 static bool HandleLink(char* link_name,
99 PathBuffer* path,
100 DirectoryListing *listing) {
101 if (!path->Add(link_name)) {
102 PostError(listing, path->data);
103 return false;
104 }
105 return listing->HandleLink(path->data);
106 }
107
108
95 static bool ListRecursively(PathBuffer* path, 109 static bool ListRecursively(PathBuffer* path,
96 bool recursive, 110 bool recursive,
111 bool follow_links,
97 DirectoryListing *listing) { 112 DirectoryListing *listing) {
98 if (!path->Add(File::PathSeparator())) { 113 if (!path->Add(File::PathSeparator())) {
99 PostError(listing, path->data); 114 PostError(listing, path->data);
100 return false; 115 return false;
101 } 116 }
102 DIR* dir_pointer; 117 DIR* dir_pointer;
103 do { 118 do {
104 dir_pointer = opendir(path->data); 119 dir_pointer = opendir(path->data);
105 } while (dir_pointer == NULL && errno == EINTR); 120 } while (dir_pointer == NULL && errno == EINTR);
106 if (dir_pointer == NULL) { 121 if (dir_pointer == NULL) {
(...skipping 10 matching lines...) Expand all
117 dirent* result; 132 dirent* result;
118 while ((status = TEMP_FAILURE_RETRY(readdir_r(dir_pointer, 133 while ((status = TEMP_FAILURE_RETRY(readdir_r(dir_pointer,
119 &entry, 134 &entry,
120 &result))) == 0 && 135 &result))) == 0 &&
121 result != NULL) { 136 result != NULL) {
122 switch (entry.d_type) { 137 switch (entry.d_type) {
123 case DT_DIR: 138 case DT_DIR:
124 success = HandleDir(entry.d_name, 139 success = HandleDir(entry.d_name,
125 path, 140 path,
126 recursive, 141 recursive,
142 follow_links,
127 listing) && success; 143 listing) && success;
128 break; 144 break;
129 case DT_REG: 145 case DT_REG:
130 success = HandleFile(entry.d_name, 146 success = HandleFile(entry.d_name,
131 path, 147 path,
132 listing) && success; 148 listing) && success;
133 break; 149 break;
134 case DT_LNK: 150 case DT_LNK:
151 if (!follow_links) {
152 success = HandleLink(entry.d_name,
153 path,
154 listing) && success;
155 break;
156 }
157 // Else fall through to next case.
158 // Fall through.
135 case DT_UNKNOWN: { 159 case DT_UNKNOWN: {
136 // On some file systems the entry type is not determined by 160 // On some file systems the entry type is not determined by
137 // readdir_r. For those and for links we use stat to determine 161 // readdir_r. For those and for links we use stat to determine
138 // the actual entry type. Notice that stat returns the type of 162 // the actual entry type. Notice that stat returns the type of
139 // the file pointed to. 163 // the file pointed to.
140 struct stat entry_info; 164 struct stat entry_info;
141 if (!path->Add(entry.d_name)) { 165 if (!path->Add(entry.d_name)) {
142 success = false; 166 success = false;
143 break; 167 break;
144 } 168 }
145 int stat_success = TEMP_FAILURE_RETRY(stat(path->data, &entry_info)); 169 int stat_success;
170 if (follow_links) {
171 stat_success = TEMP_FAILURE_RETRY(stat(path->data, &entry_info));
172 } else {
173 stat_success = TEMP_FAILURE_RETRY(lstat(path->data, &entry_info));
174 }
146 if (stat_success == -1) { 175 if (stat_success == -1) {
147 success = false; 176 success = false;
148 PostError(listing, path->data); 177 PostError(listing, path->data);
149 break; 178 break;
150 } 179 }
151 path->Reset(path_length); 180 path->Reset(path_length);
152 if (S_ISDIR(entry_info.st_mode)) { 181 if (S_ISDIR(entry_info.st_mode)) {
153 success = HandleDir(entry.d_name, 182 success = HandleDir(entry.d_name,
154 path, 183 path,
155 recursive, 184 recursive,
185 follow_links,
156 listing) && success; 186 listing) && success;
157 } else if (S_ISREG(entry_info.st_mode)) { 187 } else if (S_ISREG(entry_info.st_mode)) {
158 success = HandleFile(entry.d_name, 188 success = HandleFile(entry.d_name,
159 path, 189 path,
160 listing) && success; 190 listing) && success;
191 } else if (S_ISLNK(entry_info.st_mode)) {
192 ASSERT(!follow_links);
193 success = HandleLink(entry.d_name,
194 path,
195 listing) && success;
161 } 196 }
162 ASSERT(!S_ISLNK(entry_info.st_mode));
163 break; 197 break;
164 } 198 }
165 default: 199 default:
166 break; 200 break;
167 } 201 }
168 path->Reset(path_length); 202 path->Reset(path_length);
169 } 203 }
170 204
171 if (status != 0) { 205 if (status != 0) {
172 errno = status; 206 errno = status;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 (closedir(dir_pointer) == -1) || 309 (closedir(dir_pointer) == -1) ||
276 (remove(path->data) == -1)) { 310 (remove(path->data) == -1)) {
277 return false; 311 return false;
278 } 312 }
279 return success; 313 return success;
280 } 314 }
281 315
282 316
283 bool Directory::List(const char* dir_name, 317 bool Directory::List(const char* dir_name,
284 bool recursive, 318 bool recursive,
319 bool follow_links,
285 DirectoryListing *listing) { 320 DirectoryListing *listing) {
286 PathBuffer path; 321 PathBuffer path;
287 if (!path.Add(dir_name)) { 322 if (!path.Add(dir_name)) {
288 PostError(listing, dir_name); 323 PostError(listing, dir_name);
289 return false; 324 return false;
290 } 325 }
291 return ListRecursively(&path, recursive, listing); 326 return ListRecursively(&path, recursive, follow_links, listing);
292 } 327 }
293 328
294 329
295 Directory::ExistsResult Directory::Exists(const char* dir_name) { 330 Directory::ExistsResult Directory::Exists(const char* dir_name) {
296 struct stat entry_info; 331 struct stat entry_info;
297 int success = TEMP_FAILURE_RETRY(stat(dir_name, &entry_info)); 332 int success = TEMP_FAILURE_RETRY(stat(dir_name, &entry_info));
298 if (success == 0) { 333 if (success == 0) {
299 if (S_ISDIR(entry_info.st_mode)) { 334 if (S_ISDIR(entry_info.st_mode)) {
300 return EXISTS; 335 return EXISTS;
301 } else { 336 } else {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 } 449 }
415 450
416 451
417 bool Directory::Rename(const char* path, const char* new_path) { 452 bool Directory::Rename(const char* path, const char* new_path) {
418 ExistsResult exists = Exists(path); 453 ExistsResult exists = Exists(path);
419 if (exists != EXISTS) return false; 454 if (exists != EXISTS) return false;
420 return (TEMP_FAILURE_RETRY(rename(path, new_path)) == 0); 455 return (TEMP_FAILURE_RETRY(rename(path, new_path)) == 0);
421 } 456 }
422 457
423 #endif // defined(TARGET_OS_ANDROID) 458 #endif // defined(TARGET_OS_ANDROID)
OLDNEW
« no previous file with comments | « runtime/bin/directory.cc ('k') | runtime/bin/directory_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698