Subversion Repositories public

Rev

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

Rev 49 Rev 51
Line 201... Line 201...
201
}
201
}
202
202
203
203
204
void InotifyWatch::SetMask(uint32_t uMask) throw (InotifyException)
204
void InotifyWatch::SetMask(uint32_t uMask) throw (InotifyException)
205
{
205
{
-
 
206
  IN_WRITE_BEGIN
-
 
207
 
206
  if (m_wd != -1) {
208
  if (m_wd != -1) {
207
    int wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), uMask);
209
    int wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), uMask);
208
    if (wd != m_wd)
210
    if (wd != m_wd) {
-
 
211
      IN_WRITE_END_NOTHROW
209
      throw InotifyException(IN_EXC_MSG("changing mask failed"), wd == -1 ? errno : EINVAL, this);
212
      throw InotifyException(IN_EXC_MSG("changing mask failed"), wd == -1 ? errno : EINVAL, this);
-
 
213
    }
210
  }
214
  }
211
 
215
 
212
  m_uMask = uMask;
216
  m_uMask = uMask;
-
 
217
 
-
 
218
  IN_WRITE_END
213
}
219
}
214
220
215
void InotifyWatch::SetEnabled(bool fEnabled) throw (InotifyException)
221
void InotifyWatch::SetEnabled(bool fEnabled) throw (InotifyException)
216
{
222
{
-
 
223
  IN_WRITE_BEGIN
-
 
224
 
217
  if (fEnabled == m_fEnabled)
225
  if (fEnabled == m_fEnabled) {
-
 
226
    IN_WRITE_END_NOTHROW
218
    return;
227
    return;
-
 
228
  }
219
 
229
 
220
  if (m_pInotify != NULL) {
230
  if (m_pInotify != NULL) {
221
    if (fEnabled) {
231
    if (fEnabled) {
222
      m_wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), m_uMask);
232
      m_wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), m_uMask);
223
      if (m_wd == -1)
233
      if (m_wd == -1) {
-
 
234
        IN_WRITE_END_NOTHROW
224
        throw InotifyException(IN_EXC_MSG("enabling watch failed"), errno, this);
235
        throw InotifyException(IN_EXC_MSG("enabling watch failed"), errno, this);
-
 
236
      }
225
      m_pInotify->m_watches.insert(IN_WATCH_MAP::value_type(m_wd, this));
237
      m_pInotify->m_watches.insert(IN_WATCH_MAP::value_type(m_wd, this));
226
    }
238
    }
227
    else {
239
    else {
228
      if (inotify_rm_watch(m_pInotify->GetDescriptor(), m_wd) != 0)
240
      if (inotify_rm_watch(m_pInotify->GetDescriptor(), m_wd) != 0) {
-
 
241
        IN_WRITE_END_NOTHROW
229
        throw InotifyException(IN_EXC_MSG("disabling watch failed"), errno, this);
242
        throw InotifyException(IN_EXC_MSG("disabling watch failed"), errno, this);
-
 
243
      }
230
      m_pInotify->m_watches.erase(m_wd);
244
      m_pInotify->m_watches.erase(m_wd);
231
      m_wd = -1;
245
      m_wd = -1;
232
    }
246
    }
233
  }
247
  }
234
 
248
 
235
  m_fEnabled = fEnabled;
249
  m_fEnabled = fEnabled;
-
 
250
 
-
 
251
  IN_WRITE_END
236
}
252
}
237
253
238
254
239
Inotify::Inotify() throw (InotifyException)
255
Inotify::Inotify() throw (InotifyException)
240
{
256
{
-
 
257
  IN_LOCK_INIT
-
 
258
 
241
  m_fd = inotify_init();
259
  m_fd = inotify_init();
242
  if (m_fd == -1)
260
  if (m_fd == -1) {
-
 
261
    IN_LOCK_DONE
243
    throw InotifyException(IN_EXC_MSG("inotify init failed"), errno, NULL);
262
    throw InotifyException(IN_EXC_MSG("inotify init failed"), errno, NULL);
-
 
263
  }
244
}
264
}
245
 
265
 
