Subversion Repositories public

Rev

Rev 45 | Rev 49 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 45 Rev 47
Line 38... Line 38...
38
#define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
38
#define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
39
39
40
/// Event buffer length
40
/// Event buffer length
41
#define INOTIFY_BUFLEN (1024 * (INOTIFY_EVENT_SIZE + 16))
41
#define INOTIFY_BUFLEN (1024 * (INOTIFY_EVENT_SIZE + 16))
42
42
-
 
43
/// Helper macro for creating exception messages.
-
 
44
/**
-
 
45
 * It prepends the message by the function name.
-
 
46
 */
-
 
47
#define IN_EXC_MSG(msg) (std::string(__PRETTY_FUNCTION__) + ": " + msg)
-
 
48
-
 
49
43
50
44
// forward declaration
51
// forward declaration
45
class InotifyWatch;
52
class InotifyWatch;
46
class Inotify;
53
class Inotify;
47
54
48
55
-
 
56
/// Class for inotify exceptions
-
 
57
class InotifyException
-
 
58
{
-
 
59
public:
-
 
60
  /// Constructor
-
 
61
  /**
-
 
62
   * \param[in] rMsg message
-
 
63
   * \param[in] iErr error number (see errno.h)
-
 
64
   * \param[in] pSrc source
-
 
65
   */
-
 
66
  InotifyException(const std::string& rMsg = "", int iErr = 0, void* pSrc = NULL)
-
 
67
  : m_msg(rMsg),
-
 
68
    m_err(iErr)
-
 
69
  {
-
 
70
    m_pSrc = pSrc;
-
 
71
  }
-
 
72
 
-
 
73
  /// Returns the exception message.
-
 
74
  /**
-
 
75
   * \return message
-
 
76
   */
-
 
77
  inline const std::string& GetMessage() const
-
 
78
  {
-
 
79
    return m_msg;
-
 
80
  }
-
 
81
 
-
 
82
  /// Returns the exception error number.
-
 
83
  /**
-
 
84
   * If not applicable this value is 0 (zero).
-
 
85
   *
-
 
86
   * \return error number (standardized; see errno.h)
-
 
87
   */
-
 
88
  inline int GetErrorNumber() const
-
 
89
  {
-
 
90
    return m_err;
-
 
91
  }
-
 
92
 
-
 
93
  /// Returns the exception source.
-
 
94
  /**
-
 
95
   * \return source
-
 
96
   */
-
 
97
  inline void* GetSource() const
-
 
98
  {
-
 
99
    return m_pSrc;
-
 
100
  }
-
 
101
-
 
102
protected:
-
 
103
  std::string m_msg;      ///< message
-
 
104
  int m_err;              ///< error number
-
 
105
  mutable void* m_pSrc;   ///< source
-
 
106
};
-
 
107
-
 
108
49
/// inotify event class
109
/// inotify event class
50
/**
110
/**
51
 * It holds all information about inotify event and provides
111
 * It holds all information about inotify event and provides
52
 * access to its particular values.
112
 * access to its particular values.
53
 */
113
 */
Line 57... Line 117...
57
  /// Constructor.
117
  /// Constructor.
58
  /**
118
  /**
59
   * Creates a plain event.
119
   * Creates a plain event.
60
   */
120
   */
61
  InotifyEvent()
121
  InotifyEvent()
-
 
122
  : m_uMask(0),
-
 
123
    m_uCookie(0)
62
  {
124
  {
63
    memset(&m_evt, 0, sizeof(m_evt));
-
 
64
    m_evt.wd = (int32_t) -1;
-
 
65
    m_pWatch = NULL;
125
    m_pWatch = NULL;
66
  }
126
  }
67
 
127
 
68
  /// Constructor.
128
  /// Constructor.
69
  /**
129
  /**
Line 72... Line 132...
72
   *
132
   *
73
   * \param[in] pEvt event data
133
   * \param[in] pEvt event data
74
   * \param[in] pWatch inotify watch
134
   * \param[in] pWatch inotify watch
75
   */
