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

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

Issue 9773018: Add error handling to directory (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments Created 8 years, 8 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_impl.dart ('k') | runtime/bin/directory_win.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 "bin/directory.h" 5 #include "bin/directory.h"
6 6
7 #include <dirent.h> 7 #include <dirent.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <sys/param.h> 9 #include <sys/param.h>
10 #include <sys/stat.h> 10 #include <sys/stat.h>
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 "%s", 86 "%s",
87 file_name); 87 file_name);
88 if (written != strlen(file_name)) { 88 if (written != strlen(file_name)) {
89 return false; 89 return false;
90 } 90 }
91 return listing->HandleFile(path); 91 return listing->HandleFile(path);
92 } 92 }
93 93
94 94
95 static void PostError(DirectoryListing *listing, 95 static void PostError(DirectoryListing *listing,
96 const char* prefix, 96 const char* dir_name) {
97 const char* suffix, 97 listing->HandleError(dir_name);
98 int error_code) {
99 // TODO(sgjesse): Pass flags to indicate whether error response is
100 // needed.
101 char* error_str = Platform::StrError(error_code);
102 int error_message_size =
103 strlen(prefix) + strlen(suffix) + strlen(error_str) + 3;
104 char* message = static_cast<char*>(malloc(error_message_size + 1));
105 int written = snprintf(message,
106 error_message_size + 1,
107 "%s%s (%s)",
108 prefix,
109 suffix,
110 error_str);
111 ASSERT(written == error_message_size);
112 free(error_str);
113 listing->HandleError(message);
114 free(message);
115 } 98 }
116 99
117 100
118 static bool ListRecursively(const char* dir_name, 101 static bool ListRecursively(const char* dir_name,
119 bool recursive, 102 bool recursive,
120 DirectoryListing *listing) { 103 DirectoryListing *listing) {
121 DIR* dir_pointer; 104 DIR* dir_pointer;
122 do { 105 do {
123 dir_pointer = opendir(dir_name); 106 dir_pointer = opendir(dir_name);
124 } while (dir_pointer == NULL && errno == EINTR); 107 } while (dir_pointer == NULL && errno == EINTR);
125 if (dir_pointer == NULL) { 108 if (dir_pointer == NULL) {
126 PostError(listing, "Directory listing failed for: ", dir_name, errno); 109 PostError(listing, dir_name);
127 return false; 110 return false;
128 } 111 }
129 112
130 // Compute full path for the directory currently being listed. The 113 // Compute full path for the directory currently being listed. The
131 // path buffer will be used to construct the current path in the 114 // path buffer will be used to construct the current path in the
132 // recursive traversal. path_length does not always equal 115 // recursive traversal. path_length does not always equal
133 // strlen(path) but indicates the current prefix of path that is the 116 // strlen(path) but indicates the current prefix of path that is the
134 // path of the current directory in the traversal. 117 // path of the current directory in the traversal.
135 char *path = static_cast<char*>(malloc(PATH_MAX)); 118 char *path = static_cast<char*>(malloc(PATH_MAX));
136 ASSERT(path != NULL); 119 ASSERT(path != NULL);
137 int path_length = 0; 120 int path_length = 0;
138 bool valid = ComputeFullPath(dir_name, path, &path_length); 121 bool valid = ComputeFullPath(dir_name, path, &path_length);
139 if (!valid) { 122 if (!valid) {
140 free(path); 123 free(path);
141 PostError(listing, "Directory listing failed for: ", dir_name, errno); 124 PostError(listing, dir_name);
142 return false; 125 return false;
143 } 126 }
144 127
145 // Iterated the directory and post the directories and files to the 128 // Iterated the directory and post the directories and files to the
146 // ports. 129 // ports.
147 int read = 0; 130 int read = 0;
148 bool success = true; 131 bool success = true;
149 dirent entry; 132 dirent entry;
150 dirent* result; 133 dirent* result;
151 while ((read = TEMP_FAILURE_RETRY(readdir_r(dir_pointer, 134 while ((read = TEMP_FAILURE_RETRY(readdir_r(dir_pointer,
(...skipping 24 matching lines...) Expand all
176 PATH_MAX - path_length, 159 PATH_MAX - path_length,
177 "%s", 160 "%s",
178 entry.d_name); 161 entry.d_name);
179 if (written != strlen(entry.d_name)) { 162 if (written != strlen(entry.d_name)) {
180 success = false; 163 success = false;
181 break; 164 break;
182 } 165 }
183 int lstat_success = TEMP_FAILURE_RETRY(lstat(path, &entry_info)); 166 int lstat_success = TEMP_FAILURE_RETRY(lstat(path, &entry_info));
184 if (lstat_success == -1) { 167 if (lstat_success == -1) {
185 success = false; 168 success = false;
186 PostError(listing, "Directory listing failed for: ", path, errno); 169 PostError(listing, path);
187 break; 170 break;
188 } 171 }
189 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) { 172 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) {
190 success = success && HandleDir(entry.d_name, 173 success = success && HandleDir(entry.d_name,
191 path, 174 path,
192 path_length, 175 path_length,
193 recursive, 176 recursive,
194 listing); 177 listing);
195 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) { 178 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) {
196 success = success && HandleFile(entry.d_name, 179 success = success && HandleFile(entry.d_name,
197 path, 180 path,
198 path_length, 181 path_length,
199 listing); 182 listing);
200 } 183 }
201 break; 184 break;
202 } 185 }
203 default: 186 default:
204 break; 187 break;
205 } 188 }
206 } 189 }
207 190
208 if (read != 0) { 191 if (read != 0) {
192 errno = read;
209 success = false; 193 success = false;
210 PostError(listing, "Directory listing failed", "", read); 194 PostError(listing, dir_name);
211 } 195 }
212 196
213 if (closedir(dir_pointer) == -1) { 197 if (closedir(dir_pointer) == -1) {
214 PostError(listing, "Failed to close directory", "", errno); 198 success = false;
199 PostError(listing, dir_name);
215 } 200 }
216 free(path); 201 free(path);
217 202
218 return success; 203 return success;
219 } 204 }
220 205
221 206
222 static bool DeleteFile(char* file_name, 207 static bool DeleteFile(char* file_name,
223 char* path, 208 char* path,
224 int path_length) { 209 int path_length) {
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 } 397 }
413 398
414 399
415 bool Directory::Delete(const char* dir_name, bool recursive) { 400 bool Directory::Delete(const char* dir_name, bool recursive) {
416 if (!recursive) { 401 if (!recursive) {
417 return (TEMP_FAILURE_RETRY(remove(dir_name)) == 0); 402 return (TEMP_FAILURE_RETRY(remove(dir_name)) == 0);
418 } else { 403 } else {
419 return DeleteRecursively(dir_name); 404 return DeleteRecursively(dir_name);
420 } 405 }
421 } 406 }
OLDNEW
« no previous file with comments | « runtime/bin/directory_impl.dart ('k') | runtime/bin/directory_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698