Index: runtime/bin/directory_linux.cc |
diff --git a/runtime/bin/directory_linux.cc b/runtime/bin/directory_linux.cc |
index ab007b45532f3b8582a523347f98be08703dac26..641c0cf6d433891b059f3e830ce76b142c5e10c0 100644 |
--- a/runtime/bin/directory_linux.cc |
+++ b/runtime/bin/directory_linux.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); |
+ } |
} |