135
   */
76
  InotifyEvent(const struct inotify_event* pEvt, InotifyWatch* pWatch)
136
  InotifyEvent(const struct inotify_event* pEvt, InotifyWatch* pWatch)
-
 
137
  : m_uMask(0),
-
 
138
    m_uCookie(0)
77
  {
139
  {
78
    if (pEvt != NULL) {
140
    if (pEvt != NULL) {
79
      memcpy(&m_evt, pEvt, sizeof(m_evt));
141
      m_uMask = (uint32_t) pEvt->mask;
-
 
142
      m_uCookie = (uint32_t) pEvt->cookie;
80
      if (pEvt->name != NULL)
143
      if (pEvt->name != NULL)
81
        m_name = pEvt->name;
144
        m_name = pEvt->name;
82
      m_pWatch = pWatch;
145
      m_pWatch = pWatch;
83
    }
146
    }
84
    else {
147
    else {
85
      memset(&m_evt, 0, sizeof(m_evt));
-
 
86
      m_evt.wd = (int32_t) -1;
-
 
87
      m_pWatch = NULL;
148
      m_pWatch = NULL;
88
    }
149
    }
89
  }
150
  }
90
 
151
 
91
  /// Destructor.
152
  /// Destructor.
Line 95... Line 156...
95
  /**
156
  /**
96
   * \return watch descriptor
157
   * \return watch descriptor
97
   *
158
   *
98
   * \sa InotifyWatch::GetDescriptor()
159
   * \sa InotifyWatch::GetDescriptor()
99
   */
160
   */
100
  inline int32_t GetDescriptor() const
161
  int32_t GetDescriptor() const;
101
  {
-
 
102
    return (int32_t) m_evt.wd;
-
 
103
  }
-
 
104
 
162
 
105
  /// Returns the event mask.
163
  /// Returns the event mask.
106
  /**
164
  /**
107
   * \return event mask
165
   * \return event mask
108
   *
166
   *
109
   * \sa InotifyWatch::GetMask()
167
   * \sa InotifyWatch::GetMask()
110
   */
168
   */
111
  inline uint32_t GetMask() const
169
  inline uint32_t GetMask() const
112
  {
170
  {
113
    return (uint32_t) m_evt.mask;
171
    return m_uMask;
114
  }
172
  }
115
 
173
 
116
  /// Checks a value for the event type.
174
  /// Checks a value for the event type.
117
  /**
175
  /**
118
   * \param[in] uValue checked value
176
   * \param[in] uValue checked value
Line 129... Line 187...
129
   * \param[in] uType type which is checked for
187
   * \param[in] uType type which is checked for
130
   * \return true = event mask contains the given type, false = otherwise
188
   * \return true = event mask contains the given type, false = otherwise
131
   */
189
   */
132
  inline bool IsType(uint32_t uType) const
190
  inline bool IsType(uint32_t uType) const
133
  {
191
  {
134
    return IsType((uint32_t) m_evt.mask, uType);
192
    return IsType(m_uMask, uType);
135
  }
193
  }
136
 
194
 
137
  /// Returns the event cookie.
195
  /// Returns the event cookie.
138
  /**
196
  /**
139
   * \return event cookie
197
   * \return event cookie
140
   */
198
   */
141
  inline uint32_t GetCookie() const
199
  inline uint32_t GetCookie() const
142
  {
200
  {
143
    return (uint32_t) m_evt.cookie;
201
    return m_uCookie;
144
  }
202
  }
145
 
203
 
146
  /// Returns the event name length.
204
  /// Returns the event name length.
147
  /**
205
  /**
148
   * \return event name length
206
   * \return event name length
149
   */
207
   */
150
  inline uint32_t GetLength() const
208
  inline uint32_t GetLength() const
151
  {
209
  {
152
    return (uint32_t) m_evt.len;
210
    return (uint32_t) m_name.length();
153
  }
211
  }
