Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #if defined(TARGET_OS_ANDROID) | 6 #if defined(TARGET_OS_ANDROID) |
| 7 | 7 |
| 8 #include "bin/file_system_watcher.h" | 8 #include "bin/file_system_watcher.h" |
| 9 | 9 |
| 10 #include <errno.h> // NOLINT | 10 #include <errno.h> // NOLINT |
| 11 #include <sys/inotify.h> // NOLINT | 11 #include <sys/inotify.h> // NOLINT |
| 12 | 12 |
| 13 #include "bin/fdutils.h" | 13 #include "bin/fdutils.h" |
| 14 | 14 |
| 15 | 15 |
| 16 namespace dart { | 16 namespace dart { |
| 17 namespace bin { | 17 namespace bin { |
| 18 | 18 |
| 19 bool FileSystemWatcher::IsSupported() { | 19 bool FileSystemWatcher::IsSupported() { |
| 20 return true; | 20 return true; |
| 21 } | 21 } |
| 22 | 22 |
| 23 | 23 |
| 24 intptr_t FileSystemWatcher::WatchPath(const char* path, | 24 intptr_t FileSystemWatcher::WatchPath(const char* path, |
| 25 int events, | 25 int events, |
| 26 bool recursive) { | 26 bool recursive) { |
| 27 int fd = TEMP_FAILURE_RETRY(inotify_init()); | 27 int fd = TEMP_FAILURE_RETRY(inotify_init()); |
|
Søren Gjesse
2013/10/30 14:05:51
Please add a comment on why this fd is blocking.
Anders Johnsen
2013/10/30 14:17:22
Done.
| |
| 28 if (fd < 0 || !FDUtils::SetNonBlocking(fd) || !FDUtils::SetCloseOnExec(fd)) { | 28 if (fd < 0 || !FDUtils::SetCloseOnExec(fd)) { |
| 29 return -1; | 29 return -1; |
| 30 } | 30 } |
| 31 int list_events = 0; | 31 // Some systems dosn't support setting this as non-blocking. Since watching |
| 32 // internals are kept away from the user, we know it's possible to continue, | |
| 33 // even if setting non-blocking fails. | |
| 34 FDUtils::SetNonBlocking(fd); | |
| 35 int list_events = IN_DELETE_SELF | IN_MOVE_SELF; | |
| 32 if (events & kCreate) list_events |= IN_CREATE; | 36 if (events & kCreate) list_events |= IN_CREATE; |
| 33 if (events & kModifyContent) list_events |= IN_MODIFY | IN_ATTRIB; | 37 if (events & kModifyContent) list_events |= IN_MODIFY | IN_ATTRIB; |
| 34 if (events & kDelete) list_events |= IN_DELETE; | 38 if (events & kDelete) list_events |= IN_DELETE; |
| 35 if (events & kMove) list_events |= IN_MOVE; | 39 if (events & kMove) list_events |= IN_MOVE; |
| 36 int path_fd = TEMP_FAILURE_RETRY(inotify_add_watch(fd, path, list_events)); | 40 int path_fd = TEMP_FAILURE_RETRY(inotify_add_watch(fd, path, list_events)); |
| 37 if (path_fd < 0) { | 41 if (path_fd < 0) { |
| 38 close(fd); | 42 close(fd); |
| 39 return -1; | 43 return -1; |
| 40 } | 44 } |
| 41 return fd; | 45 return fd; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 62 } | 66 } |
| 63 const intptr_t kMaxCount = kBufferSize / kEventSize + 1; | 67 const intptr_t kMaxCount = kBufferSize / kEventSize + 1; |
| 64 Dart_Handle events = Dart_NewList(kMaxCount); | 68 Dart_Handle events = Dart_NewList(kMaxCount); |
| 65 intptr_t offset = 0; | 69 intptr_t offset = 0; |
| 66 intptr_t i = 0; | 70 intptr_t i = 0; |
| 67 while (offset < bytes) { | 71 while (offset < bytes) { |
| 68 struct inotify_event* e = | 72 struct inotify_event* e = |
| 69 reinterpret_cast<struct inotify_event*>(buffer + offset); | 73 reinterpret_cast<struct inotify_event*>(buffer + offset); |
| 70 Dart_Handle event = Dart_NewList(4); | 74 Dart_Handle event = Dart_NewList(4); |
| 71 int mask = 0; | 75 int mask = 0; |
| 72 if (e->mask & IN_MODIFY) mask |= kModifyContent; | 76 if (e->mask & IN_CLOSE_WRITE) mask |= kModifyContent; |
| 73 if (e->mask & IN_ATTRIB) mask |= kModefyAttribute; | 77 if (e->mask & IN_ATTRIB) mask |= kModefyAttribute; |
| 74 if (e->mask & IN_CREATE) mask |= kCreate; | 78 if (e->mask & IN_CREATE) mask |= kCreate; |
| 75 if (e->mask & IN_MOVE) mask |= kMove; | 79 if (e->mask & IN_MOVE) mask |= kMove; |
| 76 if (e->mask & IN_DELETE) mask |= kDelete; | 80 if (e->mask & IN_DELETE) mask |= kDelete; |
| 81 if (e->mask & (IN_DELETE_SELF | IN_MOVE_SELF)) mask |= kDeleteSelf; | |
| 82 if (e->mask & IN_ISDIR) mask |= kIsDir; | |
| 77 Dart_ListSetAt(event, 0, Dart_NewInteger(mask)); | 83 Dart_ListSetAt(event, 0, Dart_NewInteger(mask)); |
| 78 Dart_ListSetAt(event, 1, Dart_NewInteger(e->cookie)); | 84 Dart_ListSetAt(event, 1, Dart_NewInteger(e->cookie)); |
| 79 if (e->len > 0) { | 85 if (e->len > 0) { |
| 80 Dart_ListSetAt(event, 2, Dart_NewStringFromUTF8( | 86 Dart_ListSetAt(event, 2, Dart_NewStringFromUTF8( |
| 81 reinterpret_cast<uint8_t*>(e->name), strlen(e->name))); | 87 reinterpret_cast<uint8_t*>(e->name), strlen(e->name))); |
| 82 } else { | 88 } else { |
| 83 Dart_ListSetAt(event, 2, Dart_Null()); | 89 Dart_ListSetAt(event, 2, Dart_Null()); |
| 84 } | 90 } |
| 85 Dart_ListSetAt(event, 3, Dart_NewBoolean(e->mask & IN_MOVED_TO)); | 91 Dart_ListSetAt(event, 3, Dart_NewBoolean(e->mask & IN_MOVED_TO)); |
| 86 Dart_ListSetAt(events, i, event); | 92 Dart_ListSetAt(events, i, event); |
| 87 i++; | 93 i++; |
| 88 offset += kEventSize + e->len; | 94 offset += kEventSize + e->len; |
| 89 } | 95 } |
| 90 ASSERT(offset == bytes); | 96 ASSERT(offset == bytes); |
| 91 return events; | 97 return events; |
| 92 } | 98 } |
| 93 | 99 |
| 94 } // namespace bin | 100 } // namespace bin |
| 95 } // namespace dart | 101 } // namespace dart |
| 96 | 102 |
| 97 #endif // defined(TARGET_OS_ANDROID) | 103 #endif // defined(TARGET_OS_ANDROID) |
| OLD | NEW |