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

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

Issue 8511001: Reapply directory error handling change. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Cut down on includes in posix version. 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 "bin/directory.h"
6
5 #include <dirent.h> 7 #include <dirent.h>
6 #include <errno.h> 8 #include <errno.h>
7 #include <libgen.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>
11 #include <sys/types.h>
12 #include <unistd.h> 11 #include <unistd.h>
13 12
14 #include "bin/dartutils.h"
15 #include "bin/directory.h"
16 #include "bin/file.h" 13 #include "bin/file.h"
14 #include "bin/platform.h"
17 15
18 // Forward declaration. 16 // Forward declaration.
19 static bool ListRecursively(const char* dir_name, 17 static bool ListRecursively(const char* dir_name,
20 bool recursive, 18 bool recursive,
21 Dart_Port dir_port, 19 Dart_Port dir_port,
22 Dart_Port file_port, 20 Dart_Port file_port,
23 Dart_Port done_port, 21 Dart_Port done_port,
24 Dart_Port error_port); 22 Dart_Port error_port);
25 23
26 24
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 PATH_MAX - path_length, 78 PATH_MAX - path_length,
81 "%s", 79 "%s",
82 file_name); 80 file_name);
83 ASSERT(written == strlen(file_name)); 81 ASSERT(written == strlen(file_name));
84 Dart_Handle name = Dart_NewString(path); 82 Dart_Handle name = Dart_NewString(path);
85 Dart_Post(file_port, name); 83 Dart_Post(file_port, name);
86 } 84 }
87 } 85 }
88 86
89 87
88 static void PostError(Dart_Port error_port,
89 const char* prefix,
90 const char* suffix,
91 int error_code) {
92 if (error_port != 0) {
93 char* error_str = Platform::StrError(error_code);
94 int error_message_size =
95 strlen(prefix) + strlen(suffix) + strlen(error_str) + 3;
96 char* message = static_cast<char*>(malloc(error_message_size + 1));
97 int written = snprintf(message,
98 error_message_size + 1,
99 "%s%s (%s)",
100 prefix,
101 suffix,
102 error_str);
103 ASSERT(written == error_message_size);
104 free(error_str);
105 Dart_Post(error_port, Dart_NewString(message));
106 free(message);
107 }
108 }
109
110
90 static bool ListRecursively(const char* dir_name, 111 static bool ListRecursively(const char* dir_name,
91 bool recursive, 112 bool recursive,
92 Dart_Port dir_port, 113 Dart_Port dir_port,
93 Dart_Port file_port, 114 Dart_Port file_port,
94 Dart_Port done_port, 115 Dart_Port done_port,
95 Dart_Port error_port) { 116 Dart_Port error_port) {
96 DIR* dir_pointer = opendir(dir_name); 117 DIR* dir_pointer = opendir(dir_name);
97 if (dir_pointer == NULL) { 118 if (dir_pointer == NULL) {
98 // TODO(ager): post something on the error port. 119 PostError(error_port, "Directory listing failed for: ", dir_name, errno);
99 return false; 120 return false;
100 } 121 }
101 122
102 // Compute full path for the directory currently being listed. 123 // Compute full path for the directory currently being listed.
103 char *path = static_cast<char*>(malloc(PATH_MAX)); 124 char *path = static_cast<char*>(malloc(PATH_MAX));
104 ASSERT(path != NULL); 125 ASSERT(path != NULL);
105 int path_length = 0; 126 int path_length = 0;
106 ComputeFullPath(dir_name, path, &path_length); 127 ComputeFullPath(dir_name, path, &path_length);
107 128
108 // Iterated the directory and post the directories and files to the 129 // Iterated the directory and post the directories and files to the
109 // ports. 130 // ports.
110 int success = 0; 131 int success = 0;
111 bool completed = true; 132 bool listing_error = false;
112 dirent entry; 133 dirent entry;
113 dirent* result; 134 dirent* result;
114 while ((success = readdir_r(dir_pointer, &entry, &result)) == 0 && 135 while ((success = readdir_r(dir_pointer, &entry, &result)) == 0 &&
115 result != NULL) { 136 result != NULL &&
137 !listing_error) {
116 switch (entry.d_type) { 138 switch (entry.d_type) {
117 case DT_DIR: 139 case DT_DIR:
118 completed = completed && HandleDir(entry.d_name, 140 listing_error = listing_error || !HandleDir(entry.d_name,
119 path, 141 path,
120 path_length, 142 path_length,
121 recursive, 143 recursive,
122 dir_port, 144 dir_port,
123 file_port, 145 file_port,
124 done_port, 146 done_port,
125 error_port); 147 error_port);
126 break; 148 break;
127 case DT_REG: 149 case DT_REG:
128 HandleFile(entry.d_name, path, path_length, file_port); 150 HandleFile(entry.d_name, path, path_length, file_port);
129 break; 151 break;
130 case DT_UNKNOWN: { 152 case DT_UNKNOWN: {
131 // On some file systems the entry type is not determined by 153 // On some file systems the entry type is not determined by
132 // readdir_r. For those we use lstat to determine the entry 154 // readdir_r. For those we use lstat to determine the entry
133 // type. 155 // type.
134 struct stat entry_info; 156 struct stat entry_info;
135 size_t written = snprintf(path + path_length, 157 size_t written = snprintf(path + path_length,
136 PATH_MAX - path_length, 158 PATH_MAX - path_length,
137 "%s", 159 "%s",
138 entry.d_name); 160 entry.d_name);
139 ASSERT(written == strlen(entry.d_name)); 161 ASSERT(written == strlen(entry.d_name));
140 int lstat_success = lstat(path, &entry_info); 162 int lstat_success = lstat(path, &entry_info);
141 if (lstat_success != 0) { 163 if (lstat_success == -1) {
142 completed = false; 164 listing_error = true;
165 PostError(error_port, "Directory listing failed for: ", path, errno);
143 break; 166 break;
144 } 167 }
145 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) { 168 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) {
146 HandleDir(entry.d_name, 169 listing_error = listing_error || !HandleDir(entry.d_name,
147 path, 170 path,
148 path_length, 171 path_length,
149 recursive, 172 recursive,
150 dir_port, 173 dir_port,
151 file_port, 174 file_port,
152 done_port, 175 done_port,
153 error_port); 176 error_port);
154 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) { 177 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) {
155 HandleFile(entry.d_name, path, path_length, file_port); 178 HandleFile(entry.d_name, path, path_length, file_port);
156 } 179 }
157 break; 180 break;
158 } 181 }
159 default: 182 default:
160 break; 183 break;
161 } 184 }
162 } 185 }
163 completed = completed && (success == 0);
164 186
165 // TODO(ager): Post on error port if closing fails. 187 if (success != 0) {
166 closedir(dir_pointer); 188 listing_error = true;
189 PostError(error_port, "Directory listing failed", "", success);
190 }
191
192 if (closedir(dir_pointer) == -1) {
193 PostError(error_port, "Failed to close directory", "", errno);
194 }
167 free(path); 195 free(path);
168 196
169 return completed; 197 return !listing_error;
170 } 198 }
171 199
172 200
173 void Directory::List(const char* dir_name, 201 void Directory::List(const char* dir_name,
174 bool recursive, 202 bool recursive,
175 Dart_Port dir_port, 203 Dart_Port dir_port,
176 Dart_Port file_port, 204 Dart_Port file_port,
177 Dart_Port done_port, 205 Dart_Port done_port,
178 Dart_Port error_port) { 206 Dart_Port error_port) {
179 bool completed = ListRecursively(dir_name, 207 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) { 249 bool Directory::Create(const char* dir_name) {
222 // Create the directory with the permissions specified by the 250 // Create the directory with the permissions specified by the
223 // process umask. 251 // process umask.
224 return (mkdir(dir_name, 0777) == 0); 252 return (mkdir(dir_name, 0777) == 0);
225 } 253 }
226 254
227 255
228 bool Directory::Delete(const char* dir_name) { 256 bool Directory::Delete(const char* dir_name) {
229 return (rmdir(dir_name) == 0); 257 return (rmdir(dir_name) == 0);
230 } 258 }
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