Subversion Repositories public

Rev

Rev 15 | Rev 21 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 15 Rev 17
1
1
2
/// inotify C++ interface implementation
2
/// inotify C++ interface implementation
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 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)
14
 * \li 2. GNU Lesser General Public License, version 2.1 (see LICENSE-LGPL)
14
 * \li 2. GNU Lesser General Public License, version 2.1 (see LICENSE-LGPL)
15
 * \li 3. GNU General Public License, version 2  (see LICENSE-GPL)
15
 * \li 3. GNU General Public License, version 2  (see LICENSE-GPL)
16
 *
16
 *
17
 * If you want to help with choosing the best license for you,
17
 * If you want to help with choosing the best license for you,
18
 * please visit http://www.gnu.org/licenses/license-list.html.
18
 * please visit http://www.gnu.org/licenses/license-list.html.
19
 *
19
 *
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
#include <fcntl.h>
26
26
27
#include "inotify-cxx.h"
27
#include "inotify-cxx.h"
28
28
29
/// dump separator (between particular entries)
29
/// dump separator (between particular entries)
30
#define DUMP_SEP \
30
#define DUMP_SEP \
31
  ({ \
31
  ({ \
32
    if (!rStr.empty()) { \
32
    if (!rStr.empty()) { \
33
      rStr.append(","); \
33
      rStr.append(","); \
34
    } \
34
    } \
35
  })
35
  })
