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

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

Issue 8277033: Add exists, create and delete to directory implementation on Linux and Mac. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include <dirent.h>
6 #include <libgen.h>
7 #include <string.h>
8 #include <sys/param.h>
9 #include <sys/stat.h>
10 #include <sys/types.h>
11 #include <unistd.h>
12
13 #include "bin/dartutils.h"
14 #include "bin/directory.h"
15 #include "bin/file.h"
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
25
26 static void ComputeFullPath(const char* dir_name,
27 char* path,
28 int* path_length) {
29 size_t written = 0;
30
31 if (!File::IsAbsolutePath(dir_name)) {
32 ASSERT(getcwd(path, PATH_MAX) != NULL);
33 *path_length = strlen(path);
34 written = snprintf(path + *path_length,
35 PATH_MAX - *path_length,
36 "%s",
37 File::PathSeparator());
38 ASSERT(written == strlen(File::PathSeparator()));
39 *path_length += written;
40 }
41
42 // Use dirname and basename to canonicalize the provided directory
43 // name.
44 char* dir_name_copy = strdup(dir_name);
45 char* dir = dirname(dir_name_copy);
46 if (strcmp(dir, ".") != 0) {
47 written = snprintf(path + *path_length,
48 PATH_MAX - *path_length,
49 "%s%s",
50 dir,
51 File::PathSeparator());
52 ASSERT(written == (strlen(dir) + strlen(File::PathSeparator())));
53 *path_length += written;
54 }
55 char* base_name_copy = strdup(dir_name);
56 char* base = basename(base_name_copy);
57 if (strcmp(base, ".") != 0) {
58 written = snprintf(path + *path_length,
59 PATH_MAX - *path_length,
60 "%s%s",
61 base,
62 File::PathSeparator());
63 ASSERT(written == (strlen(base) + strlen(File::PathSeparator())));
64 *path_length += written;
65 }
66
67 free(dir_name_copy);
68 free(base_name_copy);
69 }
70
71
72 static bool HandleDir(char* dir_name,
73 char* path,
74 int path_length,
75 bool recursive,
76 Dart_Port dir_port,
77 Dart_Port file_port,
78 Dart_Port done_port,
79 Dart_Port error_port) {
80 if (strcmp(dir_name, ".") != 0 &&
81 strcmp(dir_name, "..") != 0) {
82 size_t written = snprintf(path + path_length,
83 PATH_MAX - path_length,
84 "%s",
85 dir_name);
86 ASSERT(written == strlen(dir_name));
87 if (dir_port != 0) {
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 }
99 }
100 return true;
101 }
102
103
104 static void HandleFile(char* file_name,
105 char* path,
106 int path_length,
107 Dart_Port file_port) {
108 if (file_port != 0) {
109 size_t written = snprintf(path + path_length,
110 PATH_MAX - path_length,
111 "%s",
112 file_name);
113 ASSERT(written == strlen(file_name));
114 Dart_Handle name = Dart_NewString(path);
115 Dart_Post(file_port, name);
116 }
117 }
118
119
120 static bool ListRecursively(const char* dir_name,
121 bool recursive,
122 Dart_Port dir_port,
123 Dart_Port file_port,
124 Dart_Port done_port,
125 Dart_Port error_port) {
126 DIR* dir_pointer = opendir(dir_name);
127 if (dir_pointer == NULL) {
128 // TODO(ager): post something on the error port.
129 return false;
130 }
131
132 // Compute full path for the directory currently being listed.
133 char *path = static_cast<char*>(malloc(PATH_MAX));
134 ASSERT(path != NULL);
135 int path_length = 0;
136 ComputeFullPath(dir_name, path, &path_length);
137
138 // Iterated the directory and post the directories and files to the
139 // ports.
140 int success = 0;
141 bool completed = true;
142 dirent entry;
143 dirent* result;
144 while ((success = readdir_r(dir_pointer, &entry, &result)) == 0 &&
145 result != NULL) {
146 switch (entry.d_type) {
147 case DT_DIR:
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);
156 break;
157 case DT_REG:
158 HandleFile(entry.d_name, path, path_length, file_port);
159 break;
160 case DT_UNKNOWN: {
161 // On some file systems the entry type is not determined by
162 // readdir_r. For those we use lstat to determine the entry
163 // type.
164 struct stat entry_info;
165 size_t written = snprintf(path + path_length,
166 PATH_MAX - path_length,
167 "%s",
168 entry.d_name);
169 ASSERT(written == strlen(entry.d_name));
170 int lstat_success = lstat(path, &entry_info);
171 if (lstat_success != 0) {
172 completed = false;
173 break;
174 }
175 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) {
176 HandleDir(entry.d_name,
177 path,
178 path_length,
179 recursive,
180 dir_port,
181 file_port,
182 done_port,
183 error_port);
184 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) {
185 HandleFile(entry.d_name, path, path_length, file_port);
186 }
187 break;
188 }
189 default:
190 break;
191 }
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);
215 if (done_port != 0) {
216 Dart_Handle value = Dart_NewBoolean(completed);
217 Dart_Post(done_port, value);
218 }
219 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698