| Index: runtime/bin/directory_macos.cc
|
| diff --git a/runtime/bin/directory_macos.cc b/runtime/bin/directory_macos.cc
|
| index ab007b45532f3b8582a523347f98be08703dac26..641c0cf6d433891b059f3e830ce76b142c5e10c0 100644
|
| --- a/runtime/bin/directory_macos.cc
|
| +++ b/runtime/bin/directory_macos.cc
|
| @@ -14,6 +14,14 @@
|
| #include "bin/directory.h"
|
| #include "bin/file.h"
|
|
|
| +// Forward declaration.
|
| +static bool ListRecursively(const char* dir_name,
|
| + bool recursive,
|
| + Dart_Port dir_port,
|
| + Dart_Port file_port,
|
| + Dart_Port done_port,
|
| + Dart_Port error_port);
|
| +
|
|
|
| static void ComputeFullPath(const char* dir_name,
|
| char* path,
|
| @@ -44,7 +52,8 @@ static void ComputeFullPath(const char* dir_name,
|
| ASSERT(written == (strlen(dir) + strlen(File::PathSeparator())));
|
| *path_length += written;
|
| }
|
| - char* base = basename(dir_name_copy);
|
| + char* base_name_copy = strdup(dir_name);
|
| + char* base = basename(base_name_copy);
|
| if (strcmp(base, ".") != 0) {
|
| written = snprintf(path + *path_length,
|
| PATH_MAX - *path_length,
|
| @@ -54,25 +63,41 @@ static void ComputeFullPath(const char* dir_name,
|
| ASSERT(written == (strlen(base) + strlen(File::PathSeparator())));
|
| *path_length += written;
|
| }
|
| +
|
| free(dir_name_copy);
|
| + free(base_name_copy);
|
| }
|
|
|
|
|
| -static void HandleDir(char* dir_name,
|
| +static bool HandleDir(char* dir_name,
|
| char* path,
|
| int path_length,
|
| - Dart_Port dir_port) {
|
| - if (dir_port != 0 &&
|
| - strcmp(dir_name, ".") != 0 &&
|
| + bool recursive,
|
| + Dart_Port dir_port,
|
| + Dart_Port file_port,
|
| + Dart_Port done_port,
|
| + Dart_Port error_port) {
|
| + if (strcmp(dir_name, ".") != 0 &&
|
| strcmp(dir_name, "..") != 0) {
|
| size_t written = snprintf(path + path_length,
|
| PATH_MAX - path_length,
|
| "%s",
|
| dir_name);
|
| ASSERT(written == strlen(dir_name));
|
| - Dart_Handle name = Dart_NewString(path);
|
| - Dart_Post(dir_port, name);
|
| + if (dir_port != 0) {
|
| + Dart_Handle name = Dart_NewString(path);
|
| + Dart_Post(dir_port, name);
|
| + }
|
| + if (recursive) {
|
| + return ListRecursively(path,
|
| + recursive,
|
| + dir_port,
|
| + file_port,
|
| + done_port,
|
| + error_port);
|
| + }
|
| }
|
| + return true;
|
| }
|
|
|
|
|
| @@ -92,38 +117,42 @@ static void HandleFile(char* file_name,
|
| }
|
|
|
|
|
| -void Directory::List(const char* dir_name,
|
| - bool recursive,
|
| - Dart_Port dir_port,
|
| - Dart_Port file_port,
|
| - Dart_Port done_port,
|
| - Dart_Port dir_error_port) {
|
| +static bool ListRecursively(const char* dir_name,
|
| + bool recursive,
|
| + Dart_Port dir_port,
|
| + Dart_Port file_port,
|
| + Dart_Port done_port,
|
| + Dart_Port error_port) {
|
| DIR* dir_pointer = opendir(dir_name);
|
| if (dir_pointer == NULL) {
|
| // TODO(ager): post something on the error port.
|
| - Dart_Handle value = Dart_NewBoolean(false);
|
| - Dart_Post(done_port, value);
|
| - return;
|
| + return false;
|
| }
|
|
|
| // Compute full path for the directory currently being listed.
|
| - char path[PATH_MAX];
|
| + char *path = static_cast<char*>(malloc(PATH_MAX));
|
| + ASSERT(path != NULL);
|
| int path_length = 0;
|
| ComputeFullPath(dir_name, path, &path_length);
|
|
|
| // Iterated the directory and post the directories and files to the
|
| // ports.
|
| - //
|
| - // TODO(ager): Handle recursion and errors caused by recursion.
|
| int success = 0;
|
| - bool lstat_error = false;
|
| + bool completed = true;
|
| dirent entry;
|
| dirent* result;
|
| while ((success = readdir_r(dir_pointer, &entry, &result)) == 0 &&
|
| result != NULL) {
|
| switch (entry.d_type) {
|
| case DT_DIR:
|
| - HandleDir(entry.d_name, path, path_length, dir_port);
|
| + completed = completed && HandleDir(entry.d_name,
|
| + path,
|
| + path_length,
|
| + recursive,
|
| + dir_port,
|
| + file_port,
|
| + done_port,
|
| + error_port);
|
| break;
|
| case DT_REG:
|
| HandleFile(entry.d_name, path, path_length, file_port);
|
| @@ -140,11 +169,18 @@ void Directory::List(const char* dir_name,
|
| ASSERT(written == strlen(entry.d_name));
|
| int lstat_success = lstat(path, &entry_info);
|
| if (lstat_success != 0) {
|
| - lstat_error = true;
|
| + completed = false;
|
| break;
|
| }
|
| if ((entry_info.st_mode & S_IFMT) == S_IFDIR) {
|
| - HandleDir(entry.d_name, path, path_length, dir_port);
|
| + HandleDir(entry.d_name,
|
| + path,
|
| + path_length,
|
| + recursive,
|
| + dir_port,
|
| + file_port,
|
| + done_port,
|
| + error_port);
|
| } else if ((entry_info.st_mode & S_IFMT) == S_IFREG) {
|
| HandleFile(entry.d_name, path, path_length, file_port);
|
| }
|
| @@ -154,16 +190,30 @@ void Directory::List(const char* dir_name,
|
| break;
|
| }
|
| }
|
| - if (done_port != 0) {
|
| - if (success != 0 || lstat_error) {
|
| - Dart_Handle value = Dart_NewBoolean(false);
|
| - Dart_Post(done_port, value);
|
| - } else {
|
| - Dart_Handle value = Dart_NewBoolean(true);
|
| - Dart_Post(done_port, value);
|
| - }
|
| - }
|
| + completed = completed && (success == 0);
|
|
|
| - // TODO(ager): Post on error port.
|
| + // TODO(ager): Post on error port if closing fails.
|
| closedir(dir_pointer);
|
| + free(path);
|
| +
|
| + return completed;
|
| +}
|
| +
|
| +
|
| +void Directory::List(const char* dir_name,
|
| + bool recursive,
|
| + Dart_Port dir_port,
|
| + Dart_Port file_port,
|
| + Dart_Port done_port,
|
| + Dart_Port error_port) {
|
| + bool completed = ListRecursively(dir_name,
|
| + recursive,
|
| + dir_port,
|
| + file_port,
|
| + done_port,
|
| + error_port);
|
| + if (done_port != 0) {
|
| + Dart_Handle value = Dart_NewBoolean(completed);
|
| + Dart_Post(done_port, value);
|
| + }
|
| }
|
|
|