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

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

Issue 8499018: Post on the error handler in the Directory API when errors are encountered. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix Windows build Created 9 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
« 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 <dirent.h> 5 #include <dirent.h>
6 #include <errno.h> 6 #include <errno.h>
7 #include <libgen.h> 7 #include <libgen.h>
8 #include <string.h> 8 #include <string.h>
9 #include <sys/param.h> 9 #include <sys/param.h>
10 #include <sys/stat.h> 10 #include <sys/stat.h>
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 PATH_MAX - path_length, 80 PATH_MAX - path_length,
81 "%s", 81 "%s",
82 file_name); 82 file_name);
83 ASSERT(written == strlen(file_name)); 83 ASSERT(written == strlen(file_name));
84 Dart_Handle name = Dart_NewString(path); 84 Dart_Handle name = Dart_NewString(path);
85 Dart_Post(file_port, name); 85 Dart_Post(file_port, name);
86 } 86 }
87 } 87 }
88 88
89 89
90 static void PostError(Dart_Port error_port,
91 const char* prefix,
92 const char* suffix,
93 int error_code) {
94 if (error_port != 0) {
95 // Extract the errno string.
96 static int kBufferSize = 1024;
97 char* error_buffer = static_cast<char*>(malloc(kBufferSize));
98 error_buffer[0] = '\0';
99 char* error_str = strerror_r(error_code, error_buffer, kBufferSize);
100 // Compose the error message from the parts.
101 int error_message_size =
102 strlen(prefix) + strlen(suffix) + strlen(error_str) + 3;
103 char* message = static_cast<char*>(malloc(error_message_size + 1));
104 int written = snprintf(message,
105 error_message_size + 1,
106 "%s%s (%s)",
107 prefix,
108 suffix,
109 error_str);
110 ASSERT(written == error_message_size);
111 free(error_buffer);
112 Dart_Post(error_port, Dart_NewString(message));
113 free(message);
114 }
115 }
116
117
90 static bool ListRecursively(const char* dir_name, 118 static bool ListRecursively(const char* dir_name,
91 bool recursive, 119 bool recursive,
92 Dart_Port dir_port, 120 Dart_Port dir_port,
93 Dart_Port file_port, 121 Dart_Port file_port,
94 Dart_Port done_port, 122 Dart_Port done_port,
95 Dart_Port error_port) { 123 Dart_Port error_port) {
96 DIR* dir_pointer = opendir(dir_name); 124 DIR* dir_pointer = opendir(dir_name);
97 if (dir_pointer == NULL) { 125 if (dir_pointer == NULL) {
98 // TODO(ager): post something on the error port. 126 PostError(error_port, "Directory listing failed for: ", dir_name, errno);
99 return false; 127 return false;
100 } 128 }
101 129
102 // Compute full path for the directory currently being listed. 130 // Compute full path for the directory currently being listed.
103 char *path = static_cast<char*>(malloc(PATH_MAX)); 131 char *path = static_cast<char*>(malloc(PATH_MAX));
104 ASSERT(path != NULL); 132 ASSERT(path != NULL);
105 int path_length = 0; 133 int path_length = 0;
106 ComputeFullPath(dir_name, path, &path_length); 134 ComputeFullPath(dir_name, path, &path_length);
107 135
108 // Iterated the directory and post the directories and files to the 136 // Iterated the directory and post the directories and files to the
109 // ports. 137 // ports.
110 int success = 0; 138 int success = 0;
111 bool completed = true; 139 bool listing_error = false;
112 dirent entry; 140 dirent entry;
113 dirent* result; 141 dirent* result;
114 while ((success = readdir_r(dir_pointer, &entry, &result)) == 0 && 142 while ((success = readdir_r(dir_pointer, &entry, &result)) == 0 &&
115 result != NULL) { 143 result != NULL &&
144 !listing_error) {
116 switch (entry.d_type) { 145 switch (entry.d_type) {
117 case DT_DIR: 146 case DT_DIR:
118 completed = completed && HandleDir(entry.d_name, 147 listing_error = listing_error || !HandleDir(entry.d_name,
119 path, 148 path,
120 path_length, 149 path_length,
121 recursive, 150 recursive,
122 dir_port, 151 dir_port,
123 file_port, 152 file_port,
124 done_port, 153 done_port,
125 error_port); 154 error_port);
126 break; 155 break;
127 case DT_REG: 156 case DT_REG:
128 HandleFile(entry.d_name, path, path_length, file_port); 157 HandleFile(entry.d_name, path, path_length, file_port);
129 break; 158 break;
130 case DT_UNKNOWN: { 159 case DT_UNKNOWN: {
131 // On some file systems the entry type is not determined by 160 // On some file systems the entry type is not determined by
132 // readdir_r. For those we use lstat to determine the entry 161 // readdir_r. For those we use lstat to determine the entry
133 // type. 162 // type.
134 struct stat entry_info; 163 struct stat entry_info;
135 size_t written = snprintf(path + path_length, 164 size_t written = snprintf(path + path_length,
136 PATH_MAX - path_length, 165 PATH_MAX - path_length,
137 "%s", 166 "%s",
138 entry.d_name); 167 entry.d_name);
139 ASSERT(written == strlen(entry.d_name)); 168 ASSERT(written == strlen(entry.d_name));
140 int lstat_success = lstat(path, &entry_info); 169 int lstat_success = lstat(path, &entry_info);
141 if (lstat_success != 0) { 170 if (lstat_success == -1) {
142 completed = false; 171 listing_error = true;
172 PostError(error_port, "Directory listing failed for: ", path, errno);
143 break; 173 break;
144 } 174 }
145 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) { 175 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) {
146 HandleDir(entry.d_name, 176 listing_error = listing_error || !HandleDir(entry.d_name,
147 path, 177 path,
148 path_length, 178 path_length,
149 recursive, 179 recursive,
150 dir_port, 180 dir_port,
151 file_port, 181 file_port,
152 done_port, 182 done_port,
153 error_port); 183 error_port);
154 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) { 184 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) {
155 HandleFile(entry.d_name, path, path_length, file_port); 185 HandleFile(entry.d_name, path, path_length, file_port);
156 } 186 }
157 break; 187 break;
158 } 188 }
159 default: 189 default:
160 break; 190 break;
161 } 191 }
162 } 192 }
163 completed = completed && (success == 0);
164 193
165 // TODO(ager): Post on error port if closing fails. 194 if (success != 0) {
166 closedir(dir_pointer); 195 listing_error = true;
196 PostError(error_port, "Directory listing failed", "", success);
197 }
198
199 if (closedir(dir_pointer) == -1) {
200 PostError(error_port, "Failed to close directory", "", errno);
201 }
167 free(path); 202 free(path);
168 203
169 return completed; 204 return !listing_error;
170 } 205 }
171 206
172 207
173 void Directory::List(const char* dir_name, 208 void Directory::List(const char* dir_name,
174 bool recursive, 209 bool recursive,
175 Dart_Port dir_port, 210 Dart_Port dir_port,
176 Dart_Port file_port, 211 Dart_Port file_port,
177 Dart_Port done_port, 212 Dart_Port done_port,
178 Dart_Port error_port) { 213 Dart_Port error_port) {
179 bool completed = ListRecursively(dir_name, 214 bool completed = ListRecursively(dir_name,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 bool Directory::Create(const char* dir_name) { 256 bool Directory::Create(const char* dir_name) {
222 // Create the directory with the permissions specified by the 257 // Create the directory with the permissions specified by the
223 // process umask. 258 // process umask.
224 return (mkdir(dir_name, 0777) == 0); 259 return (mkdir(dir_name, 0777) == 0);
225 } 260 }
226 261
227 262
228 bool Directory::Delete(const char* dir_name) { 263 bool Directory::Delete(const char* dir_name) {
229 return (rmdir(dir_name) == 0); 264 return (rmdir(dir_name) == 0);
230 } 265 }
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