12 #include <mrpt/config.h> 14 #ifdef MRPT_OS_WINDOWS 16 # define _WIN32_WINNT 0x0400 21 #include <sys/inotify.h> 42 m_watchedDirectory(path)
50 #ifdef MRPT_OS_WINDOWS 52 HANDLE hDir = CreateFileA(
55 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
58 FILE_FLAG_BACKUP_SEMANTICS,
60 if( hDir == INVALID_HANDLE_VALUE )
66 m_hNotif =
static_cast<void*
>(hDir);
75 m_fd = inotify_init();
80 m_wd = inotify_add_watch(
83 IN_CLOSE_WRITE | IN_DELETE | IN_MOVED_TO | IN_MOVED_FROM | IN_CREATE | IN_ACCESS
99 #ifdef MRPT_OS_WINDOWS 104 if (!m_watchThread.isClear())
106 CloseHandle(HANDLE(m_hNotif));
110 # if MRPT_HAS_INOTIFY 117 inotify_rm_watch(m_fd, m_wd);
130 #ifdef MRPT_OS_WINDOWS 132 ASSERTMSG_(m_hNotif!=NULL,
"CFileSystemWatcher was not initialized correctly.")
136 while (!m_queue_events_win32.empty())
141 out_list.push_back(*
obj);
148 # if MRPT_HAS_INOTIFY 167 FD_SET (m_fd, &rfds);
169 ret = select (m_fd + 1, &rfds, NULL, NULL, &time);
172 perror (
"[CFileSystemWatcher::getChanges] select");
180 else if (FD_ISSET (m_fd, &rfds))
185 #define EVENT_SIZE (sizeof (struct inotify_event)) 188 #define BUF_LEN (1024 * (EVENT_SIZE + 16)) 193 len = read (m_fd, buf, BUF_LEN);
201 perror (
"[CFileSystemWatcher::getChanges] read");
210 struct inotify_event event_val;
211 ::memcpy(&event_val, &buf[i],
sizeof(event_val));
212 struct inotify_event *
event = &event_val;
214 i += EVENT_SIZE +
event->len;
219 if (event->len) eventName =
event->name;
223 if ( 0==(event->mask & IN_UNMOUNT) &&
224 0==(event->mask & IN_Q_OVERFLOW) &&
225 0==(event->mask & IN_IGNORED) )
230 newEntry.
isDir =
event->mask & IN_ISDIR;
239 out_list.push_back( newEntry );
250 #ifdef MRPT_OS_WINDOWS 252 void CFileSystemWatcher::thread_win32_watch()
258 while(ReadDirectoryChangesW(
263 FILE_NOTIFY_CHANGE_FILE_NAME |
264 FILE_NOTIFY_CHANGE_DIR_NAME |
265 FILE_NOTIFY_CHANGE_ATTRIBUTES |
266 FILE_NOTIFY_CHANGE_SIZE |
267 FILE_NOTIFY_CHANGE_LAST_WRITE |
268 FILE_NOTIFY_CHANGE_LAST_ACCESS |
269 FILE_NOTIFY_CHANGE_CREATION,
280 FILE_NOTIFY_INFORMATION *fni =
reinterpret_cast<FILE_NOTIFY_INFORMATION*
>(&buf[idx]);
283 ASSERTMSG_(fni->FileNameLength<10000,
"Name length >10K... this is probably an error")
285 int reqLen = WideCharToMultiByte(CP_UTF8,0,fni->FileName,fni->FileNameLength >> 1,NULL,0,NULL, NULL);
286 std::vector<
char> tmpBuf(reqLen);
287 int actLen = WideCharToMultiByte(CP_UTF8,0,fni->FileName,fni->FileNameLength >> 1,&tmpBuf[0],tmpBuf.
size(),NULL, NULL);
288 ASSERTMSG_(actLen>0,"Error converting filename from WCHAR* to UTF8")
290 const
std::
string filName(&tmpBuf[0],actLen);
292 TFileSystemChange newEntry;
299 case FILE_ACTION_ADDED:
301 newEntry.eventCreated =
true;
302 m_queue_events_win32.push(
new TFileSystemChange(newEntry));
304 case FILE_ACTION_REMOVED:
306 newEntry.eventDeleted =
true;
307 m_queue_events_win32.push(
new TFileSystemChange(newEntry));
309 case FILE_ACTION_MODIFIED:
311 newEntry.eventModified =
true;
312 m_queue_events_win32.push(
new TFileSystemChange(newEntry));
314 case FILE_ACTION_RENAMED_OLD_NAME:
316 newEntry.eventMovedFrom =
true;
317 m_queue_events_win32.push(
new TFileSystemChange(newEntry));
319 case FILE_ACTION_RENAMED_NEW_NAME:
321 newEntry.eventMovedTo =
true;
322 m_queue_events_win32.push(
new TFileSystemChange(newEntry));
327 if (fni->NextEntryOffset>0)
328 idx+=fni->NextEntryOffset;
void BASE_IMPEXP memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) MRPT_NO_THROWS
An OS and compiler independent version of "memcpy".
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
#define THROW_EXCEPTION(msg)
std::string path
Complete path of the file/directory that has changed.
void getChanges(TFileSystemChangeList &out_list)
Call this method sometimes to get the list of changes in the watched directory.
GLsizei GLsizei GLuint * obj
std::string m_watchedDirectory
Ended in "/".
std::deque< TFileSystemChange > TFileSystemChangeList
GLsizei const GLchar ** string
TThreadHandle createThreadFromObjectMethod(CLASS *obj, void(CLASS::*func)(PARAM), PARAM param)
Creates a new thread running a non-static method (so it will have access to "this") from another meth...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
bool isDir
Whether the event happened to a file or a directory.
virtual ~CFileSystemWatcher()
Destructor.
void BASE_IMPEXP terminateThread(TThreadHandle &threadHandle) MRPT_NO_THROWS
Terminate a thread, giving it no choice to delete objects, etc (use only as a last resource) ...
Each of the changes detected by utils::CFileSystemWatcher.
bool BASE_IMPEXP directoryExists(const std::string &fileName)
Test if a given directory exists (it fails if the given path refers to an existing file)...
#define ASSERTMSG_(f, __ERROR_MSG)
CFileSystemWatcher(const std::string &path)
Creates the subscription to a specified path.