36
36
37
37
38
int32_t InotifyEvent::GetDescriptor() const
38
int32_t InotifyEvent::GetDescriptor() const
39
{
39
{
40
  return  m_pWatch != NULL            // if watch exists
40
  return  m_pWatch != NULL            // if watch exists
41
      ?   m_pWatch->GetDescriptor()   // return its descriptor
41
      ?   m_pWatch->GetDescriptor()   // return its descriptor
42
      :   -1;                         // else return -1
42
      :   -1;                         // else return -1
43
}
43
}
44
44
45
uint32_t InotifyEvent::GetMaskByName(const std::string& rName)
45
uint32_t InotifyEvent::GetMaskByName(const std::string& rName)
46
{
46
{
47
  if (rName == "IN_ACCESS")
47
  if (rName == "IN_ACCESS")
48
    return IN_ACCESS;
48
    return IN_ACCESS;
49
  else if (rName == "IN_MODIFY")
49
  else if (rName == "IN_MODIFY")
50
    return IN_MODIFY;
50
    return IN_MODIFY;
51
  else if (rName == "IN_ATTRIB")
51
  else if (rName == "IN_ATTRIB")
52
    return IN_ATTRIB;
52
    return IN_ATTRIB;
53
  else if (rName == "IN_CLOSE_WRITE")
53
  else if (rName == "IN_CLOSE_WRITE")
54
    return IN_CLOSE_WRITE;
54
    return IN_CLOSE_WRITE;
55
  else if (rName == "IN_CLOSE_NOWRITE")
55
  else if (rName == "IN_CLOSE_NOWRITE")
56
    return IN_CLOSE_NOWRITE;
56
    return IN_CLOSE_NOWRITE;
57
  else if (rName == "IN_MOVED_FROM")
57
  else if (rName == "IN_MOVED_FROM")
58
    return IN_MOVED_FROM;
58
    return IN_MOVED_FROM;
59
  else if (rName == "IN_MOVED_TO")
59
  else if (rName == "IN_MOVED_TO")
60
    return IN_MOVED_TO;
60
    return IN_MOVED_TO;
61
  else if (rName == "IN_CREATE")
61
  else if (rName == "IN_CREATE")
62
    return IN_CREATE;
62
    return IN_CREATE;
63
  else if (rName == "IN_DELETE")
63
  else if (rName == "IN_DELETE")
64
    return IN_DELETE;
64
    return IN_DELETE;
65
  else if (rName == "IN_DELETE_SELF")
65
  else if (rName == "IN_DELETE_SELF")
66
    return IN_DELETE_SELF;
66
    return IN_DELETE_SELF;
67
  else if (rName == "IN_UNMOUNT")
67
  else if (rName == "IN_UNMOUNT")
68
    return IN_UNMOUNT;
68
    return IN_UNMOUNT;
69
  else if (rName == "IN_Q_OVERFLOW")
69
  else if (rName == "IN_Q_OVERFLOW")
70
    return IN_Q_OVERFLOW;
70
    return IN_Q_OVERFLOW;
71
  else if (rName == "IN_IGNORED")
71
  else if (rName == "IN_IGNORED")
72
    return IN_IGNORED;
72
    return IN_IGNORED;
73
  else if (rName == "IN_CLOSE")
73
  else if (rName == "IN_CLOSE")
74
    return IN_CLOSE;
74
    return IN_CLOSE;
75
  else if (rName == "IN_MOVE")
75
  else if (rName == "IN_MOVE")
76
    return IN_MOVE;
76
    return IN_MOVE;
77
  else if (rName == "IN_ISDIR")
77
  else if (rName == "IN_ISDIR")
78
    return IN_ISDIR;
78
    return IN_ISDIR;
79
  else if (rName == "IN_ONESHOT")
79
  else if (rName == "IN_ONESHOT")
80
    return IN_ONESHOT;
80
    return IN_ONESHOT;
81
  else if (rName == "IN_ALL_EVENTS")
81
  else if (rName == "IN_ALL_EVENTS")
82
    return IN_ALL_EVENTS;
82
    return IN_ALL_EVENTS;
83
   
83
   
-
 
84
#ifdef IN_DONT_FOLLOW
-
 
85
  else if (rName == "IN_DONT_FOLLOW")
-
 
86
    return IN_DONT_FOLLOW;
-
 
87
#endif // IN_DONT_FOLLOW
-
 
88
-
 
89
#ifdef IN_ONLYDIR
-
 
90
  else if (rName == "IN_ONLYDIR")
-
 
91
    return IN_ONLYDIR;
-
 
92
#endif // IN_ONLYDIR
-
 
93
   
84
  return (uint32_t) 0;
94
  return (uint32_t) 0;
85
}
95
}
86
96
87
void InotifyEvent::DumpTypes(uint32_t uValue, std::string& rStr)
97
void InotifyEvent::DumpTypes(uint32_t uValue, std::string& rStr)
88
{
98
{
89
  rStr = "";
99
  rStr = "";
90
 
100
 
91
  if (IsType(uValue, IN_ALL_EVENTS)) {
101
  if (IsType(uValue, IN_ALL_EVENTS)) {
92
    rStr.append("IN_ALL_EVENTS");
102
    rStr.append("IN_ALL_EVENTS");
93
  }
103
  }
94
  else {
104
  else {
95
    if (IsType(uValue, IN_ACCESS)) {
105
    if (IsType(uValue, IN_ACCESS)) {
96
      DUMP_SEP;
106
      DUMP_SEP;
97
      rStr.append("IN_ACCESS");    
107
      rStr.append("IN_ACCESS");    
98
    }
108
    }
99
    if (IsType(uValue, IN_MODIFY)) {
109
    if (IsType(uValue, IN_MODIFY)) {
100
      DUMP_SEP;
110
      DUMP_SEP;
101
      rStr.append("IN_MODIFY");
111
      rStr.append("IN_MODIFY");
102
    }
112
    }
103
    if (IsType(uValue, IN_ATTRIB)) {
113
    if (IsType(uValue, IN_ATTRIB)) {
104
      DUMP_SEP;
114
      DUMP_SEP;
105
      rStr.append("IN_ATTRIB");
115
      rStr.append("IN_ATTRIB");
106
    }
116
    }
107
    if (IsType(uValue, IN_CREATE)) {
117
    if (IsType(uValue, IN_CREATE)) {
108
      DUMP_SEP;
118
      DUMP_SEP;
109
      rStr.append("IN_CREATE");
119
      rStr.append("IN_CREATE");
110
    }
120
    }
111
    if (IsType(uValue, IN_DELETE)) {
121
    if (IsType(uValue, IN_DELETE)) {
112
      DUMP_SEP;
122
      DUMP_SEP;
113
      rStr.append("IN_DELETE");
123
      rStr.append("IN_DELETE");
114
    }
124
    }
115
    if (IsType(uValue, IN_DELETE_SELF)) {
125
    if (IsType(uValue, IN_DELETE_SELF)) {
116
      DUMP_SEP;
126
      DUMP_SEP;
117
      rStr.append("IN_DELETE_SELF");
127
      rStr.append("IN_DELETE_SELF");
118
    }
128
    }
119
    if (IsType(uValue, IN_OPEN)) {
129
    if (IsType(uValue, IN_OPEN)) {
120
      DUMP_SEP;
130
      DUMP_SEP;
121
      rStr.append("IN_OPEN");
131
      rStr.append("IN_OPEN");
122
    }
132
    }
123
    if (IsType(uValue, IN_CLOSE)) {
133
    if (IsType(uValue, IN_CLOSE)) {
124
      DUMP_SEP;
134
      DUMP_SEP;
125
      rStr.append("IN_CLOSE");
135
      rStr.append("IN_CLOSE");
126
    }
136
    }
127
    else {
137
    else {
128
      if (IsType(uValue, IN_CLOSE_WRITE)) {
138
      if (IsType(uValue, IN_CLOSE_WRITE)) {
129
        DUMP_SEP;
139
        DUMP_SEP;
130
        rStr.append("IN_CLOSE_WRITE");
140
        rStr.append("IN_CLOSE_WRITE");
131
      }
141
      }
132
      if (IsType(uValue, IN_CLOSE_NOWRITE)) {
142
      if (IsType(uValue, IN_CLOSE_NOWRITE)) {
133
        DUMP_SEP;
143
        DUMP_SEP;
134
        rStr.append("IN_CLOSE_NOWRITE");
144
        rStr.append("IN_CLOSE_NOWRITE");
135
      }
145
      }
136
    }
146
    }
137
    if (IsType(uValue, IN_MOVE)) {
147
    if (IsType(uValue, IN_MOVE)) {
138
      DUMP_SEP;
148
      DUMP_SEP;
139
      rStr.append("IN_MOVE");
149
      rStr.append("IN_MOVE");
140
    }
150
    }
141
    else {
151
    else {
142
      if (IsType(uValue, IN_MOVED_FROM)) {
152
      if (IsType(uValue, IN_MOVED_FROM)) {
143
        DUMP_SEP;
153
        DUMP_SEP;
144
        rStr.append("IN_MOVED_FROM");
154
        rStr.append("IN_MOVED_FROM");
145
      }
155
      }
146
      if (IsType(uValue, IN_MOVED_TO)) {
156
      if (IsType(uValue, IN_MOVED_TO)) {
147
        DUMP_SEP;
157
        DUMP_SEP;
148
        rStr.append("IN_MOVED_TO");
158
        rStr.append("IN_MOVED_TO");
149
      }
159
      }
150
    }
160
    }
151
  }
161
  }
152
  if (IsType(uValue, IN_UNMOUNT)) {
162
  if (IsType(uValue, IN_UNMOUNT)) {
153
    DUMP_SEP;
163
    DUMP_SEP;
154
    rStr.append("IN_UNMOUNT");
164
    rStr.append("IN_UNMOUNT");
155
  }
165
  }
156
  if (IsType(uValue, IN_Q_OVERFLOW)) {
166
  if (IsType(uValue, IN_Q_OVERFLOW)) {
157
    DUMP_SEP;
167
    DUMP_SEP;
158
    rStr.append("IN_Q_OVERFLOW");
168
    rStr.append("IN_Q_OVERFLOW");
159
  }
169
  }
160
  if (IsType(uValue, IN_IGNORED)) {
170
  if (IsType(uValue, IN_IGNORED)) {
161
    DUMP_SEP;
171
    DUMP_SEP;
162
    rStr.append("IN_IGNORED");
172
    rStr.append("IN_IGNORED");
163
  }
173
  }
164
  if (IsType(uValue, IN_ISDIR)) {
174
  if (IsType(uValue, IN_ISDIR)) {
165
    DUMP_SEP;
175
    DUMP_SEP;
166
    rStr.append("IN_ISDIR");
176
    rStr.append("IN_ISDIR");
167
  }
177
  }
168
  if (IsType(uValue, IN_ONESHOT)) {
178
  if (IsType(uValue, IN_ONESHOT)) {
169
    DUMP_SEP;
179
    DUMP_SEP;
170
    rStr.append("IN_ONESHOT");
180
    rStr.append("IN_ONESHOT");
171
  }
181
  }
-
 
182
 
-
 
183
#ifdef IN_DONT_FOLLOW
-
 
184
  if (IsType(uValue, IN_DONT_FOLLOW)) {
-
 
185
    DUMP_SEP;
-
 
186
    rStr.append("IN_DONT_FOLLOW");
-
 
187
  }
-
 
188
#endif // IN_DONT_FOLLOW
-
 
189
 
-
 
190
#ifdef IN_ONLYDIR
-
 
191
  if (IsType(uValue, IN_ONLYDIR)) {
-
 
192
    DUMP_SEP;
-
 
193
    rStr.append("IN_ONLYDIR");
-
 
194
  }
-
 
195
#endif // IN_ONLYDIR
172
}
196
}
173
197
174
void InotifyEvent::DumpTypes(std::string& rStr) const
198
void InotifyEvent::DumpTypes(std::string& rStr) const
175
{
199
{
176
  DumpTypes(m_uMask, rStr);
200
  DumpTypes(m_uMask, rStr);
177
}
201
}
178
202
179
203
-
 