154
 
212
 
155
  /// Returns the event name.
213
  /// Returns the event name.
156
  /**
214
  /**
157
   * \return event name
215
   * \return event name
Line 177... Line 235...
177
  inline InotifyWatch* GetWatch()
235
  inline InotifyWatch* GetWatch()
178
  {
236
  {
179
    return m_pWatch;
237
    return m_pWatch;
180
  }
238
  }
181
 
239
 
182
  /// Returns the event raw data.
-
 
183
  /**
-
 
184
   * For NULL pointer it does nothing.
-
 
185
   *
-
 
186
   * \param[in,out] pEvt event data
-
 
187
   */
-
 
188
  inline void GetData(struct inotify_event* pEvt)
-
 
189
  {
-
 
190
    if (pEvt != NULL)
-
 
191
      memcpy(pEvt, &m_evt, sizeof(m_evt));
-
 
192
  }
-
 
193
 
-
 
194
  /// Returns the event raw data.
-
 
195
  /**
-
 
196
   * \param[in,out] rEvt event data
-
 
197
   */
-
 
198
  inline void GetData(struct inotify_event& rEvt)
-
 
199
  {
-
 
200
    memcpy(&rEvt, &m_evt, sizeof(m_evt));
-
 
201
  }
-
 
202
 
-
 
203
  /// Finds the appropriate mask for a name.
240
  /// Finds the appropriate mask for a name.
204
  /**
241
  /**
205
   * \param[in] rName mask name
242
   * \param[in] rName mask name
206
   * \return mask for name; 0 on failure
243
   * \return mask for name; 0 on failure
207
   */
244
   */
Line 219... Line 256...
219
   * \param[out] rStr dumped event types
256
   * \param[out] rStr dumped event types
220
   */
257
   */
221
  void DumpTypes(std::string& rStr) const;
258
  void DumpTypes(std::string& rStr) const;
222
 
259
 
223
private:
260
private:
224
  struct inotify_event m_evt; ///< event structure
261
  uint32_t m_uMask;           ///< mask
-
 
262
  uint32_t m_uCookie;         ///< cookie
225
  std::string m_name;         ///< event name
263
  std::string m_name;         ///< name
226
  InotifyWatch* m_pWatch;     ///< source watch
264
  InotifyWatch* m_pWatch;     ///< source watch
227
};
265
};
228
266
229
267
230
268
Line 237... Line 275...
237
   * Creates an inotify watch. Because this watch is
275
   * Creates an inotify watch. Because this watch is
238
   * inactive it has an invalid descriptor (-1).
276
   * inactive it has an invalid descriptor (-1).
239
   *
277
   *
240
   * \param[in] rPath watched file path
278
   * \param[in] rPath watched file path
241
   * \param[in] uMask mask for events
279
   * \param[in] uMask mask for events
-
 
280
   * \param[in] fEnabled events enabled yes/no
242
   */
281
   */
243
  InotifyWatch(const std::string& rPath, int32_t uMask)
282
  InotifyWatch(const std::string& rPath, int32_t uMask, bool fEnabled = true)
-
 
283
  : m_path(rPath),
-
 
284
    m_uMask(uMask),
-
 
285
    m_wd((int32_t) -1),
-
 
286
    m_fEnabled(fEnabled)
244
  {
287
  {
245
    m_path = rPath;
-
 
246
    m_uMask = uMask;
-
 
247
    m_wd = (int32_t) -1;
-
 
-
 
288
   
248
  }
289
  }
249
 
290
 
250
  /// Destructor.
291
  /// Destructor.
251
  ~InotifyWatch() {}
292
  ~InotifyWatch() {}
252
 
293
 
Line 284... Line 325...
284
  inline Inotify* GetInotify()
325
  inline Inotify* GetInotify()
285
  {
326
  {
286
    return m_pInotify;
327
    return m_pInotify;
287
  }
328
  }
