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 20... Line 20...
20
 */
20
 */
21
 
21
 
22
22
23
#include <errno.h>
23
#include <errno.h>
24
#include <unistd.h>
24
#include <unistd.h>
-
 
25
#include <fcntl.h>
25
26
26
#include "inotify-cxx.h"
27
#include "inotify-cxx.h"
27
28
-
 
29
/// dump separator (between particular entries)
28
#define DUMP_SEP \
30
#define DUMP_SEP \
29
  ({ \
31
  ({ \
30
    if (!rStr.empty()) { \
32
    if (!rStr.empty()) { \
31
      rStr.append(","); \
33
      rStr.append(","); \
32
    } \
34
    } \
33
  })
35
  })
34
36
-
 
37
-
 
38
int32_t InotifyEvent::GetDescriptor() const
-
 
39
{
-
 
40
  return  m_pWatch != NULL            // if watch exists
-
 
41
      ?   m_pWatch->GetDescriptor()   // return its descriptor
-
 
42
      :   -1;                         // else return -1
-
 
43
}
-
 
44
35
uint32_t InotifyEvent::GetMaskByName(const std::string& rName)
45
uint32_t InotifyEvent::GetMaskByName(const std::string& rName)
36
{
46
{
37
  if (rName == "IN_ACCESS")
47
  if (rName == "IN_ACCESS")
38
    return IN_ACCESS;
48
    return IN_ACCESS;
39
  else if (rName == "IN_MODIFY")
49
  else if (rName == "IN_MODIFY")
Line 161... Line 171...
161
  }
171
  }
162
}
172
}
163
173
164
void InotifyEvent::DumpTypes(std::string& rStr) const
174
void InotifyEvent::DumpTypes(std::string& rStr) const
165
{
175
{
166
  DumpTypes((uint32_t) m_evt.mask, rStr);
176
  DumpTypes(m_uMask, rStr);
167
}
177
}
168
178
169
179
170
Inotify::Inotify()
180
Inotify::Inotify() throw (InotifyException)
171
{
181
{
172
  m_fd = inotify_init();  
182
  m_fd = inotify_init();
-
 
183
  if (m_fd == -1)
-
 
184
    throw InotifyException(std::string(__PRETTY_FUNCTION__) + ": inotify init failed", errno, NULL);
173
}
185
}
174
 
186
 
175
Inotify::~Inotify()
187
Inotify::~Inotify()
176
{
188
{
177
  Close();
189
  Close();
Line 184... Line 196...
184
    close(m_fd);
196
    close(m_fd);
185
    m_fd = -1;
197
    m_fd = -1;
186
  }
198
  }
187
}
199
}
188
200
189
bool Inotify::Add(InotifyWatch* pWatch)
201
void Inotify::Add(InotifyWatch* pWatch) throw (InotifyException)
190
{
202
{
191
  if (m_fd == -1)
203
  if (m_fd == -1)
192
    return false;
204
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
193
   
205
   
194
  pWatch->m_wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask());
206
  pWatch->m_wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask());
-
 
207
195
  if (pWatch->m_wd != -1) {
208
  if (pWatch->m_wd == -1)
-
 
209
    throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this);
-
 
210
196
    m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch));
211
  m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch));
197
    pWatch->m_pInotify = this;
212
  pWatch->m_pInotify = this;
198
    return true;
-
 
199
  }
-
 
200
 
-
 
201
  return false;
-
 
202
}
213
}
203
214
204
void Inotify::Remove(InotifyWatch* pWatch)
215
void Inotify::Remove(InotifyWatch* pWatch) throw (InotifyException)
205
{
216
{
206
  if (m_fd == -1)
217
  if (m_fd == -1)
207
    return;
218
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
208
   
219
   
209
  if (inotify_rm_watch(m_fd, pWatch->GetMask()) != -1) {
220
  if (inotify_rm_watch(m_fd, pWatch->GetMask()) == -1)
-
 
221
    throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this);
-
 
222
   
210
    m_watches.erase(pWatch->m_wd);
223
  m_watches.erase(pWatch->m_wd);
211
    pWatch->m_wd = -1;
224
  pWatch->m_wd = -1;
212
    pWatch->m_pInotify = NULL;
225
  pWatch->m_pInotify = NULL;
213
  }
-
 
214
}
226
}
215
227
216
void Inotify::RemoveAll()
228
void Inotify::RemoveAll()
217
{
229
{
218
  IN_WATCH_MAP::iterator it = m_watches.begin();
230
  IN_WATCH_MAP::iterator it = m_watches.begin();
Line 225... Line 237...
225
  }
237
  }
