12 #include <mrpt/config.h>    14 #ifdef MRPT_OS_WINDOWS    16 #define _WIN32_WINNT 0x0400    21 #include <sys/inotify.h>    42         : m_watchedDirectory(path)
    51 #ifdef MRPT_OS_WINDOWS    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)
    64         m_hNotif = 
static_cast<void*
>(hDir);
    66         m_watchThread = std::thread(&CFileSystemWatcher::thread_win32_watch, 
this);
    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);
    92 #ifdef MRPT_OS_WINDOWS    97                 CloseHandle(HANDLE(m_hNotif));
   107                 if (m_wd >= 0) inotify_rm_watch(m_fd, m_wd);
   120 #ifdef MRPT_OS_WINDOWS   124                 "CFileSystemWatcher was not initialized correctly.")
   128         while (!m_queue_events_win32.empty())
   133                         out_list.push_back(*
obj);
   140         if (m_fd < 0) 
return;  
   160         ret = select(m_fd + 1, &rfds, 
nullptr, 
nullptr, &time);
   163                 perror(
"[CFileSystemWatcher::getChanges] select");
   171         else if (FD_ISSET(m_fd, &rfds))
   176 #define EVENT_SIZE (sizeof(struct inotify_event))   179 #define BUF_LEN (1024 * (EVENT_SIZE + 16))   184                 len = read(m_fd, buf, BUF_LEN);
   192                                 perror(
"[CFileSystemWatcher::getChanges] read");
   201                         struct inotify_event event_val;
   205                         struct inotify_event* 
event = &event_val;
   207                         i += EVENT_SIZE + 
event->len;
   213                         if (event->len) eventName = 
event->name;
   217                         if (0 == (event->mask & IN_UNMOUNT) &&
   218                                 0 == (event->mask & IN_Q_OVERFLOW) &&
   219                                 0 == (event->mask & IN_IGNORED))
   224                                 newEntry.
isDir = 
event->mask & IN_ISDIR;
   233                                 out_list.push_back(newEntry);
   241 #ifdef MRPT_OS_WINDOWS   243 void CFileSystemWatcher::thread_win32_watch()
   248         while (ReadDirectoryChangesW(
   249                 HANDLE(m_hNotif), buf, 
sizeof(buf),
   251                 FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME |
   252                         FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE |
   253                         FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS |
   254                         FILE_NOTIFY_CHANGE_CREATION,
   255                 &dwRead, 
nullptr, 
nullptr))
   264                         FILE_NOTIFY_INFORMATION* fni =
   265                                 reinterpret_cast<FILE_NOTIFY_INFORMATION*
>(&buf[idx]);
   269                                 fni->FileNameLength < 10000,
   270                                 "Name length >10K... this is probably an error")
   272                         int reqLen = WideCharToMultiByte(
   273                                 CP_UTF8, 0, fni->FileName, fni->FileNameLength >> 1, 
nullptr, 0,
   275                         std::vector<
char> tmpBuf(reqLen);
   276                         int actLen = WideCharToMultiByte(
   277                                 CP_UTF8, 0, fni->FileName, fni->FileNameLength >> 1, &tmpBuf[0],
   278                                 tmpBuf.
size(), 
nullptr, 
nullptr);
   280                                 actLen > 0, "Error converting filename from WCHAR* to UTF8")
   282                         const 
std::
string filName(&tmpBuf[0], actLen);
   284                         TFileSystemChange newEntry;
   291                                 case FILE_ACTION_ADDED:
   293                                         newEntry.eventCreated = 
true;
   294                                         m_queue_events_win32.push(
new TFileSystemChange(newEntry));
   297                                 case FILE_ACTION_REMOVED:
   299                                         newEntry.eventDeleted = 
true;
   300                                         m_queue_events_win32.push(
new TFileSystemChange(newEntry));
   303                                 case FILE_ACTION_MODIFIED:
   305                                         newEntry.eventModified = 
true;
   306                                         m_queue_events_win32.push(
new TFileSystemChange(newEntry));
   309                                 case FILE_ACTION_RENAMED_OLD_NAME:
   311                                         newEntry.eventMovedFrom = 
true;
   312                                         m_queue_events_win32.push(
new TFileSystemChange(newEntry));
   315                                 case FILE_ACTION_RENAMED_NEW_NAME:
   317                                         newEntry.eventMovedTo = 
true;
   318                                         m_queue_events_win32.push(
new TFileSystemChange(newEntry));
   324                         if (fni->NextEntryOffset > 0)
   325                                 idx += fni->NextEntryOffset;
 
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
 
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. 
 
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)...
 
#define ASSERTMSG_(f, __ERROR_MSG)
 
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.