204
void InotifyWatch::SetMask(uint32_t uMask) throw (InotifyException)
-
 
205
{
-
 
206
  if (m_wd != -1) {
-
 
207
    int wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), uMask);
-
 
208
    if (wd != m_wd)
-
 
209
      throw InotifyException(IN_EXC_MSG("changing mask failed"), wd == -1 ? errno : EINVAL, this);
-
 
210
  }
-
 
211
 
-
 
212
  m_uMask = uMask;
-
 
213
}
-
 
214
-
 
215
void InotifyWatch::SetEnabled(bool fEnabled) throw (InotifyException)
-
 
216
{
-
 
217
  if (fEnabled == m_fEnabled)
-
 
218
    return;
-
 
219
 
-
 
220
  if (m_pInotify != NULL) {
-
 
221
    if (fEnabled) {
-
 
222
      m_wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), m_uMask);
-
 
223
      if (m_wd == -1)
-
 
224
        throw InotifyException(IN_EXC_MSG("enabling watch failed"), errno, this);
-
 
225
      m_pInotify->m_watches.insert(IN_WATCH_MAP::value_type(m_wd, this));
-
 
226
    }
-
 
227
    else {
-
 
228
      if (inotify_rm_watch(m_pInotify->GetDescriptor(), m_wd) != 0)
-
 
229
        throw InotifyException(IN_EXC_MSG("disabling watch failed"), errno, this);
-
 
230
      m_pInotify->m_watches.erase(m_wd);
-
 
231
      m_wd = -1;
-
 
232
    }
