From c0cdb2ad99a1e2a6ade5ce76c91177a79258e669 Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 18 Apr 2014 17:10:11 +0200 Subject: 3.14 --- shared/inotify/inotify-cxx.h | 1375 +++++++++++++++++++++--------------------- 1 file changed, 689 insertions(+), 686 deletions(-) (limited to 'shared/inotify/inotify-cxx.h') 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, - * + * * 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 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 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 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); }; -- cgit