OLD | NEW |
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 | 17 |
18 bool Directory::Open(const char* path, intptr_t* dir) { | |
19 DIR* dir_pointer = opendir(path); | |
20 if (dir_pointer == NULL) { | |
21 return false; | |
22 } | |
23 *dir = reinterpret_cast<intptr_t>(dir_pointer); | |
24 return true; | |
25 } | |
26 | |
27 | |
28 bool Directory::Close(intptr_t dir) { | |
29 DIR* dir_pointer = reinterpret_cast<DIR*>(dir); | |
30 int result = closedir(dir_pointer); | |
31 return result == 0; | |
32 } | |
33 | |
34 | |
35 static void ComputeFullPath(const char* dir_name, | 18 static void ComputeFullPath(const char* dir_name, |
36 char* path, | 19 char* path, |
37 int* path_length) { | 20 int* path_length) { |
38 size_t written = 0; | 21 size_t written = 0; |
39 | 22 |
40 if (!File::IsAbsolutePath(dir_name)) { | 23 if (!File::IsAbsolutePath(dir_name)) { |
41 ASSERT(getcwd(path, PATH_MAX) != NULL); | 24 ASSERT(getcwd(path, PATH_MAX) != NULL); |
42 *path_length = strlen(path); | 25 *path_length = strlen(path); |
43 written = snprintf(path + *path_length, | 26 written = snprintf(path + *path_length, |
44 PATH_MAX - *path_length, | 27 PATH_MAX - *path_length, |
(...skipping 26 matching lines...) Expand all Loading... |
71 ASSERT(written == (strlen(base) + strlen(File::PathSeparator()))); | 54 ASSERT(written == (strlen(base) + strlen(File::PathSeparator()))); |
72 *path_length += written; | 55 *path_length += written; |
73 } | 56 } |
74 free(dir_name_copy); | 57 free(dir_name_copy); |
75 } | 58 } |
76 | 59 |
77 | 60 |
78 static void HandleDir(char* dir_name, | 61 static void HandleDir(char* dir_name, |
79 char* path, | 62 char* path, |
80 int path_length, | 63 int path_length, |
81 Dart_Port dir_handler) { | 64 Dart_Port dir_port) { |
82 if (dir_handler != 0 && | 65 if (dir_port != 0 && |
83 strcmp(dir_name, ".") != 0 && | 66 strcmp(dir_name, ".") != 0 && |
84 strcmp(dir_name, "..") != 0) { | 67 strcmp(dir_name, "..") != 0) { |
85 size_t written = snprintf(path + path_length, | 68 size_t written = snprintf(path + path_length, |
86 PATH_MAX - path_length, | 69 PATH_MAX - path_length, |
87 "%s", | 70 "%s", |
88 dir_name); | 71 dir_name); |
89 ASSERT(written == strlen(dir_name)); | 72 ASSERT(written == strlen(dir_name)); |
90 Dart_Handle name = Dart_NewString(path); | 73 Dart_Handle name = Dart_NewString(path); |
91 Dart_Post(dir_handler, name); | 74 Dart_Post(dir_port, name); |
92 } | 75 } |
93 } | 76 } |
94 | 77 |
95 | 78 |
96 static void HandleFile(char* file_name, | 79 static void HandleFile(char* file_name, |
97 char* path, | 80 char* path, |
98 int path_length, | 81 int path_length, |
99 Dart_Port file_handler) { | 82 Dart_Port file_port) { |
100 if (file_handler != 0) { | 83 if (file_port != 0) { |
101 size_t written = snprintf(path + path_length, | 84 size_t written = snprintf(path + path_length, |
102 PATH_MAX - path_length, | 85 PATH_MAX - path_length, |
103 "%s", | 86 "%s", |
104 file_name); | 87 file_name); |
105 ASSERT(written == strlen(file_name)); | 88 ASSERT(written == strlen(file_name)); |
106 Dart_Handle name = Dart_NewString(path); | 89 Dart_Handle name = Dart_NewString(path); |
107 Dart_Post(file_handler, name); | 90 Dart_Post(file_port, name); |
108 } | 91 } |
109 } | 92 } |
110 | 93 |
111 | 94 |
112 void Directory::List(const char* dir_name, | 95 void Directory::List(const char* dir_name, |
113 intptr_t dir_handle, | |
114 bool recursive, | 96 bool recursive, |
115 Dart_Port dir_handler, | 97 Dart_Port dir_port, |
116 Dart_Port file_handler, | 98 Dart_Port file_port, |
117 Dart_Port done_handler, | 99 Dart_Port done_port, |
118 Dart_Port dir_error_handler) { | 100 Dart_Port dir_error_port) { |
| 101 DIR* dir_pointer = opendir(dir_name); |
| 102 if (dir_pointer == NULL) { |
| 103 // TODO(ager): post something on the error port. |
| 104 Dart_Handle value = Dart_NewBoolean(false); |
| 105 Dart_Post(done_port, value); |
| 106 return; |
| 107 } |
| 108 |
119 // Compute full path for the directory currently being listed. | 109 // Compute full path for the directory currently being listed. |
120 char path[PATH_MAX]; | 110 char path[PATH_MAX]; |
121 int path_length = 0; | 111 int path_length = 0; |
122 ComputeFullPath(dir_name, path, &path_length); | 112 ComputeFullPath(dir_name, path, &path_length); |
123 | 113 |
124 // Iterated the directory and post the directories and files to the | 114 // Iterated the directory and post the directories and files to the |
125 // handlers. | 115 // ports. |
126 // | 116 // |
127 // TODO(ager): Handle recursion and errors caused by recursion. | 117 // TODO(ager): Handle recursion and errors caused by recursion. |
128 DIR* dir_pointer = reinterpret_cast<DIR*>(dir_handle); | |
129 int success = 0; | 118 int success = 0; |
130 bool lstat_error = false; | 119 bool lstat_error = false; |
131 dirent entry; | 120 dirent entry; |
132 dirent* result; | 121 dirent* result; |
133 while ((success = readdir_r(dir_pointer, &entry, &result)) == 0 && | 122 while ((success = readdir_r(dir_pointer, &entry, &result)) == 0 && |
134 result != NULL) { | 123 result != NULL) { |
135 switch (entry.d_type) { | 124 switch (entry.d_type) { |
136 case DT_DIR: | 125 case DT_DIR: |
137 HandleDir(entry.d_name, path, path_length, dir_handler); | 126 HandleDir(entry.d_name, path, path_length, dir_port); |
138 break; | 127 break; |
139 case DT_REG: | 128 case DT_REG: |
140 HandleFile(entry.d_name, path, path_length, file_handler); | 129 HandleFile(entry.d_name, path, path_length, file_port); |
141 break; | 130 break; |
142 case DT_UNKNOWN: { | 131 case DT_UNKNOWN: { |
| 132 // On some file systems the entry type is not determined by |
| 133 // readdir_r. For those we use lstat to determine the entry |
| 134 // type. |
143 struct stat entry_info; | 135 struct stat entry_info; |
144 size_t written = snprintf(path + path_length, | 136 size_t written = snprintf(path + path_length, |
145 PATH_MAX - path_length, | 137 PATH_MAX - path_length, |
146 "%s", | 138 "%s", |
147 entry.d_name); | 139 entry.d_name); |
148 ASSERT(written == strlen(entry.d_name)); | 140 ASSERT(written == strlen(entry.d_name)); |
149 int lstat_success = lstat(path, &entry_info); | 141 int lstat_success = lstat(path, &entry_info); |
150 if (lstat_success != 0) { | 142 if (lstat_success != 0) { |
151 lstat_error = true; | 143 lstat_error = true; |
152 break; | 144 break; |
153 } | 145 } |
154 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) { | 146 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) { |
155 HandleDir(entry.d_name, path, path_length, dir_handler); | 147 HandleDir(entry.d_name, path, path_length, dir_port); |
156 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) { | 148 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) { |
157 HandleFile(entry.d_name, path, path_length, file_handler); | 149 HandleFile(entry.d_name, path, path_length, file_port); |
158 } | 150 } |
159 break; | 151 break; |
160 } | 152 } |
161 default: | 153 default: |
162 break; | 154 break; |
163 } | 155 } |
164 } | 156 } |
165 if (done_handler != 0) { | 157 if (done_port != 0) { |
166 if (success != 0 || lstat_error) { | 158 if (success != 0 || lstat_error) { |
167 Dart_Handle value = Dart_NewBoolean(false); | 159 Dart_Handle value = Dart_NewBoolean(false); |
168 Dart_Post(done_handler, value); | 160 Dart_Post(done_port, value); |
169 } else { | 161 } else { |
170 Dart_Handle value = Dart_NewBoolean(true); | 162 Dart_Handle value = Dart_NewBoolean(true); |
171 Dart_Post(done_handler, value); | 163 Dart_Post(done_port, value); |
172 } | 164 } |
173 } | 165 } |
| 166 |
| 167 // TODO(ager): Post on error port. |
| 168 closedir(dir_pointer); |
174 } | 169 } |
OLD | NEW |