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 | |
15 #include "platform/signal_blocker.h" | 14 #include "platform/signal_blocker.h" |
16 | 15 |
17 | |
18 namespace dart { | 16 namespace dart { |
19 namespace bin { | 17 namespace bin { |
20 | 18 |
21 bool FileSystemWatcher::IsSupported() { | 19 bool FileSystemWatcher::IsSupported() { |
22 return true; | 20 return true; |
23 } | 21 } |
24 | 22 |
25 | 23 |
26 intptr_t FileSystemWatcher::Init() { | 24 intptr_t FileSystemWatcher::Init() { |
27 int id = NO_RETRY_EXPECTED(inotify_init()); | 25 int id = NO_RETRY_EXPECTED(inotify_init()); |
(...skipping 11 matching lines...) Expand all Loading... |
39 void FileSystemWatcher::Close(intptr_t id) { | 37 void FileSystemWatcher::Close(intptr_t id) { |
40 USE(id); | 38 USE(id); |
41 } | 39 } |
42 | 40 |
43 | 41 |
44 intptr_t FileSystemWatcher::WatchPath(intptr_t id, | 42 intptr_t FileSystemWatcher::WatchPath(intptr_t id, |
45 const char* path, | 43 const char* path, |
46 int events, | 44 int events, |
47 bool recursive) { | 45 bool recursive) { |
48 int list_events = IN_DELETE_SELF | IN_MOVE_SELF; | 46 int list_events = IN_DELETE_SELF | IN_MOVE_SELF; |
49 if (events & kCreate) list_events |= IN_CREATE; | 47 if (events & kCreate) { |
50 if (events & kModifyContent) list_events |= IN_CLOSE_WRITE | IN_ATTRIB; | 48 list_events |= IN_CREATE; |
51 if (events & kDelete) list_events |= IN_DELETE; | 49 } |
52 if (events & kMove) list_events |= IN_MOVE; | 50 if (events & kModifyContent) { |
| 51 list_events |= IN_CLOSE_WRITE | IN_ATTRIB; |
| 52 } |
| 53 if (events & kDelete) { |
| 54 list_events |= IN_DELETE; |
| 55 } |
| 56 if (events & kMove) { |
| 57 list_events |= IN_MOVE; |
| 58 } |
53 int path_id = NO_RETRY_EXPECTED(inotify_add_watch(id, path, list_events)); | 59 int path_id = NO_RETRY_EXPECTED(inotify_add_watch(id, path, list_events)); |
54 if (path_id < 0) { | 60 if (path_id < 0) { |
55 return -1; | 61 return -1; |
56 } | 62 } |
57 return path_id; | 63 return path_id; |
58 } | 64 } |
59 | 65 |
60 | 66 |
61 void FileSystemWatcher::UnwatchPath(intptr_t id, intptr_t path_id) { | 67 void FileSystemWatcher::UnwatchPath(intptr_t id, intptr_t path_id) { |
62 VOID_NO_RETRY_EXPECTED(inotify_rm_watch(id, path_id)); | 68 VOID_NO_RETRY_EXPECTED(inotify_rm_watch(id, path_id)); |
63 } | 69 } |
64 | 70 |
65 | 71 |
66 intptr_t FileSystemWatcher::GetSocketId(intptr_t id, intptr_t path_id) { | 72 intptr_t FileSystemWatcher::GetSocketId(intptr_t id, intptr_t path_id) { |
67 USE(path_id); | 73 USE(path_id); |
68 return id; | 74 return id; |
69 } | 75 } |
70 | 76 |
71 | 77 |
| 78 static int InotifyEventToMask(struct inotify_event* e) { |
| 79 int mask = 0; |
| 80 if (e->mask & IN_CLOSE_WRITE) { |
| 81 mask |= FileSystemWatcher::kModifyContent; |
| 82 } |
| 83 if (e->mask & IN_ATTRIB) { |
| 84 mask |= FileSystemWatcher::kModefyAttribute; |
| 85 } |
| 86 if (e->mask & IN_CREATE) { |
| 87 mask |= FileSystemWatcher::kCreate; |
| 88 } |
| 89 if (e->mask & IN_MOVE) { |
| 90 mask |= FileSystemWatcher::kMove; |
| 91 } |
| 92 if (e->mask & IN_DELETE) { |
| 93 mask |= FileSystemWatcher::kDelete; |
| 94 } |
| 95 if (e->mask & (IN_DELETE_SELF | IN_MOVE_SELF)) { |
| 96 mask |= FileSystemWatcher::kDeleteSelf; |
| 97 } |
| 98 if (e->mask & IN_ISDIR) { |
| 99 mask |= FileSystemWatcher::kIsDir; |
| 100 } |
| 101 return mask; |
| 102 } |
| 103 |
| 104 |
72 Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id, intptr_t path_id) { | 105 Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id, intptr_t path_id) { |
73 USE(path_id); | 106 USE(path_id); |
74 const intptr_t kEventSize = sizeof(struct inotify_event); | 107 const intptr_t kEventSize = sizeof(struct inotify_event); |
75 const intptr_t kBufferSize = kEventSize + NAME_MAX + 1; | 108 const intptr_t kBufferSize = kEventSize + NAME_MAX + 1; |
76 uint8_t buffer[kBufferSize]; | 109 uint8_t buffer[kBufferSize]; |
77 intptr_t bytes = TEMP_FAILURE_RETRY(read(id, buffer, kBufferSize)); | 110 intptr_t bytes = TEMP_FAILURE_RETRY(read(id, buffer, kBufferSize)); |
78 if (bytes < 0) { | 111 if (bytes < 0) { |
79 return DartUtils::NewDartOSError(); | 112 return DartUtils::NewDartOSError(); |
80 } | 113 } |
81 const intptr_t kMaxCount = bytes / kEventSize; | 114 const intptr_t kMaxCount = bytes / kEventSize; |
82 Dart_Handle events = Dart_NewList(kMaxCount); | 115 Dart_Handle events = Dart_NewList(kMaxCount); |
83 intptr_t offset = 0; | 116 intptr_t offset = 0; |
84 intptr_t i = 0; | 117 intptr_t i = 0; |
85 while (offset < bytes) { | 118 while (offset < bytes) { |
86 struct inotify_event* e = | 119 struct inotify_event* e = |
87 reinterpret_cast<struct inotify_event*>(buffer + offset); | 120 reinterpret_cast<struct inotify_event*>(buffer + offset); |
88 if ((e->mask & IN_IGNORED) == 0) {; | 121 if ((e->mask & IN_IGNORED) == 0) {; |
89 Dart_Handle event = Dart_NewList(5); | 122 Dart_Handle event = Dart_NewList(5); |
90 int mask = 0; | 123 int mask = InotifyEventToMask(e); |
91 if (e->mask & IN_CLOSE_WRITE) mask |= kModifyContent; | |
92 if (e->mask & IN_ATTRIB) mask |= kModefyAttribute; | |
93 if (e->mask & IN_CREATE) mask |= kCreate; | |
94 if (e->mask & IN_MOVE) mask |= kMove; | |
95 if (e->mask & IN_DELETE) mask |= kDelete; | |
96 if (e->mask & (IN_DELETE_SELF | IN_MOVE_SELF)) mask |= kDeleteSelf; | |
97 if (e->mask & IN_ISDIR) mask |= kIsDir; | |
98 Dart_ListSetAt(event, 0, Dart_NewInteger(mask)); | 124 Dart_ListSetAt(event, 0, Dart_NewInteger(mask)); |
99 Dart_ListSetAt(event, 1, Dart_NewInteger(e->cookie)); | 125 Dart_ListSetAt(event, 1, Dart_NewInteger(e->cookie)); |
100 if (e->len > 0) { | 126 if (e->len > 0) { |
101 Dart_ListSetAt(event, 2, Dart_NewStringFromUTF8( | 127 Dart_ListSetAt(event, 2, Dart_NewStringFromUTF8( |
102 reinterpret_cast<uint8_t*>(e->name), strlen(e->name))); | 128 reinterpret_cast<uint8_t*>(e->name), strlen(e->name))); |
103 } else { | 129 } else { |
104 Dart_ListSetAt(event, 2, Dart_Null()); | 130 Dart_ListSetAt(event, 2, Dart_Null()); |
105 } | 131 } |
106 Dart_ListSetAt(event, 3, Dart_NewBoolean(e->mask & IN_MOVED_TO)); | 132 Dart_ListSetAt(event, 3, Dart_NewBoolean(e->mask & IN_MOVED_TO)); |
107 Dart_ListSetAt(event, 4, Dart_NewInteger(e->wd)); | 133 Dart_ListSetAt(event, 4, Dart_NewInteger(e->wd)); |
108 Dart_ListSetAt(events, i, event); | 134 Dart_ListSetAt(events, i, event); |
109 i++; | 135 i++; |
110 } | 136 } |
111 offset += kEventSize + e->len; | 137 offset += kEventSize + e->len; |
112 } | 138 } |
113 ASSERT(offset == bytes); | 139 ASSERT(offset == bytes); |
114 return events; | 140 return events; |
115 } | 141 } |
116 | 142 |
117 } // namespace bin | 143 } // namespace bin |
118 } // namespace dart | 144 } // namespace dart |
119 | 145 |
120 #endif // defined(TARGET_OS_ANDROID) | 146 #endif // defined(TARGET_OS_ANDROID) |
OLD | NEW |