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

Side by Side Diff: runtime/bin/directory_macos.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_linux.cc ('k') | runtime/bin/directory_patch.dart » ('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_MACOS) 6 #if defined(TARGET_OS_MACOS)
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;
79 } 81 }
80 return listing->HandleDirectory(path->data) && 82 return listing->HandleDirectory(path->data) &&
81 (!recursive || ListRecursively(path, recursive, listing)); 83 (!recursive || ListRecursively(path, recursive, follow_links, listing));
82 } 84 }
83 85
84 86
85 static bool HandleFile(char* file_name, 87 static bool HandleFile(char* file_name,
86 PathBuffer* path, 88 PathBuffer* path,
87 DirectoryListing *listing) { 89 DirectoryListing *listing) {
88 if (!path->Add(file_name)) { 90 if (!path->Add(file_name)) {
89 PostError(listing, path->data); 91 PostError(listing, path->data);
90 return false; 92 return false;
91 } 93 }
92 return listing->HandleFile(path->data); 94 return listing->HandleFile(path->data);
93 } 95 }
94 96
95 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
96 static bool ListRecursively(PathBuffer* path, 109 static bool ListRecursively(PathBuffer* path,
97 bool recursive, 110 bool recursive,
111 bool follow_links,
98 DirectoryListing *listing) { 112 DirectoryListing *listing) {
99 if (!path->Add(File::PathSeparator())) { 113 if (!path->Add(File::PathSeparator())) {
100 PostError(listing, path->data); 114 PostError(listing, path->data);
101 return false; 115 return false;
102 } 116 }
103 DIR* dir_pointer; 117 DIR* dir_pointer;
104 do { 118 do {
105 dir_pointer = opendir(path->data); 119 dir_pointer = opendir(path->data);
106 } while (dir_pointer == NULL && errno == EINTR); 120 } while (dir_pointer == NULL && errno == EINTR);
107 if (dir_pointer == NULL) { 121 if (dir_pointer == NULL) {
(...skipping 10 matching lines...) Expand all
118 dirent* result; 132 dirent* result;
119 while ((status = TEMP_FAILURE_RETRY(readdir_r(dir_pointer, 133 while ((status = TEMP_FAILURE_RETRY(readdir_r(dir_pointer,
120 &entry, 134 &entry,
121 &result))) == 0 && 135 &result))) == 0 &&
122 result != NULL) { 136 result != NULL) {
123 switch (entry.d_type) { 137 switch (entry.d_type) {
124 case DT_DIR: 138 case DT_DIR:
125 success = HandleDir(entry.d_name, 139 success = HandleDir(entry.d_name,
126 path, 140 path,
127 recursive, 141 recursive,
142 follow_links,
128 listing) && success; 143 listing) && success;
129 break; 144 break;
130 case DT_REG: 145 case DT_REG:
131 success = HandleFile(entry.d_name, 146 success = HandleFile(entry.d_name,
132 path, 147 path,
133 listing) && success; 148 listing) && success;
134 break; 149 break;
135 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.
136 case DT_UNKNOWN: { 159 case DT_UNKNOWN: {
137 // On some file systems the entry type is not determined by 160 // On some file systems the entry type is not determined by
138 // 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
139 // the actual entry type. Notice that stat returns the type of 162 // the actual entry type. Notice that stat returns the type of
140 // the file pointed to. 163 // the file pointed to.
141 struct stat entry_info; 164 struct stat entry_info;
142 if (!path->Add(entry.d_name)) { 165 if (!path->Add(entry.d_name)) {
143 success = false; 166 success = false;
144 break; 167 break;
145 } 168 }
146 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 }
147 if (stat_success == -1) { 175 if (stat_success == -1) {
148 success = false; 176 success = false;
149 PostError(listing, path->data); 177 PostError(listing, path->data);
150 break; 178 break;
151 } 179 }
152 path->Reset(path_length); 180 path->Reset(path_length);
153 if (S_ISDIR(entry_info.st_mode)) { 181 if (S_ISDIR(entry_info.st_mode)) {
154 success = HandleDir(entry.d_name, 182 success = HandleDir(entry.d_name,
155 path, 183 path,
156 recursive, 184 recursive,
185 follow_links,
157 listing) && success; 186 listing) && success;
158 } else if (S_ISREG(entry_info.st_mode)) { 187 } else if (S_ISREG(entry_info.st_mode)) {
159 success = HandleFile(entry.d_name, 188 success = HandleFile(entry.d_name,
160 path, 189 path,
161 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;
162 } 196 }
163 ASSERT(!S_ISLNK(entry_info.st_mode));
164 break; 197 break;
165 } 198 }
166 default: 199 default:
167 break; 200 break;
168 } 201 }
169 path->Reset(path_length); 202 path->Reset(path_length);
170 } 203 }
171 204
172 if (status != 0) { 205 if (status != 0) {
173 errno = status; 206 errno = status;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 (closedir(dir_pointer) == -1) || 309 (closedir(dir_pointer) == -1) ||
277 (remove(path->data) == -1)) { 310 (remove(path->data) == -1)) {
278 return false; 311 return false;
279 } 312 }
280 return success; 313 return success;
281 } 314 }
282 315
283 316
284 bool Directory::List(const char* dir_name, 317 bool Directory::List(const char* dir_name,
285 bool recursive, 318 bool recursive,
319 bool follow_links,
286 DirectoryListing *listing) { 320 DirectoryListing *listing) {
287 PathBuffer path; 321 PathBuffer path;
288 if (!path.Add(dir_name)) { 322 if (!path.Add(dir_name)) {
289 PostError(listing, dir_name); 323 PostError(listing, dir_name);
290 return false; 324 return false;
291 } 325 }
292 return ListRecursively(&path, recursive, listing); 326 return ListRecursively(&path, recursive, follow_links, listing);
293 } 327 }
294 328
295 329
296 Directory::ExistsResult Directory::Exists(const char* dir_name) { 330 Directory::ExistsResult Directory::Exists(const char* dir_name) {
297 struct stat entry_info; 331 struct stat entry_info;
298 int success = TEMP_FAILURE_RETRY(stat(dir_name, &entry_info)); 332 int success = TEMP_FAILURE_RETRY(stat(dir_name, &entry_info));
299 if (success == 0) { 333 if (success == 0) {
300 if (S_ISDIR(entry_info.st_mode)) { 334 if (S_ISDIR(entry_info.st_mode)) {
301 return EXISTS; 335 return EXISTS;
302 } else { 336 } else {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 } 417 }
384 418
385 419
386 bool Directory::Rename(const char* path, const char* new_path) { 420 bool Directory::Rename(const char* path, const char* new_path) {
387 ExistsResult exists = Exists(path); 421 ExistsResult exists = Exists(path);
388 if (exists != EXISTS) return false; 422 if (exists != EXISTS) return false;
389 return (TEMP_FAILURE_RETRY(rename(path, new_path)) == 0); 423 return (TEMP_FAILURE_RETRY(rename(path, new_path)) == 0);
390 } 424 }
391 425
392 #endif // defined(TARGET_OS_MACOS) 426 #endif // defined(TARGET_OS_MACOS)
OLDNEW
« no previous file with comments | « runtime/bin/directory_linux.cc ('k') | runtime/bin/directory_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698