-
 
233
  }
-
 
234
 
-
 
235
  m_fEnabled = fEnabled;
-
 
236
}
-
 
237
-
 
238
180
Inotify::Inotify() throw (InotifyException)
239
Inotify::Inotify() throw (InotifyException)
181
{
240
{
182
  m_fd = inotify_init();
241
  m_fd = inotify_init();
183
  if (m_fd == -1)
242
  if (m_fd == -1)
184
    throw InotifyException(std::string(__PRETTY_FUNCTION__) + ": inotify init failed", errno, NULL);
243
    throw InotifyException(IN_EXC_MSG("inotify init failed"), errno, NULL);
185
}
244
}
186
 
245
 
187
Inotify::~Inotify()
246
Inotify::~Inotify()
188
{
247
{
189
  Close();
248
  Close();
190
}
249
}
191
250
192
void Inotify::Close()
251
void Inotify::Close()
193
{
252
{
194
  if (m_fd != -1) {
253
  if (m_fd != -1) {
195
    RemoveAll();
254
    RemoveAll();
196
    close(m_fd);
255
    close(m_fd);
197
    m_fd = -1;
256
    m_fd = -1;
198
  }
257
  }
199
}
258
}
200
259
201
void Inotify::Add(InotifyWatch* pWatch) throw (InotifyException)
260
void Inotify::Add(InotifyWatch* pWatch) throw (InotifyException)
202
{
261
{
-
 
262
  // invalid descriptor - this case shouldn't occur - go away
203
  if (m_fd == -1)
263
  if (m_fd == -1)
204
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
264
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
205
   
-
 
206
  pWatch->m_wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask());
-
 
207
-
 
208
  if (pWatch->m_wd == -1)
-
 
209
    throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this);
-
 
210
265
-
 
266
  // this path already watched - go away  
-
 