288
 
329
 
-
 
330
  inline void SetEnabled(bool fEnabled)
-
 
331
  {
-
 
332
    m_fEnabled = fEnabled;
-
 
333
  }  
-
 
334
 
-
 
335
  inline bool IsEnabled() const
-
 
336
  {
-
 
337
    return m_fEnabled;
-
 
338
  }
-
 
339
 
289
private:
340
private:
290
  friend class Inotify;
341
  friend class Inotify;
291
342
292
  std::string m_path;   ///< watched file path
343
  std::string m_path;   ///< watched file path
293
  uint32_t m_uMask;     ///< event mask
344
  uint32_t m_uMask;     ///< event mask
294
  int32_t m_wd;         ///< watch descriptor
345
  int32_t m_wd;         ///< watch descriptor
295
  Inotify* m_pInotify;  ///< inotify object
346
  Inotify* m_pInotify;  ///< inotify object
-
 
347
  bool m_fEnabled;      ///< events enabled yes/no
296
};
348
};
297
349
298
350
299
/// Mapping from watch descriptors to watch objects.
351
/// Mapping from watch descriptors to watch objects.
300
typedef std::map<int32_t, InotifyWatch*> IN_WATCH_MAP;
352
typedef std::map<int32_t, InotifyWatch*> IN_WATCH_MAP;
Line 306... Line 358...
306
public:
358
public:
307
  /// Constructor.
359
  /// Constructor.
308
  /**
360
  /**
309
   * Creates and initializes an instance of inotify communication
361
   * Creates and initializes an instance of inotify communication
310
   * object (opens the inotify device).
362
   * object (opens the inotify device).
-
 
363
   *
-
 
364
   * \throw InotifyException thrown if inotify isn't available
311
   */
365
   */
312
  Inotify();
366
  Inotify() throw (InotifyException);
313
 
367
 
314
  /// Destructor.
368
  /// Destructor.
315
  /**
369
  /**
316
   * Calls Close() due for clean-up.
370
   * Calls Close() due to clean-up.
317
   */
371
   */
318
  ~Inotify();
372
  ~Inotify();
319
 
373
 
320
  /// Removes all watches and closes the inotify device.
374
  /// Removes all watches and closes the inotify device.
321
  void Close();
375
  void Close();
322
 
376
   
323
  /// Checks whether the inotify is ready.
-
 
324
  /**
-
 
325
   * \return true = initialized properly, false = something failed
-
 
326
   */
-
 
327
  inline bool IsReady() const
-
 
328
  {
-
 
329
    return m_fd != -1;
-
 
330
  }
-
 
331
 
-
 
332
  /// Adds a new watch.
377
  /// Adds a new watch.
333
  /**
378
  /**
334
   * \param[in] pWatch inotify watch
379
   * \param[in] pWatch inotify watch
-
 
380
   *
335
   * \return true = success, false = failure
381
   * \throw InotifyException thrown if adding failed
336
   */
382
   */
337
  bool Add(InotifyWatch* pWatch);
383
  void Add(InotifyWatch* pWatch) throw (InotifyException);
338
 
384
 
339
  /// Adds a new watch.
385
  /// Adds a new watch.
340
  /**
386
  /**
341
   * \param[in] rWatch inotify watch
387
   * \param[in] rWatch inotify watch
-
 
388
   *
342
   * \return true = success, false = failure
389
   * \throw InotifyException thrown if adding failed
343
   */
390
   */
344
  inline bool Add(InotifyWatch& rWatch)
391
  inline void Add(InotifyWatch& rWatch) throw (InotifyException)
345
  {
392
  {
346
    return Add(&rWatch);
393
    Add(&rWatch);
347
  }
394
  }
348
 
395
 
349
  /// Removes a watch.
396
  /// Removes a watch.
