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 #include <sys/inotify-syscalls.h>
00036
00038 #define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
00039
00041 #define INOTIFY_BUFLEN (1024 * (INOTIFY_EVENT_SIZE + 16))
00042
00044
00047 #define IN_EXC_MSG(msg) (std::string(__PRETTY_FUNCTION__) + ": " + msg)
00048
00049
00050
00051
00052 class InotifyWatch;
00053 class Inotify;
00054
00055
00057 class InotifyException
00058 {
00059 public:
00061
00066 InotifyException(const std::string& rMsg = "", int iErr = 0, void* pSrc = NULL)
00067 : m_msg(rMsg),
00068 m_err(iErr)
00069 {
00070 m_pSrc = pSrc;
00071 }
00072
00074
00077 inline const std::string& GetMessage() const
00078 {
00079 return m_msg;
00080 }
00081
00083
00088 inline int GetErrorNumber() const
00089 {
00090 return m_err;
00091 }
00092
00094
00097 inline void* GetSource() const
00098 {
00099 return m_pSrc;
00100 }
00101
00102 protected:
00103 std::string m_msg;
00104 int m_err;
00105 mutable void* m_pSrc;
00106 };
00107
00108
00110
00114 class InotifyEvent
00115 {
00116 public:
00118
00121 InotifyEvent()
00122 : m_uMask(0),
00123 m_uCookie(0)
00124 {
00125 m_pWatch = NULL;
00126 }
00127
00129
00136 InotifyEvent(const struct inotify_event* pEvt, InotifyWatch* pWatch)
00137 : m_uMask(0),
00138 m_uCookie(0)
00139 {
00140 if (pEvt != NULL) {
00141 m_uMask = (uint32_t) pEvt->mask;
00142 m_uCookie = (uint32_t) pEvt->cookie;
00143 if (pEvt->name != NULL)
00144 m_name = pEvt->name;
00145 m_pWatch = pWatch;
00146 }
00147 else {
00148 m_pWatch = NULL;
00149 }
00150 }
00151
00153 ~InotifyEvent() {}
00154
00156
00161 int32_t GetDescriptor() const;
00162
00164
00169 inline uint32_t GetMask() const
00170 {
00171 return m_uMask;
00172 }
00173
00175
00180 inline static bool IsType(uint32_t uValue, uint32_t uType)
00181 {
00182 return ((uValue & uType) != 0) && ((~uValue & uType) == 0);
00183 }
00184
00186
00190 inline bool IsType(uint32_t uType) const
00191 {
00192 return IsType(m_uMask, uType);
00193 }
00194
00196
00199 inline uint32_t GetCookie() const
00200 {
00201 return m_uCookie;
00202 }
00203
00205
00208 inline uint32_t GetLength() const
00209 {
00210 return (uint32_t) m_name.length();
00211 }
00212
00214
00217 inline const std::string& GetName() const
00218 {
00219 return m_name;
00220 }
00221
00223
00226 inline void GetName(std::string& rName) const
00227 {
00228 rName = GetName();
00229 }
00230
00232
00235 inline InotifyWatch* GetWatch()
00236 {
00237 return m_pWatch;
00238 }
00239
00241
00245 static uint32_t GetMaskByName(const std::string& rName);
00246
00248
00252 static void DumpTypes(uint32_t uValue, std::string& rStr);
00253
00255
00258 void DumpTypes(std::string& rStr) const;
00259
00260 private:
00261 uint32_t m_uMask;
00262 uint32_t m_uCookie;
00263 std::string m_name;
00264 InotifyWatch* m_pWatch;
00265 };
00266
00267
00268
00270 class InotifyWatch
00271 {
00272 public:
00274
00282 InotifyWatch(const std::string& rPath, int32_t uMask, bool fEnabled = true)
00283 : m_path(rPath),
00284 m_uMask(uMask),
00285 m_wd((int32_t) -1),
00286 m_fEnabled(fEnabled)
00287 {
00288
00289 }
00290
00292 ~InotifyWatch() {}
00293
00295
00298 inline int32_t GetDescriptor() const
00299 {
00300 return m_wd;
00301 }
00302
00304
00307 inline const std::string& GetPath() const
00308 {
00309 return m_path;
00310 }
00311
00313
00316 inline uint32_t GetMask() const
00317 {
00318 return (uint32_t) m_uMask;
00319 }
00320
00322
00325 inline Inotify* GetInotify()
00326 {
00327 return m_pInotify;
00328 }
00329
00330 inline void SetEnabled(bool fEnabled)
00331 {
00332 m_fEnabled = fEnabled;
00333 }
00334
00335 inline bool IsEnabled() const
00336 {
00337 return m_fEnabled;
00338 }
00339
00340 private:
00341 friend class Inotify;
00342
00343 std::string m_path;
00344 uint32_t m_uMask;
00345 int32_t m_wd;
00346 Inotify* m_pInotify;
00347 bool m_fEnabled;
00348 };
00349
00350
00352 typedef std::map<int32_t, InotifyWatch*> IN_WATCH_MAP;
00353
00354
00356 class Inotify
00357 {
00358 public:
00360
00366 Inotify() throw (InotifyException);
00367
00369
00372 ~Inotify();
00373
00375 void Close();
00376
00378
00383 void Add(InotifyWatch* pWatch) throw (InotifyException);
00384
00386
00391 inline void Add(InotifyWatch& rWatch) throw (InotifyException)
00392 {
00393 Add(&rWatch);
00394 }
00395
00397
00404 void Remove(InotifyWatch* pWatch) throw (InotifyException);
00405
00407
00414 inline void Remove(InotifyWatch& rWatch) throw (InotifyException)
00415 {
00416 Remove(&rWatch);
00417 }
00418
00420 void RemoveAll();
00421
00423
00426 inline size_t GetWatchCount() const
00427 {
00428 return (size_t) m_watches.size();
00429 }
00430
00432
00443 void WaitForEvents(bool fNoIntr = false) throw (InotifyException);
00444
00446
00452 int GetEventCount();
00453
00455
00463 bool GetEvent(InotifyEvent* pEvt) throw (InotifyException);
00464
00466
00473 bool GetEvent(InotifyEvent& rEvt) throw (InotifyException)
00474 {
00475 return GetEvent(&rEvt);
00476 }
00477
00479
00487 bool PeekEvent(InotifyEvent* pEvt) throw (InotifyException);
00488
00490
00497 bool PeekEvent(InotifyEvent& rEvt) throw (InotifyException)
00498 {
00499 return PeekEvent(&rEvt);
00500 }
00501
00503
00509 InotifyWatch* FindWatch(int iDescriptor);
00510
00512
00520 inline int GetDescriptor() const
00521 {
00522 return m_fd;
00523 }
00524
00526
00537 void SetNonBlock(bool fNonBlock) throw (InotifyException);
00538
00539 private:
00540 int m_fd;
00541 IN_WATCH_MAP m_watches;
00542 unsigned char m_buf[INOTIFY_BUFLEN];
00543 std::deque<InotifyEvent> m_events;
00544 };
00545
00546
00547 #endif //_INOTIFYCXX_H_