267
  if (FindWatch(pWatch->GetPath()) != NULL)
-
 
268
    throw InotifyException(IN_EXC_MSG("path already watched"), EBUSY, this);
-
 
269
 
-
 
270
  // for enabled watch
-
 
271
  if (pWatch->IsEnabled()) {
-
 
272
   
-
 
273
    // try to add watch to kernel
-
 
274
    int wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask());
-
 
275
   
-
 
276
    // adding failed - go away
-
 
277
    if (wd == -1)
-
 
278
      throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this);
-
 
279
   
-
 
280
    // this path already watched (but defined another way)
-
 
281
    InotifyWatch* pW = FindWatch(wd);
-
 
282
    if (pW != NULL) {
-
 
283
     
-
 
284
      // 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) {
-
 
286
        throw InotifyException(IN_EXC_MSG("watch collision detected and recovery failed"), errno, this);
-
 
287
      }
-
 
288
      else {
-
 
289
        // recovery failed - go away
-
 
290
        throw InotifyException(IN_EXC_MSG("path already watched (but defined another way)"), EBUSY, this);
-
 
291
      }
-
 
292
    }
-
 
293
   
-
 
294
    pWatch->m_wd = wd;
211
  m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch));
295
    m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch));
-
 
296
  }
-
 
297
 
-
 
298
  m_paths.insert(IN_WP_MAP::value_type(pWatch->m_path, pWatch));
212
  pWatch->m_pInotify = this;
299
  pWatch->m_pInotify = this;
213
}
300
}
214
301
215
void Inotify::Remove(InotifyWatch* pWatch) throw (InotifyException)
302
void Inotify::Remove(InotifyWatch* pWatch) throw (InotifyException)
216
{
303
{
-
 
304
  // invalid descriptor - this case shouldn't occur - go away
217
  if (m_fd == -1)
305
  if (m_fd == -1)
218
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
306
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
-
 
307
 
-
 
308
  // for enabled watch
-
 
309
  if (pWatch->m_wd != -1) {  
219
   
310
   
-
 
311
    // removing watch failed - go away
220
  if (inotify_rm_watch(m_fd, pWatch->GetMask()) == -1)
312
    if (inotify_rm_watch(m_fd, pWatch->m_wd) == -1)
221
    throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this);
313
      throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this);
222
   
-
 
223
  m_watches.erase(pWatch->m_wd);
314
    m_watches.erase(pWatch->m_wd);
224
  pWatch->m_wd = -1;
315
    pWatch->m_wd = -1;
-
 
316
  }
-
 
317
-
 
318
  m_paths.erase(pWatch->m_path);
225
  pWatch->m_pInotify = NULL;
319
  pWatch->m_pInotify = NULL;
226
}
320
}
227
321
228
void Inotify::RemoveAll()
322
void Inotify::RemoveAll()
229
{
323
{
230
  IN_WATCH_MAP::iterator it = m_watches.begin();
324
  IN_WP_MAP::iterator it = m_paths.begin();
231
  while (it != m_watches.end()) {
325
  while (it != m_paths.end()) {
232
    InotifyWatch* pW = (*it).second;
326
    InotifyWatch* pW = (*it).second;
-
 
327
    if (pW->m_wd != -1) {
233
    inotify_rm_watch(m_fd, pW->GetMask());
328
      inotify_rm_watch(m_fd, pW->m_wd);
234
    pW->m_wd = -1;
329
      pW->m_wd = -1;
-
 
330
    }
235
    pW->m_pInotify = NULL;
331
    pW->m_pInotify = NULL;
236
    it++;
332
    it++;
237
  }
333
  }
238
 
334
 
239
  m_watches.clear();
335
  m_watches.clear();
-
 
336
  m_paths.clear();
240
}
337
}
241
338
242
void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException)
339
void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException)
243
{
340
{
244
  ssize_t len = 0;
341
  ssize_t len = 0;
245
 
342
 
246
  do {
343
  do {
247
    len = read(m_fd, m_buf, INOTIFY_BUFLEN);
344
    len = read(m_fd, m_buf, INOTIFY_BUFLEN);
248
  } while (fNoIntr && len == -1 && errno == EINTR);
345
  } while (fNoIntr && len == -1 && errno == EINTR);
249
 
346
 
250
  if (errno == EWOULDBLOCK)
347
  if (errno == EWOULDBLOCK)
251
    return;
348
    return;
252
 
349
 
253
  if (len < 0)
350
  if (len < 0)
254
    throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this);
351
    throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this);
