Subversion Repositories public

Rev

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

Rev 61 Rev 63
Line 3... Line 3...
3
/**
3
/**
4
 * \file inotify-cxx.cpp
4
 * \file inotify-cxx.cpp
5
 *
5
 *
6
 * inotify C++ interface
6
 * inotify C++ interface
7
 *
7
 *
8
 * Copyright (C) 2006 Lukas Jelinek <lukas@aiken.cz>
8
 * Copyright (C) 2006, 2007 Lukas Jelinek <lukas@aiken.cz>
9
 *
9
 *
10
 * This program is free software; you can redistribute it and/or
10
 * This program is free software; you can redistribute it and/or
11
 * modify it under the terms of one of the following licenses:
11
 * modify it under the terms of one of the following licenses:
12
 *
12
 *
13
 * \li 1. X11-style license (see LICENSE-X11)
13
 * \li 1. X11-style license (see LICENSE-X11)
Line 24... Line 24...
24
#include <unistd.h>
24
#include <unistd.h>
25
#include <fcntl.h>
25
#include <fcntl.h>
26
26
27
#include "inotify-cxx.h"
27
#include "inotify-cxx.h"
28
28
-
 
29
/// procfs inotify base path
-
 
30
#define PROCFS_INOTIFY_BASE "/proc/sys/fs/inotify/"
-
 
31
29
/// dump separator (between particular entries)
32
/// dump separator (between particular entries)
30
#define DUMP_SEP \
33
#define DUMP_SEP \
31
  ({ \
34
  ({ \
32
    if (!rStr.empty()) { \
35
    if (!rStr.empty()) { \
33
      rStr.append(","); \
36
      rStr.append(","); \
Line 91... Line 94...
91
94
92
#ifdef IN_ONLYDIR
95
#ifdef IN_ONLYDIR
93
  else if (rName == "IN_ONLYDIR")
96
  else if (rName == "IN_ONLYDIR")
94
    return IN_ONLYDIR;
97
    return IN_ONLYDIR;
95
#endif // IN_ONLYDIR
98
#endif // IN_ONLYDIR
-
 
99
-
 
100
#ifdef IN_MOVE_SELF
-
 
101
  else if (rName == "IN_MOVE_SELF")
-
 
102
    return IN_MOVE_SELF;
-
 
103
#endif // IN_MOVE_SELF
96
   
104
   
97
  return (uint32_t) 0;
105
  return (uint32_t) 0;
98
}
106
}
99
107
100
void InotifyEvent::DumpTypes(uint32_t uValue, std::string& rStr)
108
void InotifyEvent::DumpTypes(uint32_t uValue, std::string& rStr)
Line 135... Line 143...
135
    }
143
    }
136
    if (IsType(uValue, IN_CLOSE)) {
144
    if (IsType(uValue, IN_CLOSE)) {
137
      DUMP_SEP;
145
      DUMP_SEP;
138
      rStr.append("IN_CLOSE");
146
      rStr.append("IN_CLOSE");
139
    }
147
    }
-
 
148
-
 
149
#ifdef IN_MOVE_SELF
-
 
150
    if (IsType(uValue, IN_MOVE_SELF)) {
-
 
151
      DUMP_SEP;
-
 
152
      rStr.append("IN_MOVE_SELF");    
-
 
153
    }
-
 
154
#endif // IN_MOVE_SELF
-
 
155
   
140
    else {
156
    else {
141
      if (IsType(uValue, IN_CLOSE_WRITE)) {
157
      if (IsType(uValue, IN_CLOSE_WRITE)) {
142
        DUMP_SEP;
158
        DUMP_SEP;
143
        rStr.append("IN_CLOSE_WRITE");
159
        rStr.append("IN_CLOSE_WRITE");
144
      }
160
      }
Line 252... Line 268...
252
  m_fEnabled = fEnabled;
268
  m_fEnabled = fEnabled;
253
 
269
 
254
  IN_WRITE_END
270
  IN_WRITE_END
255
}
271
}
256
272
-
 
273
void InotifyWatch::OnOneshotEvent()
-
 
274
{
-
 
275
  IN_WRITE_BEGIN
-
 
276
 
-
 
277
  if (!m_fEnabled) {
-
 
278
    IN_WRITE_END_NOTHROW
-
 
279
    throw InotifyException(IN_EXC_MSG("event cannot occur on disabled watch"), EINVAL, this);
-
 
280
  }
-
 
281
 
-
 
282
  if (m_pInotify != NULL) {
-
 
283
    m_pInotify->m_watches.erase(m_wd);
-
 
284
    m_wd = -1;
-
 
285
  }
-
 
286
 
-
 
287
  m_fEnabled = false;
-
 
288
 
-
 
289
  IN_WRITE_END
-
 
290
}
-
 
291
257
292
258
Inotify::Inotify() throw (InotifyException)
293
Inotify::Inotify() throw (InotifyException)
259
{
294
{
260
  IN_LOCK_INIT
295
  IN_LOCK_INIT
261
 
296
 
Line 409... Line 444...
409
  while (i < len) {
444
  while (i < len) {
410
    struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i];
445
    struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i];
411
    InotifyWatch* pW = FindWatch(pEvt->wd);
446
    InotifyWatch* pW = FindWatch(pEvt->wd);
412
    if (pW != NULL) {
447
    if (pW != NULL) {
413
      InotifyEvent evt(pEvt, pW);
448
      InotifyEvent evt(pEvt, pW);
-
 
449
      if (InotifyEvent::IsType(pW->GetMask(), IN_ONESHOT))
-
 
450
        pW->OnOneshotEvent();
414
      m_events.push_back(evt);
451
      m_events.push_back(evt);
415
    }
452
    }
416
    i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
453
    i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
417
  }
454
  }
418
 
455
 
Line 504... Line 541...
504
    IN_WRITE_END_NOTHROW
541
    IN_WRITE_END_NOTHROW
505
    throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
542
    throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
506
  }
543
  }
507
   
544
   
508
  IN_WRITE_END
545
  IN_WRITE_END
-
 
546
}
-
 
547
-
 
548
uint32_t Inotify::GetCapability(InotifyCapability_t cap) throw (InotifyException)
-
 
549
{
-
 
550
  FILE* f = fopen(GetCapabilityPath(cap).c_str(), "r");
-
 
551
  if (f == NULL)
-
 
552
    throw InotifyException(IN_EXC_MSG("cannot get capability"), errno, NULL);
-
 
553
   
-
 
554
  unsigned int val = 0;
-
 
555
  if (fscanf(f, "%u", &val) != 1) {
-
 
556
    fclose(f);
-
 
557
    throw InotifyException(IN_EXC_MSG("cannot get capability"), EIO, NULL);
-
 
558
  }
-
 
559
 
-
 
560
  fclose(f);
-
 
561
 
-
 
562
  return (uint32_t) val;
-
 
563
}
-
 
564
-
 
565
void Inotify::SetCapability(InotifyCapability_t cap, uint32_t val) throw (InotifyException)
-
 
566
{
-
 
567
  FILE* f = fopen(GetCapabilityPath(cap).c_str(), "w");
-
 
568
  if (f == NULL)
-
 
569
    throw InotifyException(IN_EXC_MSG("cannot set capability"), errno, NULL);
-
 
570
   
-
 
571
  if (fprintf(f, "%u", (unsigned int) val) <= 0) {
-
 
572
    fclose(f);
-
 
573
    throw InotifyException(IN_EXC_MSG("cannot set capability"), EIO, NULL);
-
 
574
  }
-
 
575
 
-
 
576
  fclose(f);
-
 
577
}
-
 
578
-
 
579
std::string Inotify::GetCapabilityPath(InotifyCapability_t cap) throw (InotifyException)
-
 
580
{
-
 
581
  std::string path(PROCFS_INOTIFY_BASE);
-
 
582
 
-
 
583
  switch (cap) {
-
 
584
    case IN_MAX_EVENTS:
-
 
585
      path.append("max_queued_events");
-
 
586
      break;
-
 
587
    case IN_MAX_INSTANCES:
-
 
588
      path.append("max_user_instances");
-
 
589
      break;
-
 
590
    case IN_MAX_WATCHES:
-
 
591
      path.append("max_user_watches");
-
 
592
      break;
-
 
593
    default:
-
 
594
      throw InotifyException(IN_EXC_MSG("unknown capability type"), EINVAL, NULL);
-
 
595
  }
-
 
596
 
-
 
597
  return path;
509
}  
598
}
510
599