226
 
238
 
227
  m_watches.clear();
239
  m_watches.clear();
228
}
240
}
229
241
230
bool Inotify::WaitForEvents(bool fNoIntr)
242
void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException)
231
{
243
{
232
  ssize_t len = 0;
244
  ssize_t len = 0;
233
 
245
 
234
  do {
246
  do {
235
    len = read(m_fd, m_buf, INOTIFY_BUFLEN);
247
    len = read(m_fd, m_buf, INOTIFY_BUFLEN);
236
  } while (fNoIntr && len == -1 && errno == EINTR);
248
  } while (fNoIntr && len == -1 && errno == EINTR);
237
 
249
 
238
  if (len <= 0) {
250
  if (errno == EWOULDBLOCK)
239
    return false;
251
    return;
240
  }
252
 
-
 
253
  if (len < 0)
-
 
254
    throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this);
241
 
255
 
242
  ssize_t i = 0;
256
  ssize_t i = 0;
243
  while (i < len) {
257
  while (i < len) {
244
    InotifyWatch* pW = FindWatch(((struct inotify_event *) &m_buf[i])->wd);
258
    struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i];
-
 
259
    InotifyWatch* pW = FindWatch(pEvt->wd);
-
 
260
    if (pW != NULL && pW->IsEnabled()) {
245
    InotifyEvent evt((struct inotify_event *) &m_buf[i], pW);
261
      InotifyEvent evt(pEvt, pW);
246
    m_events.push_back(evt);
262
      m_events.push_back(evt);
-
 
263
    }
247
    i += INOTIFY_EVENT_SIZE + (int) evt.GetLength();
264
    i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
248
  }
265
  }
249
 
-
 
250
  return true;
-
 
251
}
266
}
252
 
267
 
253
int Inotify::GetEventCount()
268
int Inotify::GetEventCount()
254
{
269
{
255
  return m_events.size();
270
  return m_events.size();
256
}
271
}
257
 
272
 
258
bool Inotify::GetEvent(InotifyEvent* pEvt)
273
bool Inotify::GetEvent(InotifyEvent* pEvt) throw (InotifyException)
259
{
274
{
260
  bool b = PeekEvent(pEvt);
275
  bool b = PeekEvent(pEvt);
-
 
276
 
261
  if (b)
277
  if (b)
262
    m_events.pop_front();
278
    m_events.pop_front();
-
 
279
   
263
  return b;
280
  return b;
264
}
281
}
265
 
282
 
266
bool Inotify::PeekEvent(InotifyEvent* pEvt)
283
bool Inotify::PeekEvent(InotifyEvent* pEvt) throw (InotifyException)
267
{
284
{
268
  if (pEvt == NULL || m_events.empty())
285
  if (pEvt == NULL)
269
    return false;
-
 
270
   
-
 
271
  *pEvt = m_events.front();
286
    throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
272
 
287
 
-
 
288
  if (!m_events.empty()) {
-
 
289
    *pEvt = m_events.front();
273
  return true;
290
    return true;
-
 
291
  }
-
 
292
 
-
 
293
  return false;
274
}
294
}
275
295
276
InotifyWatch* Inotify::FindWatch(int iDescriptor)
296
InotifyWatch* Inotify::FindWatch(int iDescriptor)
277
{
297
{
278
  IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor);
298
  IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor);
Line 280... Line 300...
280
    return NULL;
300
    return NULL;
281
   
301
   
282
  return (*it).second;
302
  return (*it).second;
283
}
303
}
284
 
304
 
-
 
305
void Inotify::SetNonBlock(bool fNonBlock) throw (InotifyException)
-
 
306
{
-
 
307
  if (m_fd == -1)
-
 
308
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
-
 
309
   
-
 
310
  int res = fcntl(m_fd, F_GETFL);
-
 
311
  if (res == -1)
-
 
312
    throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
-
 
313
 
-
 
314
  if (fNonBlock) {
-
 
315
    res |= O_NONBLOCK;
-
 
316
  }
-
 
317
  else {
-
 
318
    res &= ~O_NONBLOCK;
-
 
319
  }
-
 
320
     
-
 
321
  if (fcntl(m_fd, F_SETFL, res) == -1)
-
 
322
    throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
-
 
323
}  
-
 
324