246
Inotify::~Inotify()
266
Inotify::~Inotify()
247
{
267
{
248
  Close();
268
  Close();
-
 
269
 
-
 
270
  IN_LOCK_DONE
249
}
271
}
250
272
251
void Inotify::Close()
273
void Inotify::Close()
252
{
274
{
-
 
275
  IN_WRITE_BEGIN
-
 
276
 
253
  if (m_fd != -1) {
277
  if (m_fd != -1) {
254
    RemoveAll();
278
    RemoveAll();
255
    close(m_fd);
279
    close(m_fd);
256
    m_fd = -1;
280
    m_fd = -1;
257
  }
281
  }
-
 
282
 
-
 
283
  IN_WRITE_END
258
}
284
}
259
285
260
void Inotify::Add(InotifyWatch* pWatch) throw (InotifyException)
286
void Inotify::Add(InotifyWatch* pWatch) throw (InotifyException)
261
{
287
{
-
 
288
  IN_WRITE_BEGIN
-
 
289
 
262
  // invalid descriptor - this case shouldn't occur - go away
290
  // invalid descriptor - this case shouldn't occur - go away
263
  if (m_fd == -1)
291
  if (m_fd == -1) {
-
 
292
    IN_WRITE_END_NOTHROW
264
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
293
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
-
 
294
  }
265
295
266
  // this path already watched - go away  
296
  // this path already watched - go away  
267
  if (FindWatch(pWatch->GetPath()) != NULL)
297
  if (FindWatch(pWatch->GetPath()) != NULL) {
-
 
298
    IN_WRITE_END_NOTHROW
268
    throw InotifyException(IN_EXC_MSG("path already watched"), EBUSY, this);
299
    throw InotifyException(IN_EXC_MSG("path already watched"), EBUSY, this);
-
 
300
  }
269
 
301
 
270
  // for enabled watch
302
  // for enabled watch
271
  if (pWatch->IsEnabled()) {
303
  if (pWatch->IsEnabled()) {
272
   
304
   
273
    // try to add watch to kernel
305
    // try to add watch to kernel
274
    int wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask());
306
    int wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask());
275
   
307
   
276
    // adding failed - go away
308
    // adding failed - go away
277
    if (wd == -1)
309
    if (wd == -1) {
-
 
310
      IN_WRITE_END_NOTHROW
278
      throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this);
311
      throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this);
-
 
312
    }
279
   
313
   
280
    // this path already watched (but defined another way)
314
    // this path already watched (but defined another way)
281
    InotifyWatch* pW = FindWatch(wd);
315
    InotifyWatch* pW = FindWatch(wd);
282
    if (pW != NULL) {
316
    if (pW != NULL) {
283
     
317
     
284
      // try to recover old watch because it may be modified - then go away
318
      // try to recover old watch because it may be modified - then go away
285
      if (inotify_add_watch(m_fd, pW->GetPath().c_str(), pW->GetMask()) < 0) {
319
      if (inotify_add_watch(m_fd, pW->GetPath().c_str(), pW->GetMask()) < 0) {
-
 
320
        IN_WRITE_END_NOTHROW
286
        throw InotifyException(IN_EXC_MSG("watch collision detected and recovery failed"), errno, this);
321
        throw InotifyException(IN_EXC_MSG("watch collision detected and recovery failed"), errno, this);
287
      }
322
      }
288
      else {
323
      else {
289
        // recovery failed - go away
324
        // recovery failed - go away
-
 
325
        IN_WRITE_END_NOTHROW
290
        throw InotifyException(IN_EXC_MSG("path already watched (but defined another way)"), EBUSY, this);
326
        throw InotifyException(IN_EXC_MSG("path already watched (but defined another way)"), EBUSY, this);
291
      }
327
      }
292
    }
328
    }
293
   
329
   
294
    pWatch->m_wd = wd;
330
    pWatch->m_wd = wd;
295
    m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch));
331
    m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch));
296
  }
332
  }
297
 
333
 
298
  m_paths.insert(IN_WP_MAP::value_type(pWatch->m_path, pWatch));
334
  m_paths.insert(IN_WP_MAP::value_type(pWatch->m_path, pWatch));
299
  pWatch->m_pInotify = this;
335
  pWatch->m_pInotify = this;
-
 
336
 
-
 
337
  IN_WRITE_END
