| Index: runtime/bin/file_system_watcher_android.cc
|
| diff --git a/runtime/bin/file_system_watcher_android.cc b/runtime/bin/file_system_watcher_android.cc
|
| index 5971ed0ad8cd63cd537fc0d0262c34843d9c1c97..96fd325bd6f59ca8fb069bdcbf09fd9d33c52943 100644
|
| --- a/runtime/bin/file_system_watcher_android.cc
|
| +++ b/runtime/bin/file_system_watcher_android.cc
|
| @@ -21,42 +21,54 @@ bool FileSystemWatcher::IsSupported() {
|
| }
|
|
|
|
|
| -intptr_t FileSystemWatcher::WatchPath(const char* path,
|
| - int events,
|
| - bool recursive) {
|
| - int fd = TEMP_FAILURE_RETRY(inotify_init());
|
| - if (fd < 0 || !FDUtils::SetCloseOnExec(fd)) {
|
| +intptr_t FileSystemWatcher::Init() {
|
| + int id = TEMP_FAILURE_RETRY(inotify_init());
|
| + if (id < 0 || !FDUtils::SetCloseOnExec(id)) {
|
| return -1;
|
| }
|
| // Some systems dosn't support setting this as non-blocking. Since watching
|
| // internals are kept away from the user, we know it's possible to continue,
|
| // even if setting non-blocking fails.
|
| - FDUtils::SetNonBlocking(fd);
|
| + FDUtils::SetNonBlocking(id);
|
| + return id;
|
| +}
|
| +
|
| +
|
| +void FileSystemWatcher::Close(intptr_t id) {
|
| + USE(id);
|
| +}
|
| +
|
| +
|
| +intptr_t FileSystemWatcher::WatchPath(intptr_t id,
|
| + const char* path,
|
| + int events,
|
| + bool recursive) {
|
| int list_events = IN_DELETE_SELF | IN_MOVE_SELF;
|
| if (events & kCreate) list_events |= IN_CREATE;
|
| - if (events & kModifyContent) list_events |= IN_MODIFY | IN_ATTRIB;
|
| + if (events & kModifyContent) list_events |= IN_CLOSE_WRITE | IN_ATTRIB;
|
| if (events & kDelete) list_events |= IN_DELETE;
|
| if (events & kMove) list_events |= IN_MOVE;
|
| - int path_fd = TEMP_FAILURE_RETRY(inotify_add_watch(fd, path, list_events));
|
| - if (path_fd < 0) {
|
| - close(fd);
|
| + int path_id = TEMP_FAILURE_RETRY(inotify_add_watch(id, path, list_events));
|
| + if (path_id < 0) {
|
| return -1;
|
| }
|
| - return fd;
|
| + return path_id;
|
| }
|
|
|
|
|
| -void FileSystemWatcher::UnwatchPath(intptr_t id) {
|
| - // Nothing to do.
|
| +void FileSystemWatcher::UnwatchPath(intptr_t id, intptr_t path_id) {
|
| + VOID_TEMP_FAILURE_RETRY(inotify_rm_watch(id, path_id));
|
| }
|
|
|
|
|
| -intptr_t FileSystemWatcher::GetSocketId(intptr_t id) {
|
| +intptr_t FileSystemWatcher::GetSocketId(intptr_t id, intptr_t path_id) {
|
| + USE(path_id);
|
| return id;
|
| }
|
|
|
|
|
| -Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id) {
|
| +Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id, intptr_t path_id) {
|
| + USE(path_id);
|
| const intptr_t kEventSize = sizeof(struct inotify_event);
|
| const intptr_t kBufferSize = kEventSize + NAME_MAX + 1;
|
| uint8_t buffer[kBufferSize];
|
| @@ -64,33 +76,36 @@ Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id) {
|
| if (bytes < 0) {
|
| return DartUtils::NewDartOSError();
|
| }
|
| - const intptr_t kMaxCount = kBufferSize / kEventSize + 1;
|
| + const intptr_t kMaxCount = bytes / kEventSize;
|
| Dart_Handle events = Dart_NewList(kMaxCount);
|
| intptr_t offset = 0;
|
| intptr_t i = 0;
|
| while (offset < bytes) {
|
| struct inotify_event* e =
|
| reinterpret_cast<struct inotify_event*>(buffer + offset);
|
| - Dart_Handle event = Dart_NewList(4);
|
| - int mask = 0;
|
| - if (e->mask & IN_CLOSE_WRITE) mask |= kModifyContent;
|
| - if (e->mask & IN_ATTRIB) mask |= kModefyAttribute;
|
| - if (e->mask & IN_CREATE) mask |= kCreate;
|
| - if (e->mask & IN_MOVE) mask |= kMove;
|
| - if (e->mask & IN_DELETE) mask |= kDelete;
|
| - if (e->mask & (IN_DELETE_SELF | IN_MOVE_SELF)) mask |= kDeleteSelf;
|
| - if (e->mask & IN_ISDIR) mask |= kIsDir;
|
| - Dart_ListSetAt(event, 0, Dart_NewInteger(mask));
|
| - Dart_ListSetAt(event, 1, Dart_NewInteger(e->cookie));
|
| - if (e->len > 0) {
|
| - Dart_ListSetAt(event, 2, Dart_NewStringFromUTF8(
|
| - reinterpret_cast<uint8_t*>(e->name), strlen(e->name)));
|
| - } else {
|
| - Dart_ListSetAt(event, 2, Dart_Null());
|
| + if ((e->mask & IN_IGNORED) == 0) {;
|
| + Dart_Handle event = Dart_NewList(5);
|
| + int mask = 0;
|
| + if (e->mask & IN_CLOSE_WRITE) mask |= kModifyContent;
|
| + if (e->mask & IN_ATTRIB) mask |= kModefyAttribute;
|
| + if (e->mask & IN_CREATE) mask |= kCreate;
|
| + if (e->mask & IN_MOVE) mask |= kMove;
|
| + if (e->mask & IN_DELETE) mask |= kDelete;
|
| + if (e->mask & (IN_DELETE_SELF | IN_MOVE_SELF)) mask |= kDeleteSelf;
|
| + if (e->mask & IN_ISDIR) mask |= kIsDir;
|
| + Dart_ListSetAt(event, 0, Dart_NewInteger(mask));
|
| + Dart_ListSetAt(event, 1, Dart_NewInteger(e->cookie));
|
| + if (e->len > 0) {
|
| + Dart_ListSetAt(event, 2, Dart_NewStringFromUTF8(
|
| + reinterpret_cast<uint8_t*>(e->name), strlen(e->name)));
|
| + } else {
|
| + Dart_ListSetAt(event, 2, Dart_Null());
|
| + }
|
| + Dart_ListSetAt(event, 3, Dart_NewBoolean(e->mask & IN_MOVED_TO));
|
| + Dart_ListSetAt(event, 4, Dart_NewInteger(e->wd));
|
| + Dart_ListSetAt(events, i, event);
|
| + i++;
|
| }
|
| - Dart_ListSetAt(event, 3, Dart_NewBoolean(e->mask & IN_MOVED_TO));
|
| - Dart_ListSetAt(events, i, event);
|
| - i++;
|
| offset += kEventSize + e->len;
|
| }
|
| ASSERT(offset == bytes);
|
|
|