350
  /**
397
  /**
351
   * If the given watch is not present it does nothing.
398
   * If the given watch is not present it does nothing.
352
   *
399
   *
353
   * \param[in] pWatch inotify watch
400
   * \param[in] pWatch inotify watch
-
 
401
   *
-
 
402
   * \throw InotifyException thrown if removing failed
354
   */
403
   */
355
  void Remove(InotifyWatch* pWatch);
404
  void Remove(InotifyWatch* pWatch) throw (InotifyException);
356
 
405
 
357
  /// Removes a watch.
406
  /// Removes a watch.
358
  /**
407
  /**
359
   * If the given watch is not present it does nothing.
408
   * If the given watch is not present it does nothing.
360
   *
409
   *
361
   * \param[in] rWatch inotify watch
410
   * \param[in] rWatch inotify watch
-
 
411
   *
-
 
412
   * \throw InotifyException thrown if removing failed
362
   */
413
   */
363
  inline void Remove(InotifyWatch& rWatch)
414
  inline void Remove(InotifyWatch& rWatch) throw (InotifyException)
364
  {
415
  {
365
    Remove(&rWatch);
416
    Remove(&rWatch);
366
  }
417
  }
367
 
418
 
368
  /// Removes all watches.
419
  /// Removes all watches.
Line 377... Line 428...
377
    return (size_t) m_watches.size();
428
    return (size_t) m_watches.size();
378
  }
429
  }
379
 
430
 
380
  /// Waits for inotify events.
431
  /// Waits for inotify events.
381
  /**
432
  /**
382
   * It waits until one or more events occur.
433
   * It waits until one or more events occur. When called
-
 
434
   * in nonblocking mode it only retrieves occurred events
-
 
435
   * to the internal queue and exits.
383
   *
436
   *
384
   * \param[in] fNoIntr if true it re-calls the system call after a handled signal
437
   * \param[in] fNoIntr if true it re-calls the system call after a handled signal
-
 
438
   *
385
   * \return true = event(s) occurred, false = failure
439
   * \throw InotifyException thrown if reading events failed
-
 
440
   *
-
 
441
   * \sa SetNonBlock()
386
   */
442
   */
387
  bool WaitForEvents(bool fNoIntr = false);
443
  void WaitForEvents(bool fNoIntr = false) throw (InotifyException);
388
 
444
 
389
  /// Returns the count of received and queued events.
445
  /// Returns the count of received and queued events.
390
  /**
446
  /**
391
   * This number is related to the events in the queue inside
447
   * This number is related to the events in the queue inside
392
   * this object, not to the events pending in the kernel.
448
   * this object, not to the events pending in the kernel.
Line 399... Line 455...
399
  /**
455
  /**
400
   * The extracted event is removed from the queue.
456
   * The extracted event is removed from the queue.
401
   * If the pointer is NULL it does nothing.
457
   * If the pointer is NULL it does nothing.
402
   *
458
   *
403
   * \param[in,out] pEvt event object
459
   * \param[in,out] pEvt event object
-
 
460
   *
404
   * \return true = success, false = failure
461
   * \throw InotifyException thrown if the provided pointer is NULL
405
   */
462
   */
406
  bool GetEvent(InotifyEvent* pEvt);
463
  bool GetEvent(InotifyEvent* pEvt) throw (InotifyException);
407
 
464
 
408
  /// Extracts a queued inotify event.
465
  /// Extracts a queued inotify event.
409
  /**
466
  /**
410
   * The extracted event is removed from the queue.
467
   * The extracted event is removed from the queue.
411
   *
468
   *
412
   * \param[in,out] rEvt event object
469
   * \param[in,out] rEvt event object
-
 
470
   *
413
   * \return true = success, false = failure
471
   * \throw InotifyException thrown only in very anomalous cases
414
   */
472
   */
415
  bool GetEvent(InotifyEvent& rEvt)
473
  bool GetEvent(InotifyEvent& rEvt) throw (InotifyException)
416
  {
474
  {
417
    return GetEvent(&rEvt);
475
    return GetEvent(&rEvt);
418
  }
476
  }