300
}
338
}
301
339
302
void Inotify::Remove(InotifyWatch* pWatch) throw (InotifyException)
340
void Inotify::Remove(InotifyWatch* pWatch) throw (InotifyException)
303
{
341
{
-
 
342
  IN_WRITE_BEGIN
-
 
343
 
304
  // invalid descriptor - this case shouldn't occur - go away
344
  // invalid descriptor - this case shouldn't occur - go away
305
  if (m_fd == -1)
345
  if (m_fd == -1) {
-
 
346
    IN_WRITE_END_NOTHROW
306
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
347
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
-
 
348
  }
307
 
349
 
308
  // for enabled watch
350
  // for enabled watch
309
  if (pWatch->m_wd != -1) {  
351
  if (pWatch->m_wd != -1) {  
310
   
352
   
311
    // removing watch failed - go away
353
    // removing watch failed - go away
312
    if (inotify_rm_watch(m_fd, pWatch->m_wd) == -1)
354
    if (inotify_rm_watch(m_fd, pWatch->m_wd) == -1) {
-
 
355
      IN_WRITE_END_NOTHROW
313
      throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this);
356
      throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this);
-
 
357
    }
314
    m_watches.erase(pWatch->m_wd);
358
    m_watches.erase(pWatch->m_wd);
315
    pWatch->m_wd = -1;
359
    pWatch->m_wd = -1;
316
  }
360
  }
317
361
318
  m_paths.erase(pWatch->m_path);
362
  m_paths.erase(pWatch->m_path);
319
  pWatch->m_pInotify = NULL;
363
  pWatch->m_pInotify = NULL;
-
 
364
 
-
 
365
  IN_WRITE_END
320
}
366
}
321
367
322
void Inotify::RemoveAll()
368
void Inotify::RemoveAll()
323
{
369
{
-
 
370
  IN_WRITE_BEGIN
-
 
371
 
324
  IN_WP_MAP::iterator it = m_paths.begin();
372
  IN_WP_MAP::iterator it = m_paths.begin();
325
  while (it != m_paths.end()) {
373
  while (it != m_paths.end()) {
326
    InotifyWatch* pW = (*it).second;
374
    InotifyWatch* pW = (*it).second;
327
    if (pW->m_wd != -1) {
375
    if (pW->m_wd != -1) {
328
      inotify_rm_watch(m_fd, pW->m_wd);
376
      inotify_rm_watch(m_fd, pW->m_wd);
Line 332... Line 380...
332
    it++;
380
    it++;
333
  }
381
  }
334
 
382
 
335
  m_watches.clear();
383
  m_watches.clear();
336
  m_paths.clear();
384
  m_paths.clear();
-
 
385
 
-
 
386
  IN_WRITE_END
337
}
387
}
338
388
339
void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException)
389
void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException)
340
{
390
{
341
  ssize_t len = 0;
391
  ssize_t len = 0;
Line 348... Line 398...
348
    return;
398
    return;
349
 
399
 
350
  if (len < 0)
400
  if (len < 0)
351
    throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this);
401
    throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this);
352
 
402
 
-
 
403
  IN_WRITE_BEGIN
-
 
404
 
353
  ssize_t i = 0;
405
  ssize_t i = 0;
354
  while (i < len) {
406
  while (i < len) {
355
    struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i];
407
    struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i];
356
    InotifyWatch* pW = FindWatch(pEvt->wd);
408
    InotifyWatch* pW = FindWatch(pEvt->wd);
357
    if (pW != NULL) {
409
    if (pW != NULL) {
358
      InotifyEvent evt(pEvt, pW);
410
      InotifyEvent evt(pEvt, pW);
359
      m_events.push_back(evt);
411
      m_events.push_back(evt);
360
    }
412
    }
361
    i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
413
    i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
362
  }
414
  }
363
}
-
 
364
 
415
 
365
int Inotify::GetEventCount()
-
 
366
{
-
 
367
  return m_events.size();
416
  IN_WRITE_END
368
}
417
}
369
 
418
 