255
 
352
 
256
  ssize_t i = 0;
353
  ssize_t i = 0;
257
  while (i < len) {
354
  while (i < len) {
258
    struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i];
355
    struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i];
259
    InotifyWatch* pW = FindWatch(pEvt->wd);
356
    InotifyWatch* pW = FindWatch(pEvt->wd);
260
    if (pW != NULL && pW->IsEnabled()) {
357
    if (pW != NULL) {
261
      InotifyEvent evt(pEvt, pW);
358
      InotifyEvent evt(pEvt, pW);
262
      m_events.push_back(evt);
359
      m_events.push_back(evt);
263
    }
360
    }
264
    i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
361
    i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
265
  }
362
  }
266
}
363
}
267
 
364
 
268
int Inotify::GetEventCount()
365
int Inotify::GetEventCount()
269
{
366
{
270
  return m_events.size();
367
  return m_events.size();
271
}
368
}
272
 
369
 
273
bool Inotify::GetEvent(InotifyEvent* pEvt) throw (InotifyException)
370
bool Inotify::GetEvent(InotifyEvent* pEvt) throw (InotifyException)
274
{
371
{
275
  bool b = PeekEvent(pEvt);
372
  bool b = PeekEvent(pEvt);
276
 
373
 
277
  if (b)
374
  if (b)
278
    m_events.pop_front();
375
    m_events.pop_front();
279
   
376
   
280
  return b;
377
  return b;
281
}
378
}
282
 
379
 
283
bool Inotify::PeekEvent(InotifyEvent* pEvt) throw (InotifyException)
380
bool Inotify::PeekEvent(InotifyEvent* pEvt) throw (InotifyException)
284
{
381
{
285
  if (pEvt == NULL)
382
  if (pEvt == NULL)
286
    throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
383
    throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
287
 
384
 
288
  if (!m_events.empty()) {
385
  if (!m_events.empty()) {
289
    *pEvt = m_events.front();
386
    *pEvt = m_events.front();
290
    return true;
387
    return true;
291
  }
388
  }
292
 
389
 
293
  return false;
390
  return false;
294
}
391
}
295
392
296
InotifyWatch* Inotify::FindWatch(int iDescriptor)
393
InotifyWatch* Inotify::FindWatch(int iDescriptor)
297
{
394
{
298
  IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor);
395
  IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor);
299
  if (it == m_watches.end())
396
  if (it == m_watches.end())
300
    return NULL;
397
    return NULL;
-
 
398
   
-
 
399
  return (*it).second;
-
 
400
}
-
 
401
-
 
402
InotifyWatch* Inotify::FindWatch(const std::string& rPath)
-
 
403
{
-
 
404
  IN_WP_MAP::iterator it = m_paths.find(rPath);
-
 
405
  if (it == m_paths.end())
-
 
406
    return NULL;
301
   
407
   
302
  return (*it).second;
408
  return (*it).second;
303
}
409
}
304
 
410
 
305
void Inotify::SetNonBlock(bool fNonBlock) throw (InotifyException)
411
void Inotify::SetNonBlock(bool fNonBlock) throw (InotifyException)
306
{
412
{
307
  if (m_fd == -1)
413
  if (m_fd == -1)
308
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
414
    throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
309
   
415
   
310
  int res = fcntl(m_fd, F_GETFL);
416
  int res = fcntl(m_fd, F_GETFL);
311
  if (res == -1)
417
  if (res == -1)
312
    throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
418
    throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
313
 
419
 
314
  if (fNonBlock) {
420
  if (fNonBlock) {
315
    res |= O_NONBLOCK;
421
    res |= O_NONBLOCK;
316
  }
422
  }
317
  else {
423
  else {
318
    res &= ~O_NONBLOCK;
424
    res &= ~O_NONBLOCK;
319
  }
425
  }
320
     
426
     
321
  if (fcntl(m_fd, F_SETFL, res) == -1)
427
  if (fcntl(m_fd, F_SETFL, res) == -1)
322
    throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
428
    throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
323
}  
429
}  
324
430
325
 
431