| 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: { |
| 143 // On some file systems the entry type is not determined by | 132 // On some file systems the entry type is not determined by |
| 144 // readdir_r. For those we use lstat to determine the entry | 133 // readdir_r. For those we use lstat to determine the entry |
| 145 // type. | 134 // type. |
| 146 struct stat entry_info; | 135 struct stat entry_info; |
| 147 size_t written = snprintf(path + path_length, | 136 size_t written = snprintf(path + path_length, |
| 148 PATH_MAX - path_length, | 137 PATH_MAX - path_length, |
| 149 "%s", | 138 "%s", |
| 150 entry.d_name); | 139 entry.d_name); |
| 151 ASSERT(written == strlen(entry.d_name)); | 140 ASSERT(written == strlen(entry.d_name)); |
| 152 int lstat_success = lstat(path, &entry_info); | 141 int lstat_success = lstat(path, &entry_info); |
| 153 if (lstat_success != 0) { | 142 if (lstat_success != 0) { |
| 154 lstat_error = true; | 143 lstat_error = true; |
| 155 break; | 144 break; |
| 156 } | 145 } |
| 157 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) { | 146 if ((entry_info.st_mode & S_IFMT) == S_IFDIR) { |
| 158 HandleDir(entry.d_name, path, path_length, dir_handler); | 147 HandleDir(entry.d_name, path, path_length, dir_port); |
| 159 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) { | 148 } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) { |
| 160 HandleFile(entry.d_name, path, path_length, file_handler); | 149 HandleFile(entry.d_name, path, path_length, file_port); |
| 161 } | 150 } |
| 162 break; | 151 break; |
| 163 } | 152 } |
| 164 default: | 153 default: |
| 165 break; | 154 break; |
| 166 } | 155 } |
| 167 } | 156 } |
| 168 if (done_handler != 0) { | 157 if (done_port != 0) { |
| 169 if (success != 0 || lstat_error) { | 158 if (success != 0 || lstat_error) { |
| 170 Dart_Handle value = Dart_NewBoolean(false); | 159 Dart_Handle value = Dart_NewBoolean(false); |
| 171 Dart_Post(done_handler, value); | 160 Dart_Post(done_port, value); |
| 172 } else { | 161 } else { |
| 173 Dart_Handle value = Dart_NewBoolean(true); | 162 Dart_Handle value = Dart_NewBoolean(true); |
| 174 Dart_Post(done_handler, value); | 163 Dart_Post(done_port, value); |
| 175 } | 164 } |
| 176 } | 165 } |
| 166 |
| 167 // TODO(ager): Post on error port. |
| 168 closedir(dir_pointer); |
| 177 } | 169 } |
| OLD | NEW |