00001
00003
00026 #ifndef _INOTIFYCXX_H_
00027 #define _INOTIFYCXX_H_
00028
00029 #include <string>
00030 #include <deque>
00031 #include <map>
00032
00033
00034 #include <sys/inotify.h>
00035
00036
00037 #ifndef __NR_inotify_init
00038 #include <sys/inotify-syscalls.h>
00039 #endif // __NR_inotify_init
00040
00042 #define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
00043
00045 #define INOTIFY_BUFLEN (1024 * (INOTIFY_EVENT_SIZE + 16))
00046
00048
00051 #define IN_EXC_MSG(msg) (std::string(__PRETTY_FUNCTION__) + ": " + msg)
00052
00053
00054
00055
00056 class InotifyWatch;
00057 class Inotify;
00058
00059
00061 class InotifyException
00062 {
00063 public:
00065
00070 InotifyException(const std::string& rMsg = "", int iErr = 0, void* pSrc = NULL)
00071 : m_msg(rMsg),
00072 m_err(iErr)
00073 {
00074 m_pSrc = pSrc;
00075 }
00076
00078
00081 inline const std::string& GetMessage() const
00082 {
00083 return m_msg;
00084 }
00085
00087
00092 inline int GetErrorNumber() const
00093 {
00094 return m_err;
00095 }
00096
00098
00101 inline void* GetSource() const
00102 {
00103 return m_pSrc;
00104 }
00105
00106 protected:
00107 std::string m_msg;
00108 int m_err;
00109 mutable void* m_pSrc;
00110 };
00111
00112
00114
00118 class InotifyEvent
00119 {
00120 public:
00122
00125 InotifyEvent()
00126 : m_uMask(0),
00127 m_uCookie(0)
00128 {
00129 m_pWatch = NULL;
00130 }
00131
00133
00140 InotifyEvent(const struct inotify_event* pEvt, InotifyWatch* pWatch)
00141 : m_uMask(0),
00142 m_uCookie(0)
00143 {
00144 if (pEvt != NULL) {
00145 m_uMask = (uint32_t) pEvt->mask;
00146 m_uCookie = (uint32_t) pEvt->cookie;
00147 if (pEvt->name != NULL)
00148 m_name = pEvt->name;
00149 m_pWatch = pWatch;
00150 }
00151 else {
00152 m_pWatch = NULL;
00153 }
00154 }
00155
00157 ~InotifyEvent() {}
00158
00160
00165 int32_t GetDescriptor() const;
00166
00168
00173 inline uint32_t GetMask() const
00174 {
00175 return m_uMask;
00176 }
00177
00179
00184 inline static bool IsType(uint32_t uValue, uint32_t uType)
00185 {
00186 return ((uValue & uType) != 0) && ((~uValue & uType) == 0);
00187 }
00188
00190
00194 inline bool IsType(uint32_t uType) const
00195 {
00196 return IsType(m_uMask, uType);
00197 }
00198
00200
00203 inline uint32_t GetCookie() const
00204 {
00205 return m_uCookie;
00206 }
00207
00209
00212 inline uint32_t GetLength() const
00213 {
00214 return (uint32_t) m_name.length();
00215 }
00216
00218
00221 inline const std::string& GetName() const
00222 {
00223 return m_name;
00224 }
00225
00227
00230 inline void GetName(std::string& rName) const
00231 {
00232 rName = GetName();
00233 }
00234
00236
00239 inline InotifyWatch* GetWatch()
00240 {
00241 return m_pWatch;
00242 }
00243
00245
00249 static uint32_t GetMaskByName(const std::string& rName);
00250
00252
00256 static void DumpTypes(uint32_t uValue, std::string& rStr);
00257
00259
00262 void DumpTypes(std::string& rStr) const;
00263
00264 private:
00265 uint32_t m_uMask;
00266 uint32_t m_uCookie;
00267 std::string m_name;
00268 InotifyWatch* m_pWatch;
00269 };
00270
00271
00272
00274 class InotifyWatch
00275 {
00276 public:
00278
00286 InotifyWatch(const std::string& rPath, int32_t uMask, bool fEnabled = true)
00287 : m_path(rPath),
00288 m_uMask(uMask),
00289 m_wd((int32_t) -1),
00290 m_fEnabled(fEnabled)
00291 {
00292
00293 }
00294
00296 ~InotifyWatch() {}
00297
00299
00302 inline int32_t GetDescriptor() const
00303 {
00304 return m_wd;
00305 }
00306
00308
00311 inline const std::string& GetPath() const
00312 {
00313 return m_path;
00314 }
00315
00317
00320 inline uint32_t GetMask() const
00321 {
00322 return (uint32_t) m_uMask;
00323 }
00324
00326
00335 void SetMask(uint32_t uMask) throw (InotifyException);
00336
00338
00341 inline Inotify* GetInotify()
00342 {
00343 return m_pInotify;
00344 }
00345
00347
00358 void SetEnabled(bool fEnabled) throw (InotifyException);
00359
00361
00364 inline bool IsEnabled() const
00365 {
00366 return m_fEnabled;
00367 }
00368
00369 private:
00370 friend class Inotify;
00371
00372 std::string m_path;
00373 uint32_t m_uMask;
00374 int32_t m_wd;
00375 Inotify* m_pInotify;
00376 bool m_fEnabled;
00377 };
00378
00379
00381 typedef std::map<int32_t, InotifyWatch*> IN_WATCH_MAP;
00382
00384 typedef std::map<std::string, InotifyWatch*> IN_WP_MAP;
00385
00386
00388 class Inotify
00389 {
00390 public:
00392
00398 Inotify() throw (InotifyException);
00399
00401
00404 ~Inotify();
00405
00407 void Close();
00408
00410
00415 void Add(InotifyWatch* pWatch) throw (InotifyException);
00416
00418
00423 inline void Add(InotifyWatch& rWatch) throw (InotifyException)
00424 {
00425 Add(&rWatch);
00426 }
00427
00429
00436 void Remove(InotifyWatch* pWatch) throw (InotifyException);
00437
00439
00446 inline void Remove(InotifyWatch& rWatch) throw (InotifyException)
00447 {
00448 Remove(&rWatch);
00449 }
00450
00452 void RemoveAll();
00453
00455
00458 inline size_t GetWatchCount() const
00459 {
00460 return (size_t) m_watches.size();
00461 }
00462
00464
00475 void WaitForEvents(bool fNoIntr = false) throw (InotifyException);
00476
00478
00484 int GetEventCount();
00485
00487
00495 bool GetEvent(InotifyEvent* pEvt) throw (InotifyException);
00496
00498
00505 bool GetEvent(InotifyEvent& rEvt) throw (InotifyException)
00506 {
00507 return GetEvent(&rEvt);
00508 }
00509
00511
00519 bool PeekEvent(InotifyEvent* pEvt) throw (InotifyException);
00520
00522
00529 bool PeekEvent(InotifyEvent& rEvt) throw (InotifyException)
00530 {
00531 return PeekEvent(&rEvt);
00532 }
00533
00535
00541 InotifyWatch* FindWatch(int iDescriptor);
00542
00544
00554 InotifyWatch* FindWatch(const std::string& rPath);
00555
00557
00565 inline int GetDescriptor() const
00566 {
00567 return m_fd;
00568 }
00569
00571
00582 void SetNonBlock(bool fNonBlock) throw (InotifyException);
00583
00584 private:
00585 int m_fd;
00586 IN_WATCH_MAP m_watches;
00587 IN_WP_MAP m_paths;
00588 unsigned char m_buf[INOTIFY_BUFLEN];
00589 std::deque<InotifyEvent> m_events;
00590
00591 friend class InotifyWatch;
00592 };
00593
00594
00595 #endif //_INOTIFYCXX_H_