419
 
477
 
420
  /// Extracts a queued inotify event (without removing).
478
  /// Extracts a queued inotify event (without removing).
421
  /**
479
  /**
422
   * The extracted event stays in the queue.
480
   * The extracted event stays in the queue.
423
   * If the pointer is NULL it does nothing.
481
   * If the pointer is NULL it does nothing.
424
   *
482
   *
425
   * \param[in,out] pEvt event object
483
   * \param[in,out] pEvt event object
-
 
484
   *
426
   * \return true = success, false = failure
485
   * \throw InotifyException thrown if the provided pointer is NULL
427
   */
486
   */
428
  bool PeekEvent(InotifyEvent* pEvt);
487
  bool PeekEvent(InotifyEvent* pEvt) throw (InotifyException);
429
 
488
 
430
  /// Extracts a queued inotify event (without removing).
489
  /// Extracts a queued inotify event (without removing).
431
  /**
490
  /**
432
   * The extracted event stays in the queue.
491
   * The extracted event stays in the queue.
433
   *
492
   *
434
   * \param[in,out] rEvt event object
493
   * \param[in,out] rEvt event object
-
 
494
   *
435
   * \return true = success, false = failure
495
   * \throw InotifyException thrown only in very anomalous cases
436
   */
496
   */
437
  bool PeekEvent(InotifyEvent& rEvt)
497
  bool PeekEvent(InotifyEvent& rEvt) throw (InotifyException)
438
  {
498
  {
439
    return PeekEvent(&rEvt);
499
    return PeekEvent(&rEvt);
440
  }
500
  }
441
 
501
 
442
  /// Searches for a watch.
502
  /// Searches for a watch.
Line 444... Line 504...
444
   * It tries to find a watch by the given descriptor.
504
   * It tries to find a watch by the given descriptor.
445
   *
505
   *
446
   * \param[in] iDescriptor watch descriptor
506
   * \param[in] iDescriptor watch descriptor
447
   * \return found descriptor; NULL if no such watch exists
507
   * \return found descriptor; NULL if no such watch exists
448
   */
508
   */
449
  InotifyWatch* FindWatch(int iDescriptor);  
509
  InotifyWatch* FindWatch(int iDescriptor);
-
 
510
 
-
 
511
  /// Returns the file descriptor.
-
 
512
  /**
-
 
513
   * The descriptor can be used in standard low-level file
-
 
514
   * functions (poll(), select(), fcntl() etc.).
-
 
515
   *
-
 
516
   * \return valid file descriptor or -1 for inactive object
-
 
517
   *
-
 
518
   * \sa SetNonBlock()
-
 
519
   */
-
 
520
  inline int GetDescriptor() const
-
 
521
  {
-
 
522
    return m_fd;
-
 
523
  }
-
 
524
 
-
 
525
  /// Enables/disables non-blocking mode.
-
 
526
  /**
-
 
527
   * Use this mode if you want to monitor the descriptor
-
 
528
   * (acquired thru GetDescriptor()) in functions such as
-
 
529
   * poll(), select() etc.
-
 
530
   *
-
 
531
   * \param[in] fNonBlock enable/disable non-blocking mode
-
 
532
   *
-
 
533
   * \throw InotifyException thrown if setting mode failed
-
 
534
   *
-
 
535
   * \sa GetDescriptor()
-
 
536
   */
-
 
537
  void SetNonBlock(bool fNonBlock) throw (InotifyException);
450
538
451
private:
539
private:
452
  int m_fd;                             ///< file descriptor
540
  int m_fd;                             ///< file descriptor
453
  IN_WATCH_MAP m_watches;               ///< watches
541
  IN_WATCH_MAP m_watches;               ///< watches
454
  unsigned char m_buf[INOTIFY_BUFLEN];  ///< buffer for events
542
  unsigned char m_buf[INOTIFY_BUFLEN];  ///< buffer for events