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(
78 m_fd, path.c_str(), IN_CLOSE_WRITE | IN_DELETE | IN_MOVED_TO |
79 IN_MOVED_FROM | IN_CREATE | IN_ACCESS);
107 if (m_wd >= 0) inotify_rm_watch(m_fd, m_wd);
124 "CFileSystemWatcher was not initialized correctly.");
142 out_list.push_back(*
obj);
149 if (m_fd < 0)
return;
169 ret = select(m_fd + 1, &rfds,
nullptr,
nullptr, &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;
214 struct inotify_event*
event = &event_val;
216 i += EVENT_SIZE +
event->len;
222 if (event->len) eventName =
event->name;
226 if (0 == (event->mask & IN_UNMOUNT) &&
227 0 == (event->mask & IN_Q_OVERFLOW) &&
228 0 == (event->mask & IN_IGNORED))
233 newEntry.
isDir =
event->mask & IN_ISDIR;
242 out_list.push_back(newEntry);
257 while (ReadDirectoryChangesW(
260 FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME |
261 FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE |
262 FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS |
263 FILE_NOTIFY_CHANGE_CREATION,
264 &dwRead,
nullptr,
nullptr))
273 FILE_NOTIFY_INFORMATION* fni =
274 reinterpret_cast<FILE_NOTIFY_INFORMATION*
>(&buf[idx]);
278 fni->FileNameLength < 10000,
279 "Name length >10K... this is probably an error");
281 int reqLen = WideCharToMultiByte(
282 CP_UTF8, 0, fni->FileName, fni->FileNameLength >> 1,
nullptr, 0,
284 std::vector<char> tmpBuf(reqLen);
285 int actLen = WideCharToMultiByte(
286 CP_UTF8, 0, fni->FileName, fni->FileNameLength >> 1, &tmpBuf[0],
287 tmpBuf.size(),
nullptr,
nullptr);
289 actLen > 0,
"Error converting filename from WCHAR* to UTF8");
301 case FILE_ACTION_ADDED:
308 case FILE_ACTION_REMOVED:
315 case FILE_ACTION_MODIFIED:
322 case FILE_ACTION_RENAMED_OLD_NAME:
329 case FILE_ACTION_RENAMED_NEW_NAME:
339 if (fni->NextEntryOffset > 0)
340 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
GLsizei GLsizei GLuint * obj
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
GLsizei const GLchar ** string
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.