summaryrefslogtreecommitdiff
path: root/shared/inotify/inotify-cxx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'shared/inotify/inotify-cxx.cpp')
-rw-r--r--shared/inotify/inotify-cxx.cpp1020
1 files changed, 544 insertions, 476 deletions
diff --git a/shared/inotify/inotify-cxx.cpp b/shared/inotify/inotify-cxx.cpp
index 689612ac..5a460ec7 100644
--- a/shared/inotify/inotify-cxx.cpp
+++ b/shared/inotify/inotify-cxx.cpp
@@ -2,11 +2,11 @@
/// inotify C++ interface implementation
/**
* \file inotify-cxx.cpp
- *
+ *
* inotify C++ interface
- *
+ *
* Copyright (C) 2006, 2007, 2009 Lukas Jelinek <lukas@aiken.cz>
- *
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of one of the following licenses:
*
@@ -19,9 +19,9 @@
*
* Credits:
* Mike Frysinger (cleanup of includes)
- *
+ *
*/
-
+
#include <errno.h>
#include <unistd.h>
@@ -52,590 +52,658 @@
int32_t InotifyEvent::GetDescriptor() const
{
- return m_pWatch != NULL // if watch exists
- ? m_pWatch->GetDescriptor() // return its descriptor
- : -1; // else return -1
+ return m_pWatch != NULL // if watch exists
+ ? m_pWatch->GetDescriptor() // return its descriptor
+ : -1; // else return -1
}
uint32_t InotifyEvent::GetMaskByName(const std::string& rName)
{
- if (rName == "IN_ACCESS")
- return IN_ACCESS;
- else if (rName == "IN_MODIFY")
- return IN_MODIFY;
- else if (rName == "IN_ATTRIB")
- return IN_ATTRIB;
- else if (rName == "IN_CLOSE_WRITE")
- return IN_CLOSE_WRITE;
- else if (rName == "IN_CLOSE_NOWRITE")
- return IN_CLOSE_NOWRITE;
- else if (rName == "IN_OPEN")
- return IN_OPEN;
- else if (rName == "IN_MOVED_FROM")
- return IN_MOVED_FROM;
- else if (rName == "IN_MOVED_TO")
- return IN_MOVED_TO;
- else if (rName == "IN_CREATE")
- return IN_CREATE;
- else if (rName == "IN_DELETE")
- return IN_DELETE;
- else if (rName == "IN_DELETE_SELF")
- return IN_DELETE_SELF;
- else if (rName == "IN_UNMOUNT")
- return IN_UNMOUNT;
- else if (rName == "IN_Q_OVERFLOW")
- return IN_Q_OVERFLOW;
- else if (rName == "IN_IGNORED")
- return IN_IGNORED;
- else if (rName == "IN_CLOSE")
- return IN_CLOSE;
- else if (rName == "IN_MOVE")
- return IN_MOVE;
- else if (rName == "IN_ISDIR")
- return IN_ISDIR;
- else if (rName == "IN_ONESHOT")
- return IN_ONESHOT;
- else if (rName == "IN_ALL_EVENTS")
- return IN_ALL_EVENTS;
-
+ if (rName == "IN_ACCESS")
+ return IN_ACCESS;
+ else if (rName == "IN_MODIFY")
+ return IN_MODIFY;
+ else if (rName == "IN_ATTRIB")
+ return IN_ATTRIB;
+ else if (rName == "IN_CLOSE_WRITE")
+ return IN_CLOSE_WRITE;
+ else if (rName == "IN_CLOSE_NOWRITE")
+ return IN_CLOSE_NOWRITE;
+ else if (rName == "IN_OPEN")
+ return IN_OPEN;
+ else if (rName == "IN_MOVED_FROM")
+ return IN_MOVED_FROM;
+ else if (rName == "IN_MOVED_TO")
+ return IN_MOVED_TO;
+ else if (rName == "IN_CREATE")
+ return IN_CREATE;
+ else if (rName == "IN_DELETE")
+ return IN_DELETE;
+ else if (rName == "IN_DELETE_SELF")
+ return IN_DELETE_SELF;
+ else if (rName == "IN_UNMOUNT")
+ return IN_UNMOUNT;
+ else if (rName == "IN_Q_OVERFLOW")
+ return IN_Q_OVERFLOW;
+ else if (rName == "IN_IGNORED")
+ return IN_IGNORED;
+ else if (rName == "IN_CLOSE")
+ return IN_CLOSE;
+ else if (rName == "IN_MOVE")
+ return IN_MOVE;
+ else if (rName == "IN_ISDIR")
+ return IN_ISDIR;
+ else if (rName == "IN_ONESHOT")
+ return IN_ONESHOT;
+ else if (rName == "IN_ALL_EVENTS")
+ return IN_ALL_EVENTS;
+
#ifdef IN_DONT_FOLLOW
- else if (rName == "IN_DONT_FOLLOW")
- return IN_DONT_FOLLOW;
+ else if (rName == "IN_DONT_FOLLOW")
+ return IN_DONT_FOLLOW;
#endif // IN_DONT_FOLLOW
#ifdef IN_ONLYDIR
- else if (rName == "IN_ONLYDIR")
- return IN_ONLYDIR;
+ else if (rName == "IN_ONLYDIR")
+ return IN_ONLYDIR;
#endif // IN_ONLYDIR
#ifdef IN_MOVE_SELF
- else if (rName == "IN_MOVE_SELF")
- return IN_MOVE_SELF;
+ else if (rName == "IN_MOVE_SELF")
+ return IN_MOVE_SELF;
#endif // IN_MOVE_SELF
-
- return (uint32_t) 0;
+
+ return (uint32_t) 0;
}
void InotifyEvent::DumpTypes(uint32_t uValue, std::string& rStr)
{
- rStr = "";
-
- if (IsType(uValue, IN_ALL_EVENTS)) {
- rStr.append("IN_ALL_EVENTS");
- }
- else {
- if (IsType(uValue, IN_ACCESS)) {
- DUMP_SEP;
- rStr.append("IN_ACCESS");
- }
- if (IsType(uValue, IN_MODIFY)) {
- DUMP_SEP;
- rStr.append("IN_MODIFY");
- }
- if (IsType(uValue, IN_ATTRIB)) {
- DUMP_SEP;
- rStr.append("IN_ATTRIB");
- }
- if (IsType(uValue, IN_CREATE)) {
- DUMP_SEP;
- rStr.append("IN_CREATE");
- }
- if (IsType(uValue, IN_DELETE)) {
- DUMP_SEP;
- rStr.append("IN_DELETE");
- }
- if (IsType(uValue, IN_DELETE_SELF)) {
- DUMP_SEP;
- rStr.append("IN_DELETE_SELF");
- }
- if (IsType(uValue, IN_OPEN)) {
- DUMP_SEP;
- rStr.append("IN_OPEN");
- }
- if (IsType(uValue, IN_CLOSE)) {
- DUMP_SEP;
- rStr.append("IN_CLOSE");
+ rStr = "";
+
+ if (IsType(uValue, IN_ALL_EVENTS))
+ {
+ rStr.append("IN_ALL_EVENTS");
}
+ else
+ {
+ if (IsType(uValue, IN_ACCESS))
+ {
+ DUMP_SEP;
+ rStr.append("IN_ACCESS");
+ }
+ if (IsType(uValue, IN_MODIFY))
+ {
+ DUMP_SEP;
+ rStr.append("IN_MODIFY");
+ }
+ if (IsType(uValue, IN_ATTRIB))
+ {
+ DUMP_SEP;
+ rStr.append("IN_ATTRIB");
+ }
+ if (IsType(uValue, IN_CREATE))
+ {
+ DUMP_SEP;
+ rStr.append("IN_CREATE");
+ }
+ if (IsType(uValue, IN_DELETE))
+ {
+ DUMP_SEP;
+ rStr.append("IN_DELETE");
+ }
+ if (IsType(uValue, IN_DELETE_SELF))
+ {
+ DUMP_SEP;
+ rStr.append("IN_DELETE_SELF");
+ }
+ if (IsType(uValue, IN_OPEN))
+ {
+ DUMP_SEP;
+ rStr.append("IN_OPEN");
+ }
+ if (IsType(uValue, IN_CLOSE))
+ {
+ DUMP_SEP;
+ rStr.append("IN_CLOSE");
+ }
#ifdef IN_MOVE_SELF
- if (IsType(uValue, IN_MOVE_SELF)) {
- DUMP_SEP;
- rStr.append("IN_MOVE_SELF");
- }
+ if (IsType(uValue, IN_MOVE_SELF))
+ {
+ DUMP_SEP;
+ rStr.append("IN_MOVE_SELF");
+ }
#endif // IN_MOVE_SELF
-
- else {
- if (IsType(uValue, IN_CLOSE_WRITE)) {
+
+ else
+ {
+ if (IsType(uValue, IN_CLOSE_WRITE))
+ {
+ DUMP_SEP;
+ rStr.append("IN_CLOSE_WRITE");
+ }
+ if (IsType(uValue, IN_CLOSE_NOWRITE))
+ {
+ DUMP_SEP;
+ rStr.append("IN_CLOSE_NOWRITE");
+ }
+ }
+ if (IsType(uValue, IN_MOVE))
+ {
+ DUMP_SEP;
+ rStr.append("IN_MOVE");
+ }
+ else
+ {
+ if (IsType(uValue, IN_MOVED_FROM))
+ {
+ DUMP_SEP;
+ rStr.append("IN_MOVED_FROM");
+ }
+ if (IsType(uValue, IN_MOVED_TO))
+ {
+ DUMP_SEP;
+ rStr.append("IN_MOVED_TO");
+ }
+ }
+ }
+ if (IsType(uValue, IN_UNMOUNT))
+ {
DUMP_SEP;
- rStr.append("IN_CLOSE_WRITE");
- }
- if (IsType(uValue, IN_CLOSE_NOWRITE)) {
+ rStr.append("IN_UNMOUNT");
+ }
+ if (IsType(uValue, IN_Q_OVERFLOW))
+ {
DUMP_SEP;
- rStr.append("IN_CLOSE_NOWRITE");
- }
+ rStr.append("IN_Q_OVERFLOW");
}
- if (IsType(uValue, IN_MOVE)) {
- DUMP_SEP;
- rStr.append("IN_MOVE");
+ if (IsType(uValue, IN_IGNORED))
+ {
+ DUMP_SEP;
+ rStr.append("IN_IGNORED");
}
- else {
- if (IsType(uValue, IN_MOVED_FROM)) {
+ if (IsType(uValue, IN_ISDIR))
+ {
DUMP_SEP;
- rStr.append("IN_MOVED_FROM");
- }
- if (IsType(uValue, IN_MOVED_TO)) {
+ rStr.append("IN_ISDIR");
+ }
+ if (IsType(uValue, IN_ONESHOT))
+ {
DUMP_SEP;
- rStr.append("IN_MOVED_TO");
- }
- }
- }
- if (IsType(uValue, IN_UNMOUNT)) {
- DUMP_SEP;
- rStr.append("IN_UNMOUNT");
- }
- if (IsType(uValue, IN_Q_OVERFLOW)) {
- DUMP_SEP;
- rStr.append("IN_Q_OVERFLOW");
- }
- if (IsType(uValue, IN_IGNORED)) {
- DUMP_SEP;
- rStr.append("IN_IGNORED");
- }
- if (IsType(uValue, IN_ISDIR)) {
- DUMP_SEP;
- rStr.append("IN_ISDIR");
- }
- if (IsType(uValue, IN_ONESHOT)) {
- DUMP_SEP;
- rStr.append("IN_ONESHOT");
- }
-
+ rStr.append("IN_ONESHOT");
+ }
+
#ifdef IN_DONT_FOLLOW
- if (IsType(uValue, IN_DONT_FOLLOW)) {
- DUMP_SEP;
- rStr.append("IN_DONT_FOLLOW");
- }
+ if (IsType(uValue, IN_DONT_FOLLOW))
+ {
+ DUMP_SEP;
+ rStr.append("IN_DONT_FOLLOW");
+ }
#endif // IN_DONT_FOLLOW
-
+
#ifdef IN_ONLYDIR
- if (IsType(uValue, IN_ONLYDIR)) {
- DUMP_SEP;
- rStr.append("IN_ONLYDIR");
- }
+ if (IsType(uValue, IN_ONLYDIR))
+ {
+ DUMP_SEP;
+ rStr.append("IN_ONLYDIR");
+ }
#endif // IN_ONLYDIR
}
void InotifyEvent::DumpTypes(std::string& rStr) const
{
- DumpTypes(m_uMask, rStr);
+ DumpTypes(m_uMask, rStr);
}
void InotifyWatch::SetMask(uint32_t uMask) throw (InotifyException)
{
- IN_WRITE_BEGIN
-
- if (m_wd != -1) {
- int wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), uMask);
- if (wd != m_wd) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("changing mask failed"), wd == -1 ? errno : EINVAL, this);
- }
- }
-
- m_uMask = uMask;
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ if (m_wd != -1)
+ {
+ int wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), uMask);
+ if (wd != m_wd)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("changing mask failed"), wd == -1 ? errno : EINVAL, this);
+ }
+ }
+
+ m_uMask = uMask;
+
+ IN_WRITE_END
}
void InotifyWatch::SetEnabled(bool fEnabled) throw (InotifyException)
{
- IN_WRITE_BEGIN
-
- if (fEnabled == m_fEnabled) {
- IN_WRITE_END_NOTHROW
- return;
- }
-
- if (m_pInotify != NULL) {
- if (fEnabled) {
- m_wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), m_uMask);
- if (m_wd == -1) {
+ IN_WRITE_BEGIN
+
+ if (fEnabled == m_fEnabled)
+ {
IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("enabling watch failed"), errno, this);
- }
- m_pInotify->m_watches.insert(IN_WATCH_MAP::value_type(m_wd, this));
+ return;
}
- else {
- if (inotify_rm_watch(m_pInotify->GetDescriptor(), m_wd) != 0) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("disabling watch failed"), errno, this);
- }
- m_pInotify->m_watches.erase(m_wd);
- m_wd = -1;
- }
- }
-
- m_fEnabled = fEnabled;
-
- IN_WRITE_END
+
+ if (m_pInotify != NULL)
+ {
+ if (fEnabled)
+ {
+ m_wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), m_uMask);
+ if (m_wd == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("enabling watch failed"), errno, this);
+ }
+ m_pInotify->m_watches.insert(IN_WATCH_MAP::value_type(m_wd, this));
+ }
+ else
+ {
+ if (inotify_rm_watch(m_pInotify->GetDescriptor(), m_wd) != 0)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("disabling watch failed"), errno, this);
+ }
+ m_pInotify->m_watches.erase(m_wd);
+ m_wd = -1;
+ }
+ }
+
+ m_fEnabled = fEnabled;
+
+ IN_WRITE_END
}
void InotifyWatch::__Disable()
{
- IN_WRITE_BEGIN
-
- if (!m_fEnabled) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("event cannot occur on disabled watch"), EINVAL, this);
- }
-
- if (m_pInotify != NULL) {
- m_pInotify->m_watches.erase(m_wd);
- m_wd = -1;
- }
-
- m_fEnabled = false;
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ if (!m_fEnabled)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("event cannot occur on disabled watch"), EINVAL, this);
+ }
+
+ if (m_pInotify != NULL)
+ {
+ m_pInotify->m_watches.erase(m_wd);
+ m_wd = -1;
+ }
+
+ m_fEnabled = false;
+
+ IN_WRITE_END
}
Inotify::Inotify() throw (InotifyException)
{
- IN_LOCK_INIT
-
- m_fd = inotify_init();
- if (m_fd == -1) {
- IN_LOCK_DONE
- throw InotifyException(IN_EXC_MSG("inotify init failed"), errno, NULL);
- }
+ IN_LOCK_INIT
+
+ m_fd = inotify_init();
+ if (m_fd == -1)
+ {
+ IN_LOCK_DONE
+ throw InotifyException(IN_EXC_MSG("inotify init failed"), errno, NULL);
+ }
}
-
+
Inotify::~Inotify()
{
- Close();
-
- IN_LOCK_DONE
+ Close();
+
+ IN_LOCK_DONE
}
void Inotify::Close()
{
- IN_WRITE_BEGIN
-
- if (m_fd != -1) {
- RemoveAll();
- close(m_fd);
- m_fd = -1;
- }
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ if (m_fd != -1)
+ {
+ RemoveAll();
+ close(m_fd);
+ m_fd = -1;
+ }
+
+ IN_WRITE_END
}
void Inotify::Add(InotifyWatch* pWatch) throw (InotifyException)
{
- IN_WRITE_BEGIN
-
- // invalid descriptor - this case shouldn't occur - go away
- if (m_fd == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
- }
-
- // this path already watched - go away
- if (FindWatch(pWatch->GetPath()) != NULL) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("path already watched"), EBUSY, this);
- }
-
- // for enabled watch
- if (pWatch->IsEnabled()) {
-
- // try to add watch to kernel
- int wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask());
-
- // adding failed - go away
- if (wd == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this);
- }
-
- // this path already watched (but defined another way)
- InotifyWatch* pW = FindWatch(wd);
- if (pW != NULL) {
-
- // try to recover old watch because it may be modified - then go away
- if (inotify_add_watch(m_fd, pW->GetPath().c_str(), pW->GetMask()) < 0) {
+ IN_WRITE_BEGIN
+
+ // invalid descriptor - this case shouldn't occur - go away
+ if (m_fd == -1)
+ {
IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("watch collision detected and recovery failed"), errno, this);
- }
- else {
- // recovery failed - go away
+ throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
+ }
+
+ // this path already watched - go away
+ if (FindWatch(pWatch->GetPath()) != NULL)
+ {
IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("path already watched (but defined another way)"), EBUSY, this);
- }
- }
-
- pWatch->m_wd = wd;
- m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch));
- }
-
- m_paths.insert(IN_WP_MAP::value_type(pWatch->m_path, pWatch));
- pWatch->m_pInotify = this;
-
- IN_WRITE_END
+ throw InotifyException(IN_EXC_MSG("path already watched"), EBUSY, this);
+ }
+
+ // for enabled watch
+ if (pWatch->IsEnabled())
+ {
+
+ // try to add watch to kernel
+ int wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask());
+
+ // adding failed - go away
+ if (wd == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this);
+ }
+
+ // this path already watched (but defined another way)
+ InotifyWatch* pW = FindWatch(wd);
+ if (pW != NULL)
+ {
+
+ // try to recover old watch because it may be modified - then go away
+ if (inotify_add_watch(m_fd, pW->GetPath().c_str(), pW->GetMask()) < 0)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("watch collision detected and recovery failed"), errno, this);
+ }
+ else
+ {
+ // recovery failed - go away
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("path already watched (but defined another way)"), EBUSY, this);
+ }
+ }
+
+ pWatch->m_wd = wd;
+ m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch));
+ }
+
+ m_paths.insert(IN_WP_MAP::value_type(pWatch->m_path, pWatch));
+ pWatch->m_pInotify = this;
+
+ IN_WRITE_END
}
void Inotify::Remove(InotifyWatch* pWatch) throw (InotifyException)
{
- IN_WRITE_BEGIN
-
- // invalid descriptor - this case shouldn't occur - go away
- if (m_fd == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
- }
-
- // for enabled watch
- if (pWatch->m_wd != -1) {
-
- // removing watch failed - go away
- if (inotify_rm_watch(m_fd, pWatch->m_wd) == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this);
- }
- m_watches.erase(pWatch->m_wd);
- pWatch->m_wd = -1;
- }
-
- m_paths.erase(pWatch->m_path);
- pWatch->m_pInotify = NULL;
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ // invalid descriptor - this case shouldn't occur - go away
+ if (m_fd == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
+ }
+
+ // for enabled watch
+ if (pWatch->m_wd != -1)
+ {
+
+ // removing watch failed - go away
+ if (inotify_rm_watch(m_fd, pWatch->m_wd) == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this);
+ }
+ m_watches.erase(pWatch->m_wd);
+ pWatch->m_wd = -1;
+ }
+
+ m_paths.erase(pWatch->m_path);
+ pWatch->m_pInotify = NULL;
+
+ IN_WRITE_END
}
void Inotify::RemoveAll()
{
- IN_WRITE_BEGIN
-
- IN_WP_MAP::iterator it = m_paths.begin();
- while (it != m_paths.end()) {
- InotifyWatch* pW = (*it).second;
- if (pW->m_wd != -1) {
- inotify_rm_watch(m_fd, pW->m_wd);
- pW->m_wd = -1;
- }
- pW->m_pInotify = NULL;
- it++;
- }
-
- m_watches.clear();
- m_paths.clear();
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ IN_WP_MAP::iterator it = m_paths.begin();
+ while (it != m_paths.end())
+ {
+ InotifyWatch* pW = (*it).second;
+ if (pW->m_wd != -1)
+ {
+ inotify_rm_watch(m_fd, pW->m_wd);
+ pW->m_wd = -1;
+ }
+ pW->m_pInotify = NULL;
+ it++;
+ }
+
+ m_watches.clear();
+ m_paths.clear();
+
+ IN_WRITE_END
}
void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException)
{
- ssize_t len = 0;
-
- do {
- len = read(m_fd, m_buf, INOTIFY_BUFLEN);
- } while (fNoIntr && len == -1 && errno == EINTR);
-
- if (len == -1 && !(errno == EWOULDBLOCK || errno == EINTR))
- throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this);
-
- if (len == -1)
- return;
-
- IN_WRITE_BEGIN
-
- ssize_t i = 0;
- while (i < len) {
- struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i];
- InotifyWatch* pW = FindWatch(pEvt->wd);
- if (pW != NULL) {
- InotifyEvent evt(pEvt, pW);
- if ( InotifyEvent::IsType(pW->GetMask(), IN_ONESHOT)
- || InotifyEvent::IsType(evt.GetMask(), IN_IGNORED))
- pW->__Disable();
- m_events.push_back(evt);
- }
- i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
- }
-
- IN_WRITE_END
+ ssize_t len = 0;
+
+ do
+ {
+ len = read(m_fd, m_buf, INOTIFY_BUFLEN);
+ }
+ while (fNoIntr && len == -1 && errno == EINTR);
+
+ if (len == -1 && !(errno == EWOULDBLOCK || errno == EINTR))
+ throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this);
+
+ if (len == -1)
+ return;
+
+ IN_WRITE_BEGIN
+
+ ssize_t i = 0;
+ while (i < len)
+ {
+ struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i];
+ InotifyWatch* pW = FindWatch(pEvt->wd);
+ if (pW != NULL)
+ {
+ InotifyEvent evt(pEvt, pW);
+ if ( InotifyEvent::IsType(pW->GetMask(), IN_ONESHOT)
+ || InotifyEvent::IsType(evt.GetMask(), IN_IGNORED))
+ pW->__Disable();
+ m_events.push_back(evt);
+ }
+ i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
+ }
+
+ IN_WRITE_END
}
-
+
bool Inotify::GetEvent(InotifyEvent* pEvt) throw (InotifyException)
{
- if (pEvt == NULL)
- throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
-
- IN_WRITE_BEGIN
-
- bool b = !m_events.empty();
- if (b) {
- *pEvt = m_events.front();
- m_events.pop_front();
- }
-
- IN_WRITE_END
-
- return b;
+ if (pEvt == NULL)
+ throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
+
+ IN_WRITE_BEGIN
+
+ bool b = !m_events.empty();
+ if (b)
+ {
+ *pEvt = m_events.front();
+ m_events.pop_front();
+ }
+
+ IN_WRITE_END
+
+ return b;
}
-
+
bool Inotify::PeekEvent(InotifyEvent* pEvt) throw (InotifyException)
{
- if (pEvt == NULL)
- throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
-
- IN_READ_BEGIN
-
- bool b = !m_events.empty();
- if (b) {
- *pEvt = m_events.front();
- }
-
- IN_READ_END
-
- return b;
+ if (pEvt == NULL)
+ throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
+
+ IN_READ_BEGIN
+
+ bool b = !m_events.empty();
+ if (b)
+ {
+ *pEvt = m_events.front();
+ }
+
+ IN_READ_END
+
+ return b;
}
InotifyWatch* Inotify::FindWatch(int iDescriptor)
{
- IN_READ_BEGIN
-
- IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor);
- InotifyWatch* pW = it == m_watches.end() ? NULL : (*it).second;
-
- IN_READ_END
-
- return pW;
+ IN_READ_BEGIN
+
+ IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor);
+ InotifyWatch* pW = it == m_watches.end() ? NULL : (*it).second;
+
+ IN_READ_END
+
+ return pW;
}
InotifyWatch* Inotify::FindWatch(const std::string& rPath)
{
- IN_READ_BEGIN
-
- IN_WP_MAP::iterator it = m_paths.find(rPath);
- InotifyWatch* pW = it == m_paths.end() ? NULL : (*it).second;
-
- IN_READ_END
-
- return pW;
+ IN_READ_BEGIN
+
+ IN_WP_MAP::iterator it = m_paths.find(rPath);
+ InotifyWatch* pW = it == m_paths.end() ? NULL : (*it).second;
+
+ IN_READ_END
+
+ return pW;
}
-
+
void Inotify::SetNonBlock(bool fNonBlock) throw (InotifyException)
{
- IN_WRITE_BEGIN
-
- if (m_fd == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
- }
-
- int res = fcntl(m_fd, F_GETFL);
- if (res == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
- }
-
- if (fNonBlock) {
- res |= O_NONBLOCK;
- }
- else {
- res &= ~O_NONBLOCK;
- }
-
- if (fcntl(m_fd, F_SETFL, res) == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
- }
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ if (m_fd == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
+ }
+
+ int res = fcntl(m_fd, F_GETFL);
+ if (res == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
+ }
+
+ if (fNonBlock)
+ {
+ res |= O_NONBLOCK;
+ }
+ else
+ {
+ res &= ~O_NONBLOCK;
+ }
+
+ if (fcntl(m_fd, F_SETFL, res) == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
+ }
+
+ IN_WRITE_END
}
void Inotify::SetCloseOnExec(bool fClOnEx) throw (InotifyException)
{
- IN_WRITE_BEGIN
-
- if (m_fd == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
- }
-
- int res = fcntl(m_fd, F_GETFD);
- if (res == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
- }
-
- if (fClOnEx) {
- res |= FD_CLOEXEC;
- }
- else {
- res &= ~FD_CLOEXEC;
- }
-
- if (fcntl(m_fd, F_SETFD, res) == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
- }
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ if (m_fd == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
+ }
+
+ int res = fcntl(m_fd, F_GETFD);
+ if (res == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
+ }
+
+ if (fClOnEx)
+ {
+ res |= FD_CLOEXEC;
+ }
+ else
+ {
+ res &= ~FD_CLOEXEC;
+ }
+
+ if (fcntl(m_fd, F_SETFD, res) == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
+ }
+
+ IN_WRITE_END
}
uint32_t Inotify::GetCapability(InotifyCapability_t cap) throw (InotifyException)
{
- FILE* f = fopen(GetCapabilityPath(cap).c_str(), "r");
- if (f == NULL)
- throw InotifyException(IN_EXC_MSG("cannot get capability"), errno, NULL);
-
- unsigned int val = 0;
- if (fscanf(f, "%u", &val) != 1) {
+ FILE* f = fopen(GetCapabilityPath(cap).c_str(), "r");
+ if (f == NULL)
+ throw InotifyException(IN_EXC_MSG("cannot get capability"), errno, NULL);
+
+ unsigned int val = 0;
+ if (fscanf(f, "%u", &val) != 1)
+ {
+ fclose(f);
+ throw InotifyException(IN_EXC_MSG("cannot get capability"), EIO, NULL);
+ }
+
fclose(f);
- throw InotifyException(IN_EXC_MSG("cannot get capability"), EIO, NULL);
- }
-
- fclose(f);
-
- return (uint32_t) val;
+
+ return (uint32_t) val;
}
void Inotify::SetCapability(InotifyCapability_t cap, uint32_t val) throw (InotifyException)
{
- FILE* f = fopen(GetCapabilityPath(cap).c_str(), "w");
- if (f == NULL)
- throw InotifyException(IN_EXC_MSG("cannot set capability"), errno, NULL);
-
- if (fprintf(f, "%u", (unsigned int) val) <= 0) {
+ FILE* f = fopen(GetCapabilityPath(cap).c_str(), "w");
+ if (f == NULL)
+ throw InotifyException(IN_EXC_MSG("cannot set capability"), errno, NULL);
+
+ if (fprintf(f, "%u", (unsigned int) val) <= 0)
+ {
+ fclose(f);
+ throw InotifyException(IN_EXC_MSG("cannot set capability"), EIO, NULL);
+ }
+
fclose(f);
- throw InotifyException(IN_EXC_MSG("cannot set capability"), EIO, NULL);
- }
-
- fclose(f);
}
std::string Inotify::GetCapabilityPath(InotifyCapability_t cap) throw (InotifyException)
{
- std::string path(PROCFS_INOTIFY_BASE);
-
- switch (cap) {
- case IN_MAX_EVENTS:
- path.append("max_queued_events");
- break;
- case IN_MAX_INSTANCES:
- path.append("max_user_instances");
- break;
- case IN_MAX_WATCHES:
- path.append("max_user_watches");
- break;
- default:
- throw InotifyException(IN_EXC_MSG("unknown capability type"), EINVAL, NULL);
- }
-
- return path;
+ std::string path(PROCFS_INOTIFY_BASE);
+
+ switch (cap)
+ {
+ case IN_MAX_EVENTS:
+ path.append("max_queued_events");
+ break;
+ case IN_MAX_INSTANCES:
+ path.append("max_user_instances");
+ break;
+ case IN_MAX_WATCHES:
+ path.append("max_user_watches");
+ break;
+ default:
+ throw InotifyException(IN_EXC_MSG("unknown capability type"), EINVAL, NULL);
+ }
+
+ return path;
}
bgstack15