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

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

Issue 8243005: Directory: implement recursive directory listing on Linux and Mac. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Remove sizeof Created 9 years, 2 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 | « no previous file | runtime/bin/directory_macos.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 <libgen.h> 6 #include <libgen.h>
7 #include <string.h> 7 #include <string.h>
8 #include <sys/param.h> 8 #include <sys/param.h>
9 #include <sys/stat.h> 9 #include <sys/stat.h>
10 #include <sys/types.h> 10 #include <sys/types.h>
11 #include <unistd.h> 11 #include <unistd.h>
12 12
13 #include "bin/dartutils.h" 13 #include "bin/dartutils.h"
14 #include "bin/directory.h" 14 #include "bin/directory.h"
15 #include "bin/file.h" 15 #include "bin/file.h"
16 16
17 // Forward declaration.
18 static bool ListRecursively(const char* dir_name,
19 bool recursive,
20 Dart_Port dir_port,
21 Dart_Port file_port,
22 Dart_Port done_port,
23 Dart_Port error_port);
24
17 25
18 static void ComputeFullPath(const char* dir_name, 26 static void ComputeFullPath(const char* dir_name,
19 char* path, 27 char* path,
20 int* path_length) { 28 int* path_length) {
21 size_t written = 0; 29 size_t written = 0;
22 30
23 if (!File::IsAbsolutePath(dir_name)) { 31 if (!File::IsAbsolutePath(dir_name)) {
24 ASSERT(getcwd(path, PATH_MAX) != NULL); 32 ASSERT(getcwd(path, PATH_MAX) != NULL);
25 *path_length = strlen(path); 33 *path_length = strlen(path);
26 written = snprintf(path + *path_length, 34 written = snprintf(path + *path_length,
(...skipping 10 matching lines...) Expand all
37 char* dir = dirname(dir_name_copy); 45 char* dir = dirname(dir_name_copy);
38 if (strcmp(dir, ".") != 0) { 46 if (strcmp(dir, ".") != 0) {
39 written = snprintf(path + *path_length, 47 written = snprintf(path + *path_length,
40 PATH_MAX - *path_length, 48 PATH_MAX - *path_length,
41 "%s%s", 49 "%s%s",
42 dir, 50 dir,
43 File::PathSeparator()); 51 File::PathSeparator());
44 ASSERT(written == (strlen(dir) + strlen(File::PathSeparator()))); 52 ASSERT(written == (strlen(dir) + strlen(File::PathSeparator())));
45 *path_length += written; 53 *path_length += written;
46 } 54 }
47 char* base = basename(dir_name_copy); 55 char* base_name_copy = strdup(dir_name);
56 char* base = basename(base_name_copy);
48 if (strcmp(base, ".") != 0) { 57 if (strcmp(base, ".") != 0) {
49 written = snprintf(path + *path_length, 58 written = snprintf(path + *path_length,
50 PATH_MAX - *path_length, 59 PATH_MAX - *path_length,
51 "%s%s", 60 "%s%s",
52 base, 61 base,
53 File::PathSeparator()); 62 File::PathSeparator());
54 ASSERT(written == (strlen(base) + strlen(File::PathSeparator()))); 63 ASSERT(written == (strlen(base) + strlen(File::PathSeparator())));
55 *path_length += written; 64 *path_length += written;
56 } 65 }
66
57 free(dir_name_copy); 67 free(dir_name_copy);
68 free(base_name_copy);
58 } 69 }
59 70
60 71
61 static void HandleDir(char* dir_name, 72 static bool HandleDir(char* dir_name,
62 char* path, 73 char* path,
63 int path_length, 74 int path_length,
64 Dart_Port dir_port) { 75 bool recursive,
65 if (dir_port != 0 && 76 Dart_Port dir_port,
66 strcmp(dir_name, ".") != 0 && 77 Dart_Port file_port,
78 Dart_Port done_port,
79 Dart_Port error_port) {
80 if (strcmp(dir_name, ".") != 0 &&
67 strcmp(dir_name, "..") != 0) { 81 strcmp(dir_name, "..") != 0) {
68 size_t written = snprintf(path + path_length, 82 size_t written = snprintf(path + path_length,
69 PATH_MAX - path_length, 83 PATH_MAX - path_length,
70 "%s", 84 "%s",
71 dir_name); 85 dir_name);
72 ASSERT(written == strlen(dir_name)); 86 ASSERT(written == strlen(dir_name));
73 Dart_Handle name = Dart_NewString(path); 87 if (dir_port != 0) {
74 Dart_Post(dir_port, name); 88 Dart_Handle name = Dart_NewString(path);
89 Dart_Post(dir_port, name);
90 }
91 if (recursive) {
92 return ListRecursively(path,
93 recursive,
94 dir_port,
95 file_port,
96 done_port,
97 error_port);
98 }
75 } 99 }
100 return true;
76 } 101 }
77 102
78 103
79 static void HandleFile(char* file_name, 104 static void HandleFile(char* file_name,
80 char* path, 105 char* path,
81 int path_length, 106 int path_length,
82 Dart_Port file_port) { 107 Dart_Port file_port) {
83 if (file_port != 0) { 108 if (file_port != 0) {
84 size_t written = snprintf(path + path_length, 109 size_t written = snprintf(path + path_length,
85 PATH_MAX - path_length, 110 PATH_MAX - path_length,
86 "%s", 111 "%s",
87 file_name); 112 file_name);
88 ASSERT(written == strlen(file_name)); 113 ASSERT(written == strlen(file_name));
89 Dart_Handle name = Dart_NewString(path); 114 Dart_Handle name = Dart_NewString(path);
90 Dart_Post(file_port, name); 115 Dart_Post(file_port, name);
91 } 116 }
92 } 117 }
93 118
94 119
95 void Directory::List(const char* dir_name, 120 static bool ListRecursively(const char* dir_name,
96 bool recursive, 121 bool recursive,
97 Dart_Port dir_port, 122 Dart_Port dir_port,
98 Dart_Port file_port, 123 Dart_Port file_port,
99 Dart_Port done_port, 124 Dart_Port done_port,
100 Dart_Port dir_error_port) { 125 Dart_Port error_port) {
101 DIR* dir_pointer = opendir(dir_name); 126 DIR* dir_pointer = opendir(dir_name);
102 if (dir_pointer == NULL) { 127 if (dir_pointer == NULL) {
103 // TODO(ager): post something on the error port. 128 // TODO(ager): post something on the error port.
104 Dart_Handle value = Dart_NewBoolean(false); 129 return false;
105 Dart_Post(done_port, value);
106 return;
107 } 130 }
108 131
109 // Compute full path for the directory currently being listed. 132 // Compute full path for the directory currently being listed.
110 char path[PATH_MAX]; 133 char *path = static_cast<char*>(malloc(PATH_MAX));
134 ASSERT(path != NULL);
111 int path_length = 0; 135 int path_length = 0;
112 ComputeFullPath(dir_name, path, &path_length); 136 ComputeFullPath(dir_name, path, &path_length);
113 137
114 // Iterated the directory and post the directories and files to the 138 // Iterated the directory and post the directories and files to the
115 // ports. 139 // ports.
116 //
117 // TODO(ager): Handle recursion and errors caused by recursion.
118 int success = 0; 140 int success = 0;
119 bool lstat_error = false; 141 bool completed = true;
120 dirent entry; 142 dirent entry;
121 dirent* result; 143 dirent* result;
122 while ((success = readdir_r(dir_pointer, &entry, &result)) == 0 && 144 while ((success = readdir_r(dir_pointer, &entry, &result)) == 0 &&
123 result != NULL) { 145 result != NULL) {
124 switch (entry.d_type) { 146 switch (entry.d_type) {
125 case DT_DIR: 147 case DT_DIR:
126 HandleDir(entry.d_name, path, path_length, dir_port); 148 completed = completed && HandleDir(entry.d_name,
149 path,
150 path_length,
151 recursive,
152 dir_port,
153 file_port,
154 done_port,
155 error_port);
127 break; 156 break;
128 case DT_REG: 157 case DT_REG:
129 HandleFile(entry.d_name, path, path_length, file_port); 158 HandleFile(entry.d_name, path, path_length, file_port);
130 break; 159 break;
131 case DT_UNKNOWN: { 160 case DT_UNKNOWN: {
132 // On some file systems the entry type is not determined by 161 // On some file systems the entry type is not determined by
133 // readdir_r. For those we use lstat to determine the entry 162 // readdir_r. For those we use lstat to determine the entry
134 // type. 163 // type.
135 struct stat entry_info; 164 struct stat entry_info;
136 size_t written = snprintf(path + path_length, 165 size_t written = snprintf(path + path_length,
137 PATH_MAX - path_length, 166 PATH_MAX - path_length,
138 "%s", 167 "%s",
139 entry.d_name); 168 entry.d_name);
140 ASSERT(written == strlen(entry.d_name)); 169 ASSERT(written == strlen(entry.d_name));
141 int lstat_success = lstat(path, &entry_info); 170 int lstat_success = lstat(path, &entry_info);
142 if (lstat_success != 0) { 171 if (lstat_success != 0) {
143 lstat_error = true; 172 completed = false;
144 break; 173 break;
145 } 174 }
146 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) { 175 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) {
147 HandleDir(entry.d_name, path, path_length, dir_port); 176 HandleDir(entry.d_name,
177 path,
178 path_length,
179 recursive,
180 dir_port,
181 file_port,
182 done_port,
183 error_port);
148 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) { 184 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) {
149 HandleFile(entry.d_name, path, path_length, file_port); 185 HandleFile(entry.d_name, path, path_length, file_port);
150 } 186 }
151 break; 187 break;
152 } 188 }
153 default: 189 default:
154 break; 190 break;
155 } 191 }
156 } 192 }
193 completed = completed && (success == 0);
194
195 // TODO(ager): Post on error port if closing fails.
196 closedir(dir_pointer);
197 free(path);
198
199 return completed;
200 }
201
202
203 void Directory::List(const char* dir_name,
204 bool recursive,
205 Dart_Port dir_port,
206 Dart_Port file_port,
207 Dart_Port done_port,
208 Dart_Port error_port) {
209 bool completed = ListRecursively(dir_name,
210 recursive,
211 dir_port,
212 file_port,
213 done_port,
214 error_port);
157 if (done_port != 0) { 215 if (done_port != 0) {
158 if (success != 0 || lstat_error) { 216 Dart_Handle value = Dart_NewBoolean(completed);
159 Dart_Handle value = Dart_NewBoolean(false); 217 Dart_Post(done_port, value);
160 Dart_Post(done_port, value);
161 } else {
162 Dart_Handle value = Dart_NewBoolean(true);
163 Dart_Post(done_port, value);
164 }
165 } 218 }
166
167 // TODO(ager): Post on error port.
168 closedir(dir_pointer);
169 } 219 }
OLDNEW
« no previous file with comments | « no previous file | runtime/bin/directory_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698