370
bool Inotify::GetEvent(InotifyEvent* pEvt) throw (InotifyException)
419
bool Inotify::GetEvent(InotifyEvent* pEvt) throw (InotifyException)
371
{
420
{
372
  bool b = PeekEvent(pEvt);
421
  if (pEvt == NULL)
-
 
422
    throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
-
 
423
 
-
 
424
  IN_WRITE_BEGIN
373
 
425
 
-
 
426
  bool b = !m_events.empty();
374
  if (b)
427
  if (b) {
-
 
428
    *pEvt = m_events.front();
375
    m_events.pop_front();
429
    m_events.pop_front();
-
 
430
  }
-
 
431
 
-
 
432
  IN_WRITE_END
376
   
433
   
377
  return b;
434
  return b;
378
}
435
}
379
 
436
 
380
bool Inotify::PeekEvent(InotifyEvent* pEvt) throw (InotifyException)
437
bool Inotify::PeekEvent(InotifyEvent* pEvt) throw (InotifyException)
381
{
438
{
382
  if (pEvt == NULL)
439
  if (pEvt == NULL)
383
    throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
440
    throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
384
 
441
 
-
 
442
  IN_READ_BEGIN
-
 
443
 
385
  if (!m_events.empty()) {
444
  bool b = !m_events.empty();
-
 
445
  if (b) {
386
    *pEvt = m_events.front();
446
    *pEvt = m_events.front();
387
    return true;
-
 
388
  }
447
  }
389
 
448
 
-
 
449
  IN_READ_END
-
 
450
 
390
  return false;
451
  return b;
391
}
452
}
392
453
393
InotifyWatch* Inotify::FindWatch(int iDescriptor)
454
InotifyWatch* Inotify::FindWatch(int iDescriptor)
394
{
455
{
-
 
456
  IN_READ_BEGIN
-
 
457
 
395
  IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor);
458
  IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor);
396
  if (it == m_watches.end())
459
  InotifyWatch* pW = it == m_watches.end() ? NULL : (*it).second;
-
 
460
 
397
    return NULL;
461
  IN_READ_END
398
   
462
 
399
  return (*it).second;
463
  return pW;
400
}
464
}
401
465
402
InotifyWatch* Inotify::FindWatch(const std::string& rPath)
466
InotifyWatch* Inotify::FindWatch(const std::string& rPath)
403
{
467
{
-
 
468
  IN_READ_BEGIN
-
 
469
 
404
  IN_WP_MAP::iterator it = m_paths.find(rPath);
470
  IN_WP_MAP::iterator it = m_paths.find(rPath);
405
  if (it == m_paths.end())
471
  InotifyWatch* pW = it == m_paths.end() ? NULL : (*it).second;
-
 
472
 
406
    return NULL;
473
  IN_READ_END
407
   
474
   
408
  return (*it).second;
475
  return pW;
409
}
476
}
410
 
477
 
411
void Inotify::SetNonBlock(bool fNonBlock) throw (InotifyException)
478
void Inotify::SetNonBlock(bool fNonBlock) throw (InotifyException)
412
{
479
{
-
 
480
  IN_WRITE_BEGIN
-
 
481
 
413
  if (m_fd == -1)
482
  if (m_fd == -1) {
-
 
483
    IN_WRITE_END_NOTHROW
414
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
484
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
-
 
485
  }
415
   
486
   
416
  int res = fcntl(m_fd, F_GETFL);
487
  int res = fcntl(m_fd, F_GETFL);
417
  if (res == -1)
488
  if (res == -1) {
-
 
489
    IN_WRITE_END_NOTHROW
418
    throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
490
    throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
-
 
491
  }
419
 
492
 
420
  if (fNonBlock) {
493
  if (fNonBlock) {
421
    res |= O_NONBLOCK;
494
    res |= O_NONBLOCK;
422
  }
495
  }
423
  else {
496
  else {
424
    res &= ~O_NONBLOCK;
497
    res &= ~O_NONBLOCK;
425
  }
498
  }
426
     
499
     
427
  if (fcntl(m_fd, F_SETFL, res) == -1)
500
  if (fcntl(m_fd, F_SETFL, res) == -1) {
-
 
501
    IN_WRITE_END_NOTHROW
428
    throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
502
    throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
-
 
503
  }
-
 
504
   
-
 
505
  IN_WRITE_END
429
}  
506
}  
430
507