Rev 15 | Rev 21 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 15 | Rev 17 | ||
---|---|---|---|
Line 79... | Line 79... | ||
79 | else if (rName == "IN_ONESHOT") |
79 | else if (rName == "IN_ONESHOT") |
80 | return IN_ONESHOT; |
80 | return IN_ONESHOT; |
81 | else if (rName == "IN_ALL_EVENTS") |
81 | else if (rName == "IN_ALL_EVENTS") |
82 | return IN_ALL_EVENTS; |
82 | return IN_ALL_EVENTS; |
83 | 83 | ||
- | 84 | #ifdef IN_DONT_FOLLOW
|
|
- | 85 | else if (rName == "IN_DONT_FOLLOW") |
|
- | 86 | return IN_DONT_FOLLOW; |
|
- | 87 | #endif // IN_DONT_FOLLOW
|
|
- | 88 | ||
- | 89 | #ifdef IN_ONLYDIR
|
|
- | 90 | else if (rName == "IN_ONLYDIR") |
|
- | 91 | return IN_ONLYDIR; |
|
- | 92 | #endif // IN_ONLYDIR
|
|
- | 93 | ||
84 | return (uint32_t) 0; |
94 | return (uint32_t) 0; |
85 | }
|
95 | }
|
86 | 96 | ||
87 | void InotifyEvent::DumpTypes(uint32_t uValue, std::string& rStr) |
97 | void InotifyEvent::DumpTypes(uint32_t uValue, std::string& rStr) |
88 | {
|
98 | {
|
Line 167... | Line 177... | ||
167 | }
|
177 | }
|
168 | if (IsType(uValue, IN_ONESHOT)) { |
178 | if (IsType(uValue, IN_ONESHOT)) { |
169 | DUMP_SEP;
|
179 | DUMP_SEP;
|
170 | rStr.append("IN_ONESHOT"); |
180 | rStr.append("IN_ONESHOT"); |
171 | }
|
181 | }
|
- | 182 | ||
- | 183 | #ifdef IN_DONT_FOLLOW
|
|
- | 184 | if (IsType(uValue, IN_DONT_FOLLOW)) { |
|
- | 185 | DUMP_SEP;
|
|
- | 186 | rStr.append("IN_DONT_FOLLOW"); |
|
- | 187 | }
|
|
- | 188 | #endif // IN_DONT_FOLLOW
|
|
- | 189 | ||
- | 190 | #ifdef IN_ONLYDIR
|
|
- | 191 | if (IsType(uValue, IN_ONLYDIR)) { |
|
- | 192 | DUMP_SEP;
|
|
- | 193 | rStr.append("IN_ONLYDIR"); |
|
- | 194 | }
|
|
- | 195 | #endif // IN_ONLYDIR
|
|
172 | }
|
196 | }
|
173 | 197 | ||
174 | void InotifyEvent::DumpTypes(std::string& rStr) const |
198 | void InotifyEvent::DumpTypes(std::string& rStr) const |
175 | {
|
199 | {
|
176 | DumpTypes(m_uMask, rStr); |
200 | DumpTypes(m_uMask, rStr); |
177 | }
|
201 | }
|
178 | 202 | ||
179 | 203 | ||
- | 204 | void InotifyWatch::SetMask(uint32_t uMask) throw (InotifyException) |
|
- | 205 | {
|
|
- | 206 | if (m_wd != -1) { |
|
- | 207 | int wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), uMask); |
|
- | 208 | if (wd != m_wd) |
|
- | 209 | throw InotifyException(IN_EXC_MSG("changing mask failed"), wd == -1 ? errno : EINVAL, this); |
|
- | 210 | }
|
|
- | 211 | ||
- | 212 | m_uMask = uMask; |
|
- | 213 | }
|
|
- | 214 | ||
- | 215 | void InotifyWatch::SetEnabled(bool fEnabled) throw (InotifyException) |
|
- | 216 | {
|
|
- | 217 | if (fEnabled == m_fEnabled) |
|
- | 218 | return; |
|
- | 219 | ||
- | 220 | if (m_pInotify != NULL) { |
|
- | 221 | if (fEnabled) { |
|
- | 222 | m_wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), m_uMask); |
|
- | 223 | if (m_wd == -1) |
|
- | 224 | throw InotifyException(IN_EXC_MSG("enabling watch failed"), errno, this); |
|
- | 225 | m_pInotify->m_watches.insert(IN_WATCH_MAP::value_type(m_wd, this)); |
|
- | 226 | }
|
|
- | 227 | else { |
|
- | 228 | if (inotify_rm_watch(m_pInotify->GetDescriptor(), m_wd) != 0) |
|
- | 229 | throw InotifyException(IN_EXC_MSG("disabling watch failed"), errno, this); |
|
- | 230 | m_pInotify->m_watches.erase(m_wd); |
|
- | 231 | m_wd = -1; |
|
- | 232 | }
|
|
- | 233 | }
|
|
- | 234 | ||
- | 235 | m_fEnabled = fEnabled; |
|
- | 236 | }
|
|
- | 237 | ||
- | 238 | ||
180 | Inotify::Inotify() throw (InotifyException) |
239 | Inotify::Inotify() throw (InotifyException) |
181 | {
|
240 | {
|
182 | m_fd = inotify_init(); |
241 | m_fd = inotify_init(); |
183 | if (m_fd == -1) |
242 | if (m_fd == -1) |
184 | throw InotifyException(std::string(__PRETTY_FUNCTION__) + ": inotify init failed", errno, NULL); |
243 | throw InotifyException(IN_EXC_MSG("inotify init failed"), errno, NULL); |
185 | }
|
244 | }
|
186 | 245 | ||
187 | Inotify::~Inotify() |
246 | Inotify::~Inotify() |
188 | {
|
247 | {
|
189 | Close(); |
248 | Close(); |
Line 198... | Line 257... | ||
198 | }
|
257 | }
|
199 | }
|
258 | }
|
200 | 259 | ||
201 | void Inotify::Add(InotifyWatch* pWatch) throw (InotifyException) |
260 | void Inotify::Add(InotifyWatch* pWatch) throw (InotifyException) |
202 | {
|
261 | {
|
- | 262 | // invalid descriptor - this case shouldn't occur - go away
|
|
203 | if (m_fd == -1) |
263 | if (m_fd == -1) |
204 | throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
264 | throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
205 | 265 | ||
- | 266 | // this path already watched - go away
|
|
- | 267 | if (FindWatch(pWatch->GetPath()) != NULL) |
|
- | 268 | throw InotifyException(IN_EXC_MSG("path already watched"), EBUSY, this); |
|
- | 269 | ||
- | 270 | // for enabled watch
|
|
- | 271 | if (pWatch->IsEnabled()) { |
|
- | 272 | ||
- | 273 | // try to add watch to kernel
|
|
206 | pWatch->m_wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask()); |
274 | int wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask()); |
207 | 275 | ||
- | 276 | // adding failed - go away
|
|
208 | if (pWatch->m_wd == -1) |
277 | if (wd == -1) |
209 | throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this); |
278 | throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this); |
210 | 279 | ||
- | 280 | // this path already watched (but defined another way)
|
|
- | 281 | InotifyWatch* pW = FindWatch(wd); |
|
- | 282 | if (pW != NULL) { |
|
- | 283 | ||
- | 284 | // try to recover old watch because it may be modified - then go away
|
|
- | 285 | if (inotify_add_watch(m_fd, pW->GetPath().c_str(), pW->GetMask()) < 0) { |
|
- | 286 | throw InotifyException(IN_EXC_MSG("watch collision detected and recovery failed"), errno, this); |
|
- | 287 | }
|
|
- | 288 | else { |
|
- | 289 | // recovery failed - go away
|
|
- | 290 | throw InotifyException(IN_EXC_MSG("path already watched (but defined another way)"), EBUSY, this); |
|
- | 291 | }
|
|
- | 292 | }
|
|
- | 293 | ||
- | 294 | pWatch->m_wd = wd; |
|
211 | m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch)); |
295 | m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch)); |
- | 296 | }
|
|
- | 297 | ||
- | 298 | m_paths.insert(IN_WP_MAP::value_type(pWatch->m_path, pWatch)); |
|
212 | pWatch->m_pInotify = this; |
299 | pWatch->m_pInotify = this; |
213 | }
|
300 | }
|
214 | 301 | ||
215 | void Inotify::Remove(InotifyWatch* pWatch) throw (InotifyException) |
302 | void Inotify::Remove(InotifyWatch* pWatch) throw (InotifyException) |
216 | {
|
303 | {
|
- | 304 | // invalid descriptor - this case shouldn't occur - go away
|
|
217 | if (m_fd == -1) |
305 | if (m_fd == -1) |
218 | throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
306 | throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
219 | 307 | ||
220 | if (inotify_rm_watch(m_fd, pWatch->GetMask()) == -1) |
308 | // for enabled watch
|
221 | throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this); |
309 | if (pWatch->m_wd != -1) { |
222 | 310 | ||
- | 311 | // removing watch failed - go away
|
|
- | 312 | if (inotify_rm_watch(m_fd, pWatch->m_wd) == -1) |
|
- | 313 | throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this); |
|
223 | m_watches.erase(pWatch->m_wd); |
314 | m_watches.erase(pWatch->m_wd); |
224 | pWatch->m_wd = -1; |
315 | pWatch->m_wd = -1; |
- | 316 | }
|
|
- | 317 | ||
- | 318 | m_paths.erase(pWatch->m_path); |
|
225 | pWatch->m_pInotify = NULL; |
319 | pWatch->m_pInotify = NULL; |
226 | }
|
320 | }
|
227 | 321 | ||
228 | void Inotify::RemoveAll() |
322 | void Inotify::RemoveAll() |
229 | {
|
323 | {
|
230 | IN_WATCH_MAP::iterator it = m_watches.begin(); |
324 | IN_WP_MAP::iterator it = m_paths.begin(); |
231 | while (it != m_watches.end()) { |
325 | while (it != m_paths.end()) { |
232 | InotifyWatch* pW = (*it).second; |
326 | InotifyWatch* pW = (*it).second; |
- | 327 | if (pW->m_wd != -1) { |
|
233 | inotify_rm_watch(m_fd, pW->GetMask()); |
328 | inotify_rm_watch(m_fd, pW->m_wd); |
234 | pW->m_wd = -1; |
329 | pW->m_wd = -1; |
- | 330 | }
|
|
235 | pW->m_pInotify = NULL; |
331 | pW->m_pInotify = NULL; |
236 | it++; |
332 | it++; |
237 | }
|
333 | }
|
238 | 334 | ||
239 | m_watches.clear(); |
335 | m_watches.clear(); |
- | 336 | m_paths.clear(); |
|
240 | }
|
337 | }
|
241 | 338 | ||
242 | void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException) |
339 | void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException) |
243 | {
|
340 | {
|
244 | ssize_t len = 0; |
341 | ssize_t len = 0; |
Line 255... | Line 352... | ||
255 | 352 | ||
256 | ssize_t i = 0; |
353 | ssize_t i = 0; |
257 | while (i < len) { |
354 | while (i < len) { |
258 | struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i]; |
355 | struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i]; |
259 | InotifyWatch* pW = FindWatch(pEvt->wd); |
356 | InotifyWatch* pW = FindWatch(pEvt->wd); |
260 | if (pW != NULL && pW->IsEnabled()) { |
357 | if (pW != NULL) { |
261 | InotifyEvent evt(pEvt, pW); |
358 | InotifyEvent evt(pEvt, pW); |
262 | m_events.push_back(evt); |
359 | m_events.push_back(evt); |
263 | }
|
360 | }
|
264 | i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len; |
361 | i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len; |
265 | }
|
362 | }
|
Line 300... | Line 397... | ||
300 | return NULL; |
397 | return NULL; |
301 | 398 | ||
302 | return (*it).second; |
399 | return (*it).second; |
303 | }
|
400 | }
|
304 | 401 | ||
- | 402 | InotifyWatch* Inotify::FindWatch(const std::string& rPath) |
|
- | 403 | {
|
|
- | 404 | IN_WP_MAP::iterator it = m_paths.find(rPath); |
|
- | 405 | if (it == m_paths.end()) |
|
- | 406 | return NULL; |
|
- | 407 | ||
- | 408 | return (*it).second; |
|
- | 409 | }
|
|
- | 410 | ||
305 | void Inotify::SetNonBlock(bool fNonBlock) throw (InotifyException) |
411 | void Inotify::SetNonBlock(bool fNonBlock) throw (InotifyException) |
306 | {
|
412 | {
|
307 | if (m_fd == -1) |
413 | if (m_fd == -1) |
308 | throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
414 | throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
309 | 415 |