12 #include <mrpt/config.h> 16 #define _WIN32_WINNT 0x0400 21 #include <sys/inotify.h> 42 : m_watchedDirectory(path)
53 HANDLE hDir = CreateFileA(
54 path.c_str(), FILE_LIST_DIRECTORY,
55 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
57 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,
nullptr);
58 if (hDir == INVALID_HANDLE_VALUE)
73 m_fd = inotify_init();
77 m_wd = inotify_add_watch(
79 IN_CLOSE_WRITE | IN_DELETE | IN_MOVED_TO | IN_MOVED_FROM | IN_CREATE |
108 if (m_wd >= 0) inotify_rm_watch(m_fd, m_wd);
125 "CFileSystemWatcher was not initialized correctly.");
143 out_list.push_back(*obj);
150 if (m_fd < 0)
return;
172 ret = select(m_fd + 1, &rfds,
nullptr,
nullptr, &time);
175 perror(
"[CFileSystemWatcher::getChanges] select");
183 else if (FD_ISSET(m_fd, &rfds))
188 #define EVENT_SIZE (sizeof(struct inotify_event)) 191 #define BUF_LEN (1024 * (EVENT_SIZE + 16)) 196 const auto len = read(m_fd, buf, BUF_LEN);
204 perror(
"[CFileSystemWatcher::getChanges] read");
213 struct inotify_event event_val
219 struct inotify_event*
event = &event_val;
221 i += EVENT_SIZE +
event->len;
227 if (event->len) eventName =
event->name;
231 if (0 == (event->mask & IN_UNMOUNT) &&
232 0 == (event->mask & IN_Q_OVERFLOW) &&
233 0 == (event->mask & IN_IGNORED))
238 newEntry.
isDir =
event->mask & IN_ISDIR;
247 out_list.push_back(newEntry);
259 uint8_t buf[8 * 1024];
262 while (ReadDirectoryChangesW(
265 FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME |
266 FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE |
267 FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS |
268 FILE_NOTIFY_CHANGE_CREATION,
269 &dwRead,
nullptr,
nullptr))
278 FILE_NOTIFY_INFORMATION* fni =
279 reinterpret_cast<FILE_NOTIFY_INFORMATION*
>(&buf[idx]);
283 fni->FileNameLength < 10000,
284 "Name length >10K... this is probably an error");
286 int reqLen = WideCharToMultiByte(
287 CP_UTF8, 0, fni->FileName, fni->FileNameLength >> 1,
nullptr, 0,
289 std::vector<char> tmpBuf(reqLen);
290 int actLen = WideCharToMultiByte(
291 CP_UTF8, 0, fni->FileName, fni->FileNameLength >> 1, &tmpBuf[0],
292 tmpBuf.size(),
nullptr,
nullptr);
294 actLen > 0,
"Error converting filename from WCHAR* to UTF8");
296 const std::string filName(&tmpBuf[0], actLen);
306 case FILE_ACTION_ADDED:
313 case FILE_ACTION_REMOVED:
320 case FILE_ACTION_MODIFIED:
327 case FILE_ACTION_RENAMED_OLD_NAME:
334 case FILE_ACTION_RENAMED_NEW_NAME:
344 if (fni->NextEntryOffset > 0)
345 idx += fni->NextEntryOffset;
#define THROW_EXCEPTION(msg)
std::queue< TFileSystemChange * > m_queue_events_win32_msgs
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.
std::deque< TFileSystemChange > TFileSystemChangeList
std::string m_watchedDirectory
Ended in "/".
std::thread m_watchThread
#define ASSERT_(f)
Defines an assertion mechanism.
void thread_win32_watch()
Watch thread; only needed in win32.
#define ASSERTMSG_(f, __ERROR_MSG)
Defines an assertion mechanism.
std::mutex m_queue_events_win32_cs
bool isDir
Whether the event happened to a file or a directory.
virtual ~CFileSystemWatcher()
Destructor.
Each of the changes detected by utils::CFileSystemWatcher.
bool directoryExists(const std::string &fileName)
Test if a given directory exists (it fails if the given path refers to an existing file)...
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
CFileSystemWatcher(const std::string &path)
Creates the subscription to a specified path.