summaryrefslogtreecommitdiff
path: root/shared/inotify/inotify-cxx.h
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:10:11 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:10:11 +0200
commitc0cdb2ad99a1e2a6ade5ce76c91177a79258e669 (patch)
tree4701a015385d9a6a5a4ba99a8f1f5d400fff26b1 /shared/inotify/inotify-cxx.h
parent3.13 (diff)
downloadFreeFileSync-c0cdb2ad99a1e2a6ade5ce76c91177a79258e669.tar.gz
FreeFileSync-c0cdb2ad99a1e2a6ade5ce76c91177a79258e669.tar.bz2
FreeFileSync-c0cdb2ad99a1e2a6ade5ce76c91177a79258e669.zip
3.14
Diffstat (limited to 'shared/inotify/inotify-cxx.h')
-rw-r--r--shared/inotify/inotify-cxx.h1375
1 files changed, 689 insertions, 686 deletions
diff --git a/shared/inotify/inotify-cxx.h b/shared/inotify/inotify-cxx.h
index 34ae2212..2fb00fc8 100644
--- a/shared/inotify/inotify-cxx.h
+++ b/shared/inotify/inotify-cxx.h
@@ -2,11 +2,11 @@
/// inotify C++ interface header
/**
* \file inotify-cxx.h
- *
+ *
* 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:
*
@@ -50,12 +50,12 @@
*/
#define IN_EXC_MSG(msg) (std::string(__PRETTY_FUNCTION__) + ": " + msg)
-/// inotify capability/limit identifiers
+/// inotify capability/limit identifiers
typedef enum
{
- IN_MAX_EVENTS = 0, ///< max. events in the kernel queue
- IN_MAX_INSTANCES = 1, ///< max. inotify file descriptors per process
- IN_MAX_WATCHES = 2 ///< max. watches per file descriptor
+ IN_MAX_EVENTS = 0, ///< max. events in the kernel queue
+ IN_MAX_INSTANCES = 1, ///< max. inotify file descriptors per process
+ IN_MAX_WATCHES = 2 ///< max. watches per file descriptor
} InotifyCapability_t;
/// inotify-cxx thread safety
@@ -63,16 +63,16 @@ typedef enum
* If this symbol is defined you can use this interface safely
* threaded applications. Remember that it slightly degrades
* performance.
- *
+ *
* Even if INOTIFY_THREAD_SAFE is defined some classes stay
* unsafe. If you must use them (must you?) in more than one
* thread concurrently you need to implement explicite locking.
- *
+ *
* You need not to define INOTIFY_THREAD_SAFE in that cases
* where the application is multithreaded but all the inotify
* infrastructure will be managed only in one thread. This is
* the recommended way.
- *
+ *
* Locking may fail (it is very rare but not impossible). In this
* case an exception is thrown. But if unlocking fails in case
* of an error it does nothing (this failure is ignored).
@@ -95,7 +95,7 @@ typedef enum
throw InotifyException(IN_EXC_MSG("cannot initialize lock"), res, this); \
pthread_rwlockattr_destroy(&attr); \
}
-
+
#define IN_LOCK_DONE pthread_rwlock_destroy(&__m_lock);
#define IN_READ_BEGIN \
@@ -104,23 +104,23 @@ typedef enum
if (res != 0) \
throw InotifyException(IN_EXC_MSG("locking for reading failed"), res, (void*) this); \
}
-
+
#define IN_READ_END \
{ \
int res = pthread_rwlock_unlock(&__m_lock); \
if (res != 0) \
throw InotifyException(IN_EXC_MSG("unlocking failed"), res, (void*) this); \
}
-
+
#define IN_READ_END_NOTHROW pthread_rwlock_unlock(&__m_lock);
-
+
#define IN_WRITE_BEGIN \
{ \
int res = pthread_rwlock_wrlock(&__m_lock); \
if (res != 0) \
throw InotifyException(IN_EXC_MSG("locking for writing failed"), res, (void*) this); \
}
-
+
#define IN_WRITE_END IN_READ_END
#define IN_WRITE_END_NOTHROW IN_READ_END_NOTHROW
@@ -151,59 +151,59 @@ class Inotify;
* This class allows to acquire information about exceptional
* events. It makes easier to log or display error messages
* and to identify problematic code locations.
- *
+ *
* Although this class is basically thread-safe it is not intended
* to be shared between threads.
*/
class InotifyException
{
public:
- /// Constructor
- /**
- * \param[in] rMsg message
- * \param[in] iErr error number (see errno.h)
- * \param[in] pSrc source
- */
- InotifyException(const std::string& rMsg = "", int iErr = 0, void* pSrc = NULL)
- : m_msg(rMsg),
- m_err(iErr)
- {
- m_pSrc = pSrc;
- }
-
- /// Returns the exception message.
- /**
- * \return message
- */
- inline const std::string& GetMessage() const
- {
- return m_msg;
- }
-
- /// Returns the exception error number.
- /**
- * If not applicable this value is 0 (zero).
- *
- * \return error number (standardized; see errno.h)
- */
- inline int GetErrorNumber() const
- {
- return m_err;
- }
-
- /// Returns the exception source.
- /**
- * \return source
- */
- inline void* GetSource() const
- {
- return m_pSrc;
- }
+ /// Constructor
+ /**
+ * \param[in] rMsg message
+ * \param[in] iErr error number (see errno.h)
+ * \param[in] pSrc source
+ */
+ InotifyException(const std::string& rMsg = "", int iErr = 0, void* pSrc = NULL)
+ : m_msg(rMsg),
+ m_err(iErr)
+ {
+ m_pSrc = pSrc;
+ }
+
+ /// Returns the exception message.
+ /**
+ * \return message
+ */
+ inline const std::string& GetMessage() const
+ {
+ return m_msg;
+ }
+
+ /// Returns the exception error number.
+ /**
+ * If not applicable this value is 0 (zero).
+ *
+ * \return error number (standardized; see errno.h)
+ */
+ inline int GetErrorNumber() const
+ {
+ return m_err;
+ }
+
+ /// Returns the exception source.
+ /**
+ * \return source
+ */
+ inline void* GetSource() const
+ {
+ return m_pSrc;
+ }
protected:
- std::string m_msg; ///< message
- int m_err; ///< error number
- mutable void* m_pSrc; ///< source
+ std::string m_msg; ///< message
+ int m_err; ///< error number
+ mutable void* m_pSrc; ///< source
};
@@ -211,7 +211,7 @@ protected:
/**
* It holds all information about inotify event and provides
* access to its particular values.
- *
+ *
* This class is not (and is not intended to be) thread-safe
* and therefore it must not be used concurrently in multiple
* threads.
@@ -219,157 +219,160 @@ protected:
class InotifyEvent
{
public:
- /// Constructor.
- /**
- * Creates a plain event.
- */
- InotifyEvent()
- : m_uMask(0),
- m_uCookie(0)
- {
- m_pWatch = NULL;
- }
-
- /// Constructor.
- /**
- * Creates an event based on inotify event data.
- * For NULL pointers it works the same way as InotifyEvent().
- *
- * \param[in] pEvt event data
- * \param[in] pWatch inotify watch
- */
- InotifyEvent(const struct inotify_event* pEvt, InotifyWatch* pWatch)
- : m_uMask(0),
- m_uCookie(0)
- {
- if (pEvt != NULL) {
- m_uMask = (uint32_t) pEvt->mask;
- m_uCookie = (uint32_t) pEvt->cookie;
- if (pEvt->name != NULL) {
- m_name = pEvt->len > 0
- ? pEvt->name
- : "";
- }
- m_pWatch = pWatch;
- }
- else {
- m_pWatch = NULL;
+ /// Constructor.
+ /**
+ * Creates a plain event.
+ */
+ InotifyEvent()
+ : m_uMask(0),
+ m_uCookie(0)
+ {
+ m_pWatch = NULL;
}
- }
-
- /// Destructor.
- ~InotifyEvent() {}
-
- /// Returns the event watch descriptor.
- /**
- * \return watch descriptor
- *
- * \sa InotifyWatch::GetDescriptor()
- */
- int32_t GetDescriptor() const;
-
- /// Returns the event mask.
- /**
- * \return event mask
- *
- * \sa InotifyWatch::GetMask()
- */
- inline uint32_t GetMask() const
- {
- return m_uMask;
- }
-
- /// Checks a value for the event type.
- /**
- * \param[in] uValue checked value
- * \param[in] uType type which is checked for
- * \return true = the value contains the given type, false = otherwise
- */
- inline static bool IsType(uint32_t uValue, uint32_t uType)
- {
- return ((uValue & uType) != 0) && ((~uValue & uType) == 0);
- }
-
- /// Checks for the event type.
- /**
- * \param[in] uType type which is checked for
- * \return true = event mask contains the given type, false = otherwise
- */
- inline bool IsType(uint32_t uType) const
- {
- return IsType(m_uMask, uType);
- }
-
- /// Returns the event cookie.
- /**
- * \return event cookie
- */
- inline uint32_t GetCookie() const
- {
- return m_uCookie;
- }
-
- /// Returns the event name length.
- /**
- * \return event name length
- */
- inline uint32_t GetLength() const
- {
- return (uint32_t) m_name.length();
- }
-
- /// Returns the event name.
- /**
- * \return event name
- */
- inline const std::string& GetName() const
- {
- return m_name;
- }
-
- /// Extracts the event name.
- /**
- * \param[out] rName event name
- */
- inline void GetName(std::string& rName) const
- {
- rName = GetName();
- }
-
- /// Returns the source watch.
- /**
- * \return source watch
- */
- inline InotifyWatch* GetWatch()
- {
- return m_pWatch;
- }
-
- /// Finds the appropriate mask for a name.
- /**
- * \param[in] rName mask name
- * \return mask for name; 0 on failure
- */
- static uint32_t GetMaskByName(const std::string& rName);
-
- /// Fills the string with all types contained in an event mask value.
- /**
- * \param[in] uValue event mask value
- * \param[out] rStr dumped event types
- */
- static void DumpTypes(uint32_t uValue, std::string& rStr);
-
- /// Fills the string with all types contained in the event mask.
- /**
- * \param[out] rStr dumped event types
- */
- void DumpTypes(std::string& rStr) const;
-
+
+ /// Constructor.
+ /**
+ * Creates an event based on inotify event data.
+ * For NULL pointers it works the same way as InotifyEvent().
+ *
+ * \param[in] pEvt event data
+ * \param[in] pWatch inotify watch
+ */
+ InotifyEvent(const struct inotify_event* pEvt, InotifyWatch* pWatch)
+ : m_uMask(0),
+ m_uCookie(0)
+ {
+ if (pEvt != NULL)
+ {
+ m_uMask = (uint32_t) pEvt->mask;
+ m_uCookie = (uint32_t) pEvt->cookie;
+ if (pEvt->name != NULL)
+ {
+ m_name = pEvt->len > 0
+ ? pEvt->name
+ : "";
+ }
+ m_pWatch = pWatch;
+ }
+ else
+ {
+ m_pWatch = NULL;
+ }
+ }
+
+ /// Destructor.
+ ~InotifyEvent() {}
+
+ /// Returns the event watch descriptor.
+ /**
+ * \return watch descriptor
+ *
+ * \sa InotifyWatch::GetDescriptor()
+ */
+ int32_t GetDescriptor() const;
+
+ /// Returns the event mask.
+ /**
+ * \return event mask
+ *
+ * \sa InotifyWatch::GetMask()
+ */
+ inline uint32_t GetMask() const
+ {
+ return m_uMask;
+ }
+
+ /// Checks a value for the event type.
+ /**
+ * \param[in] uValue checked value
+ * \param[in] uType type which is checked for
+ * \return true = the value contains the given type, false = otherwise
+ */
+ inline static bool IsType(uint32_t uValue, uint32_t uType)
+ {
+ return ((uValue & uType) != 0) && ((~uValue & uType) == 0);
+ }
+
+ /// Checks for the event type.
+ /**
+ * \param[in] uType type which is checked for
+ * \return true = event mask contains the given type, false = otherwise
+ */
+ inline bool IsType(uint32_t uType) const
+ {
+ return IsType(m_uMask, uType);
+ }
+
+ /// Returns the event cookie.
+ /**
+ * \return event cookie
+ */
+ inline uint32_t GetCookie() const
+ {
+ return m_uCookie;
+ }
+
+ /// Returns the event name length.
+ /**
+ * \return event name length
+ */
+ inline uint32_t GetLength() const
+ {
+ return (uint32_t) m_name.length();
+ }
+
+ /// Returns the event name.
+ /**
+ * \return event name
+ */
+ inline const std::string& GetName() const
+ {
+ return m_name;
+ }
+
+ /// Extracts the event name.
+ /**
+ * \param[out] rName event name
+ */
+ inline void GetName(std::string& rName) const
+ {
+ rName = GetName();
+ }
+
+ /// Returns the source watch.
+ /**
+ * \return source watch
+ */
+ inline InotifyWatch* GetWatch()
+ {
+ return m_pWatch;
+ }
+
+ /// Finds the appropriate mask for a name.
+ /**
+ * \param[in] rName mask name
+ * \return mask for name; 0 on failure
+ */
+ static uint32_t GetMaskByName(const std::string& rName);
+
+ /// Fills the string with all types contained in an event mask value.
+ /**
+ * \param[in] uValue event mask value
+ * \param[out] rStr dumped event types
+ */
+ static void DumpTypes(uint32_t uValue, std::string& rStr);
+
+ /// Fills the string with all types contained in the event mask.
+ /**
+ * \param[out] rStr dumped event types
+ */
+ void DumpTypes(std::string& rStr) const;
+
private:
- uint32_t m_uMask; ///< mask
- uint32_t m_uCookie; ///< cookie
- std::string m_name; ///< name
- InotifyWatch* m_pWatch; ///< source watch
+ uint32_t m_uMask; ///< mask
+ uint32_t m_uCookie; ///< cookie
+ std::string m_name; ///< name
+ InotifyWatch* m_pWatch; ///< source watch
};
@@ -378,140 +381,140 @@ private:
/**
* It holds information about the inotify watch on a particular
* inode.
- *
+ *
* If the INOTIFY_THREAD_SAFE is defined this class is thread-safe.
*/
class InotifyWatch
{
public:
- /// Constructor.
- /**
- * Creates an inotify watch. Because this watch is
- * inactive it has an invalid descriptor (-1).
- *
- * \param[in] rPath watched file path
- * \param[in] uMask mask for events
- * \param[in] fEnabled events enabled yes/no
- */
- InotifyWatch(const std::string& rPath, int32_t uMask, bool fEnabled = true)
- : m_path(rPath),
- m_uMask(uMask),
- m_wd((int32_t) -1),
- m_fEnabled(fEnabled)
- {
- IN_LOCK_INIT
- }
-
- /// Destructor.
- ~InotifyWatch()
- {
- IN_LOCK_DONE
- }
-
- /// Returns the watch descriptor.
- /**
- * \return watch descriptor; -1 for inactive watch
- */
- inline int32_t GetDescriptor() const
- {
- return m_wd;
- }
-
- /// Returns the watched file path.
- /**
- * \return file path
- */
- inline const std::string& GetPath() const
- {
- return m_path;
- }
-
- /// Returns the watch event mask.
- /**
- * \return event mask
- */
- inline uint32_t GetMask() const
- {
- return (uint32_t) m_uMask;
- }
-
- /// Sets the watch event mask.
- /**
- * If the watch is active (added to an instance of Inotify)
- * this method may fail due to unsuccessful re-setting
- * the watch in the kernel.
- *
- * \param[in] uMask event mask
- *
- * \throw InotifyException thrown if changing fails
- */
- void SetMask(uint32_t uMask) throw (InotifyException);
-
- /// Returns the appropriate inotify class instance.
- /**
- * \return inotify instance
- */
- inline Inotify* GetInotify()
- {
- return m_pInotify;
- }
-
- /// Enables/disables the watch.
- /**
- * If the watch is active (added to an instance of Inotify)
- * this method may fail due to unsuccessful re-setting
- * the watch in the kernel.
- *
- * Re-setting the current state has no effect.
- *
- * \param[in] fEnabled set enabled yes/no
- *
- * \throw InotifyException thrown if enabling/disabling fails
- */
- void SetEnabled(bool fEnabled) throw (InotifyException);
-
- /// Checks whether the watch is enabled.
- /**
- * \return true = enables, false = disabled
- */
- inline bool IsEnabled() const
- {
- return m_fEnabled;
- }
-
- /// Checks whether the watch is recursive.
- /**
- * A recursive watch monitors a directory itself and all
- * its subdirectories. This watch is a logical object
- * which may have many underlying kernel watches.
- *
- * \return currently always false (recursive watches not yet supported)
- * \attention Recursive watches are currently NOT supported.
- * They are planned for future versions.
- */
- inline bool IsRecursive() const
- {
- return false;
- }
-
+ /// Constructor.
+ /**
+ * Creates an inotify watch. Because this watch is
+ * inactive it has an invalid descriptor (-1).
+ *
+ * \param[in] rPath watched file path
+ * \param[in] uMask mask for events
+ * \param[in] fEnabled events enabled yes/no
+ */
+ InotifyWatch(const std::string& rPath, int32_t uMask, bool fEnabled = true)
+ : m_path(rPath),
+ m_uMask(uMask),
+ m_wd((int32_t) -1),
+ m_fEnabled(fEnabled)
+ {
+ IN_LOCK_INIT
+ }
+
+ /// Destructor.
+ ~InotifyWatch()
+ {
+ IN_LOCK_DONE
+ }
+
+ /// Returns the watch descriptor.
+ /**
+ * \return watch descriptor; -1 for inactive watch
+ */
+ inline int32_t GetDescriptor() const
+ {
+ return m_wd;
+ }
+
+ /// Returns the watched file path.
+ /**
+ * \return file path
+ */
+ inline const std::string& GetPath() const
+ {
+ return m_path;
+ }
+
+ /// Returns the watch event mask.
+ /**
+ * \return event mask
+ */
+ inline uint32_t GetMask() const
+ {
+ return (uint32_t) m_uMask;
+ }
+
+ /// Sets the watch event mask.
+ /**
+ * If the watch is active (added to an instance of Inotify)
+ * this method may fail due to unsuccessful re-setting
+ * the watch in the kernel.
+ *
+ * \param[in] uMask event mask
+ *
+ * \throw InotifyException thrown if changing fails
+ */
+ void SetMask(uint32_t uMask) throw (InotifyException);
+
+ /// Returns the appropriate inotify class instance.
+ /**
+ * \return inotify instance
+ */
+ inline Inotify* GetInotify()
+ {
+ return m_pInotify;
+ }
+
+ /// Enables/disables the watch.
+ /**
+ * If the watch is active (added to an instance of Inotify)
+ * this method may fail due to unsuccessful re-setting
+ * the watch in the kernel.
+ *
+ * Re-setting the current state has no effect.
+ *
+ * \param[in] fEnabled set enabled yes/no
+ *
+ * \throw InotifyException thrown if enabling/disabling fails
+ */
+ void SetEnabled(bool fEnabled) throw (InotifyException);
+
+ /// Checks whether the watch is enabled.
+ /**
+ * \return true = enables, false = disabled
+ */
+ inline bool IsEnabled() const
+ {
+ return m_fEnabled;
+ }
+
+ /// Checks whether the watch is recursive.
+ /**
+ * A recursive watch monitors a directory itself and all
+ * its subdirectories. This watch is a logical object
+ * which may have many underlying kernel watches.
+ *
+ * \return currently always false (recursive watches not yet supported)
+ * \attention Recursive watches are currently NOT supported.
+ * They are planned for future versions.
+ */
+ inline bool IsRecursive() const
+ {
+ return false;
+ }
+
private:
- friend class Inotify;
-
- std::string m_path; ///< watched file path
- uint32_t m_uMask; ///< event mask
- int32_t m_wd; ///< watch descriptor
- Inotify* m_pInotify; ///< inotify object
- bool m_fEnabled; ///< events enabled yes/no
-
- IN_LOCK_DECL
-
- /// Disables the watch (due to removing by the kernel).
- /**
- * This method must be called after receiving an event.
- * It ensures the watch object is consistent with the kernel
- * data.
- */
- void __Disable();
+ friend class Inotify;
+
+ std::string m_path; ///< watched file path
+ uint32_t m_uMask; ///< event mask
+ int32_t m_wd; ///< watch descriptor
+ Inotify* m_pInotify; ///< inotify object
+ bool m_fEnabled; ///< events enabled yes/no
+
+ IN_LOCK_DECL
+
+ /// Disables the watch (due to removing by the kernel).
+ /**
+ * This method must be called after receiving an event.
+ * It ensures the watch object is consistent with the kernel
+ * data.
+ */
+ void __Disable();
};
@@ -526,360 +529,360 @@ typedef std::map<std::string, InotifyWatch*> IN_WP_MAP;
/**
* It holds information about the inotify device descriptor
* and manages the event queue.
- *
+ *
* If the INOTIFY_THREAD_SAFE is defined this class is thread-safe.
*/
class Inotify
{
public:
- /// Constructor.
- /**
- * Creates and initializes an instance of inotify communication
- * object (opens the inotify device).
- *
- * \throw InotifyException thrown if inotify isn't available
- */
- Inotify() throw (InotifyException);
-
- /// Destructor.
- /**
- * Calls Close() due to clean-up.
- */
- ~Inotify();
-
- /// Removes all watches and closes the inotify device.
- void Close();
-
- /// Adds a new watch.
- /**
- * \param[in] pWatch inotify watch
- *
- * \throw InotifyException thrown if adding failed
- */
- void Add(InotifyWatch* pWatch) throw (InotifyException);
-
- /// Adds a new watch.
- /**
- * \param[in] rWatch inotify watch
- *
- * \throw InotifyException thrown if adding failed
- */
- inline void Add(InotifyWatch& rWatch) throw (InotifyException)
- {
- Add(&rWatch);
- }
-
- /// Removes a watch.
- /**
- * If the given watch is not present it does nothing.
- *
- * \param[in] pWatch inotify watch
- *
- * \throw InotifyException thrown if removing failed
- */
- void Remove(InotifyWatch* pWatch) throw (InotifyException);
-
- /// Removes a watch.
- /**
- * If the given watch is not present it does nothing.
- *
- * \param[in] rWatch inotify watch
- *
- * \throw InotifyException thrown if removing failed
- */
- inline void Remove(InotifyWatch& rWatch) throw (InotifyException)
- {
- Remove(&rWatch);
- }
-
- /// Removes all watches.
- void RemoveAll();
-
- /// Returns the count of watches.
- /**
- * This is the total count of all watches (regardless whether
- * enabled or not).
- *
- * \return count of watches
- *
- * \sa GetEnabledCount()
- */
- inline size_t GetWatchCount() const
- {
- IN_READ_BEGIN
- size_t n = (size_t) m_paths.size();
- IN_READ_END
- return n;
- }
-
- /// Returns the count of enabled watches.
- /**
- * \return count of enabled watches
- *
- * \sa GetWatchCount()
- */
- inline size_t GetEnabledCount() const
- {
- IN_READ_BEGIN
- size_t n = (size_t) m_watches.size();
- IN_READ_END
- return n;
- }
-
- /// Waits for inotify events.
- /**
- * It waits until one or more events occur. When called
- * in nonblocking mode it only retrieves occurred events
- * to the internal queue and exits.
- *
- * \param[in] fNoIntr if true it re-calls the system call after a handled signal
- *
- * \throw InotifyException thrown if reading events failed
- *
- * \sa SetNonBlock()
- */
- void WaitForEvents(bool fNoIntr = false) throw (InotifyException);
-
- /// Returns the count of received and queued events.
- /**
- * This number is related to the events in the queue inside
- * this object, not to the events pending in the kernel.
- *
- * \return count of events
- */
- inline size_t GetEventCount()
- {
- IN_READ_BEGIN
- size_t n = (size_t) m_events.size();
- IN_READ_END
- return n;
- }
-
- /// Extracts a queued inotify event.
- /**
- * The extracted event is removed from the queue.
- * If the pointer is NULL it does nothing.
- *
- * \param[in,out] pEvt event object
- *
- * \throw InotifyException thrown if the provided pointer is NULL
- */
- bool GetEvent(InotifyEvent* pEvt) throw (InotifyException);
-
- /// Extracts a queued inotify event.
- /**
- * The extracted event is removed from the queue.
- *
- * \param[in,out] rEvt event object
- *
- * \throw InotifyException thrown only in very anomalous cases
- */
- bool GetEvent(InotifyEvent& rEvt) throw (InotifyException)
- {
- return GetEvent(&rEvt);
- }
-
- /// Extracts a queued inotify event (without removing).
- /**
- * The extracted event stays in the queue.
- * If the pointer is NULL it does nothing.
- *
- * \param[in,out] pEvt event object
- *
- * \throw InotifyException thrown if the provided pointer is NULL
- */
- bool PeekEvent(InotifyEvent* pEvt) throw (InotifyException);
-
- /// Extracts a queued inotify event (without removing).
- /**
- * The extracted event stays in the queue.
- *
- * \param[in,out] rEvt event object
- *
- * \throw InotifyException thrown only in very anomalous cases
- */
- bool PeekEvent(InotifyEvent& rEvt) throw (InotifyException)
- {
- return PeekEvent(&rEvt);
- }
-
- /// Searches for a watch by a watch descriptor.
- /**
- * It tries to find a watch by the given descriptor.
- *
- * \param[in] iDescriptor watch descriptor
- * \return pointer to a watch; NULL if no such watch exists
- */
- InotifyWatch* FindWatch(int iDescriptor);
-
- /// Searches for a watch by a filesystem path.
- /**
- * It tries to find a watch by the given filesystem path.
- *
- * \param[in] rPath filesystem path
- * \return pointer to a watch; NULL if no such watch exists
- *
- * \attention The path must be exactly identical to the one
- * used for the searched watch. Be careful about
- * absolute/relative and case-insensitive paths.
- */
- InotifyWatch* FindWatch(const std::string& rPath);
-
- /// Returns the file descriptor.
- /**
- * The descriptor can be used in standard low-level file
- * functions (poll(), select(), fcntl() etc.).
- *
- * \return valid file descriptor or -1 for inactive object
- *
- * \sa SetNonBlock()
- */
- inline int GetDescriptor() const
- {
- return m_fd;
- }
-
- /// Enables/disables non-blocking mode.
- /**
- * Use this mode if you want to monitor the descriptor
- * (acquired thru GetDescriptor()) in functions such as
- * poll(), select() etc.
- *
- * Non-blocking mode is disabled by default.
- *
- * \param[in] fNonBlock enable/disable non-blocking mode
- *
- * \throw InotifyException thrown if setting mode failed
- *
- * \sa GetDescriptor(), SetCloseOnExec()
- */
- void SetNonBlock(bool fNonBlock) throw (InotifyException);
-
- /// Enables/disables closing on exec.
- /**
- * Enable this if you want to close the descriptor when
- * executing another program. Otherwise, the descriptor
- * will be inherited.
- *
- * Closing on exec is disabled by default.
- *
- * \param[in] fClOnEx enable/disable closing on exec
- *
- * \throw InotifyException thrown if setting failed
- *
- * \sa GetDescriptor(), SetNonBlock()
- */
- void SetCloseOnExec(bool fClOnEx) throw (InotifyException);
-
- /// Acquires a particular inotify capability/limit.
- /**
- * \param[in] cap capability/limit identifier
- * \return capability/limit value
- * \throw InotifyException thrown if the given value cannot be acquired
- */
- static uint32_t GetCapability(InotifyCapability_t cap) throw (InotifyException);
-
- /// Modifies a particular inotify capability/limit.
- /**
- * \param[in] cap capability/limit identifier
- * \param[in] val new capability/limit value
- * \throw InotifyException thrown if the given value cannot be set
- * \attention Using this function requires root privileges.
- * Beware of setting extensive values - it may seriously
- * affect system performance and/or stability.
- */
- static void SetCapability(InotifyCapability_t cap, uint32_t val) throw (InotifyException);
-
- /// Returns the maximum number of events in the kernel queue.
- /**
- * \return maximum number of events in the kernel queue
- * \throw InotifyException thrown if the given value cannot be acquired
- */
- inline static uint32_t GetMaxEvents() throw (InotifyException)
- {
- return GetCapability(IN_MAX_EVENTS);
- }
-
- /// Sets the maximum number of events in the kernel queue.
- /**
- * \param[in] val new value
- * \throw InotifyException thrown if the given value cannot be set
- * \attention Using this function requires root privileges.
- * Beware of setting extensive values - the greater value
- * is set here the more physical memory may be used for the inotify
- * infrastructure.
- */
- inline static void SetMaxEvents(uint32_t val) throw (InotifyException)
- {
- SetCapability(IN_MAX_EVENTS, val);
- }
-
- /// Returns the maximum number of inotify instances per process.
- /**
- * It means the maximum number of open inotify file descriptors
- * per running process.
- *
- * \return maximum number of inotify instances
- * \throw InotifyException thrown if the given value cannot be acquired
- */
- inline static uint32_t GetMaxInstances() throw (InotifyException)
- {
- return GetCapability(IN_MAX_INSTANCES);
- }
-
- /// Sets the maximum number of inotify instances per process.
- /**
- * \param[in] val new value
- * \throw InotifyException thrown if the given value cannot be set
- * \attention Using this function requires root privileges.
- * Beware of setting extensive values - the greater value
- * is set here the more physical memory may be used for the inotify
- * infrastructure.
- */
- inline static void SetMaxInstances(uint32_t val) throw (InotifyException)
- {
- SetCapability(IN_MAX_INSTANCES, val);
- }
-
- /// Returns the maximum number of inotify watches per instance.
- /**
- * It means the maximum number of inotify watches per inotify
- * file descriptor.
- *
- * \return maximum number of inotify watches
- * \throw InotifyException thrown if the given value cannot be acquired
- */
- inline static uint32_t GetMaxWatches() throw (InotifyException)
- {
- return GetCapability(IN_MAX_WATCHES);
- }
-
- /// Sets the maximum number of inotify watches per instance.
- /**
- * \param[in] val new value
- * \throw InotifyException thrown if the given value cannot be set
- * \attention Using this function requires root privileges.
- * Beware of setting extensive values - the greater value
- * is set here the more physical memory may be used for the inotify
- * infrastructure.
- */
- inline static void SetMaxWatches(uint32_t val) throw (InotifyException)
- {
- SetCapability(IN_MAX_WATCHES, val);
- }
+ /// Constructor.
+ /**
+ * Creates and initializes an instance of inotify communication
+ * object (opens the inotify device).
+ *
+ * \throw InotifyException thrown if inotify isn't available
+ */
+ Inotify() throw (InotifyException);
+
+ /// Destructor.
+ /**
+ * Calls Close() due to clean-up.
+ */
+ ~Inotify();
+
+ /// Removes all watches and closes the inotify device.
+ void Close();
+
+ /// Adds a new watch.
+ /**
+ * \param[in] pWatch inotify watch
+ *
+ * \throw InotifyException thrown if adding failed
+ */
+ void Add(InotifyWatch* pWatch) throw (InotifyException);
+
+ /// Adds a new watch.
+ /**
+ * \param[in] rWatch inotify watch
+ *
+ * \throw InotifyException thrown if adding failed
+ */
+ inline void Add(InotifyWatch& rWatch) throw (InotifyException)
+ {
+ Add(&rWatch);
+ }
+
+ /// Removes a watch.
+ /**
+ * If the given watch is not present it does nothing.
+ *
+ * \param[in] pWatch inotify watch
+ *
+ * \throw InotifyException thrown if removing failed
+ */
+ void Remove(InotifyWatch* pWatch) throw (InotifyException);
+
+ /// Removes a watch.
+ /**
+ * If the given watch is not present it does nothing.
+ *
+ * \param[in] rWatch inotify watch
+ *
+ * \throw InotifyException thrown if removing failed
+ */
+ inline void Remove(InotifyWatch& rWatch) throw (InotifyException)
+ {
+ Remove(&rWatch);
+ }
+
+ /// Removes all watches.
+ void RemoveAll();
+
+ /// Returns the count of watches.
+ /**
+ * This is the total count of all watches (regardless whether
+ * enabled or not).
+ *
+ * \return count of watches
+ *
+ * \sa GetEnabledCount()
+ */
+ inline size_t GetWatchCount() const
+ {
+ IN_READ_BEGIN
+ size_t n = (size_t) m_paths.size();
+ IN_READ_END
+ return n;
+ }
+
+ /// Returns the count of enabled watches.
+ /**
+ * \return count of enabled watches
+ *
+ * \sa GetWatchCount()
+ */
+ inline size_t GetEnabledCount() const
+ {
+ IN_READ_BEGIN
+ size_t n = (size_t) m_watches.size();
+ IN_READ_END
+ return n;
+ }
+
+ /// Waits for inotify events.
+ /**
+ * It waits until one or more events occur. When called
+ * in nonblocking mode it only retrieves occurred events
+ * to the internal queue and exits.
+ *
+ * \param[in] fNoIntr if true it re-calls the system call after a handled signal
+ *
+ * \throw InotifyException thrown if reading events failed
+ *
+ * \sa SetNonBlock()
+ */
+ void WaitForEvents(bool fNoIntr = false) throw (InotifyException);
+
+ /// Returns the count of received and queued events.
+ /**
+ * This number is related to the events in the queue inside
+ * this object, not to the events pending in the kernel.
+ *
+ * \return count of events
+ */
+ inline size_t GetEventCount()
+ {
+ IN_READ_BEGIN
+ size_t n = (size_t) m_events.size();
+ IN_READ_END
+ return n;
+ }
+
+ /// Extracts a queued inotify event.
+ /**
+ * The extracted event is removed from the queue.
+ * If the pointer is NULL it does nothing.
+ *
+ * \param[in,out] pEvt event object
+ *
+ * \throw InotifyException thrown if the provided pointer is NULL
+ */
+ bool GetEvent(InotifyEvent* pEvt) throw (InotifyException);
+
+ /// Extracts a queued inotify event.
+ /**
+ * The extracted event is removed from the queue.
+ *
+ * \param[in,out] rEvt event object
+ *
+ * \throw InotifyException thrown only in very anomalous cases
+ */
+ bool GetEvent(InotifyEvent& rEvt) throw (InotifyException)
+ {
+ return GetEvent(&rEvt);
+ }
+
+ /// Extracts a queued inotify event (without removing).
+ /**
+ * The extracted event stays in the queue.
+ * If the pointer is NULL it does nothing.
+ *
+ * \param[in,out] pEvt event object
+ *
+ * \throw InotifyException thrown if the provided pointer is NULL
+ */
+ bool PeekEvent(InotifyEvent* pEvt) throw (InotifyException);
+
+ /// Extracts a queued inotify event (without removing).
+ /**
+ * The extracted event stays in the queue.
+ *
+ * \param[in,out] rEvt event object
+ *
+ * \throw InotifyException thrown only in very anomalous cases
+ */
+ bool PeekEvent(InotifyEvent& rEvt) throw (InotifyException)
+ {
+ return PeekEvent(&rEvt);
+ }
+
+ /// Searches for a watch by a watch descriptor.
+ /**
+ * It tries to find a watch by the given descriptor.
+ *
+ * \param[in] iDescriptor watch descriptor
+ * \return pointer to a watch; NULL if no such watch exists
+ */
+ InotifyWatch* FindWatch(int iDescriptor);
+
+ /// Searches for a watch by a filesystem path.
+ /**
+ * It tries to find a watch by the given filesystem path.
+ *
+ * \param[in] rPath filesystem path
+ * \return pointer to a watch; NULL if no such watch exists
+ *
+ * \attention The path must be exactly identical to the one
+ * used for the searched watch. Be careful about
+ * absolute/relative and case-insensitive paths.
+ */
+ InotifyWatch* FindWatch(const std::string& rPath);
+
+ /// Returns the file descriptor.
+ /**
+ * The descriptor can be used in standard low-level file
+ * functions (poll(), select(), fcntl() etc.).
+ *
+ * \return valid file descriptor or -1 for inactive object
+ *
+ * \sa SetNonBlock()
+ */
+ inline int GetDescriptor() const
+ {
+ return m_fd;
+ }
+
+ /// Enables/disables non-blocking mode.
+ /**
+ * Use this mode if you want to monitor the descriptor
+ * (acquired thru GetDescriptor()) in functions such as
+ * poll(), select() etc.
+ *
+ * Non-blocking mode is disabled by default.
+ *
+ * \param[in] fNonBlock enable/disable non-blocking mode
+ *
+ * \throw InotifyException thrown if setting mode failed
+ *
+ * \sa GetDescriptor(), SetCloseOnExec()
+ */
+ void SetNonBlock(bool fNonBlock) throw (InotifyException);
+
+ /// Enables/disables closing on exec.
+ /**
+ * Enable this if you want to close the descriptor when
+ * executing another program. Otherwise, the descriptor
+ * will be inherited.
+ *
+ * Closing on exec is disabled by default.
+ *
+ * \param[in] fClOnEx enable/disable closing on exec
+ *
+ * \throw InotifyException thrown if setting failed
+ *
+ * \sa GetDescriptor(), SetNonBlock()
+ */
+ void SetCloseOnExec(bool fClOnEx) throw (InotifyException);
+
+ /// Acquires a particular inotify capability/limit.
+ /**
+ * \param[in] cap capability/limit identifier
+ * \return capability/limit value
+ * \throw InotifyException thrown if the given value cannot be acquired
+ */
+ static uint32_t GetCapability(InotifyCapability_t cap) throw (InotifyException);
+
+ /// Modifies a particular inotify capability/limit.
+ /**
+ * \param[in] cap capability/limit identifier
+ * \param[in] val new capability/limit value
+ * \throw InotifyException thrown if the given value cannot be set
+ * \attention Using this function requires root privileges.
+ * Beware of setting extensive values - it may seriously
+ * affect system performance and/or stability.
+ */
+ static void SetCapability(InotifyCapability_t cap, uint32_t val) throw (InotifyException);
+
+ /// Returns the maximum number of events in the kernel queue.
+ /**
+ * \return maximum number of events in the kernel queue
+ * \throw InotifyException thrown if the given value cannot be acquired
+ */
+ inline static uint32_t GetMaxEvents() throw (InotifyException)
+ {
+ return GetCapability(IN_MAX_EVENTS);
+ }
+
+ /// Sets the maximum number of events in the kernel queue.
+ /**
+ * \param[in] val new value
+ * \throw InotifyException thrown if the given value cannot be set
+ * \attention Using this function requires root privileges.
+ * Beware of setting extensive values - the greater value
+ * is set here the more physical memory may be used for the inotify
+ * infrastructure.
+ */
+ inline static void SetMaxEvents(uint32_t val) throw (InotifyException)
+ {
+ SetCapability(IN_MAX_EVENTS, val);
+ }
+
+ /// Returns the maximum number of inotify instances per process.
+ /**
+ * It means the maximum number of open inotify file descriptors
+ * per running process.
+ *
+ * \return maximum number of inotify instances
+ * \throw InotifyException thrown if the given value cannot be acquired
+ */
+ inline static uint32_t GetMaxInstances() throw (InotifyException)
+ {
+ return GetCapability(IN_MAX_INSTANCES);
+ }
+
+ /// Sets the maximum number of inotify instances per process.
+ /**
+ * \param[in] val new value
+ * \throw InotifyException thrown if the given value cannot be set
+ * \attention Using this function requires root privileges.
+ * Beware of setting extensive values - the greater value
+ * is set here the more physical memory may be used for the inotify
+ * infrastructure.
+ */
+ inline static void SetMaxInstances(uint32_t val) throw (InotifyException)
+ {
+ SetCapability(IN_MAX_INSTANCES, val);
+ }
+
+ /// Returns the maximum number of inotify watches per instance.
+ /**
+ * It means the maximum number of inotify watches per inotify
+ * file descriptor.
+ *
+ * \return maximum number of inotify watches
+ * \throw InotifyException thrown if the given value cannot be acquired
+ */
+ inline static uint32_t GetMaxWatches() throw (InotifyException)
+ {
+ return GetCapability(IN_MAX_WATCHES);
+ }
+
+ /// Sets the maximum number of inotify watches per instance.
+ /**
+ * \param[in] val new value
+ * \throw InotifyException thrown if the given value cannot be set
+ * \attention Using this function requires root privileges.
+ * Beware of setting extensive values - the greater value
+ * is set here the more physical memory may be used for the inotify
+ * infrastructure.
+ */
+ inline static void SetMaxWatches(uint32_t val) throw (InotifyException)
+ {
+ SetCapability(IN_MAX_WATCHES, val);
+ }
+
+private:
+ int m_fd; ///< file descriptor
+ IN_WATCH_MAP m_watches; ///< watches (by descriptors)
+ IN_WP_MAP m_paths; ///< watches (by paths)
+ unsigned char m_buf[INOTIFY_BUFLEN]; ///< buffer for events
+ std::deque<InotifyEvent> m_events; ///< event queue
+
+ IN_LOCK_DECL
+
+ friend class InotifyWatch;
-private:
- int m_fd; ///< file descriptor
- IN_WATCH_MAP m_watches; ///< watches (by descriptors)
- IN_WP_MAP m_paths; ///< watches (by paths)
- unsigned char m_buf[INOTIFY_BUFLEN]; ///< buffer for events
- std::deque<InotifyEvent> m_events; ///< event queue
-
- IN_LOCK_DECL
-
- friend class InotifyWatch;
-
- static std::string GetCapabilityPath(InotifyCapability_t cap) throw (InotifyException);
+ static std::string GetCapabilityPath(InotifyCapability_t cap) throw (InotifyException);
};
bgstack15