diff --git a/src/monitor.cpp b/src/monitor.cpp index de41db2..05fedc0 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -10,28 +10,47 @@ #include "monitor.h" -static void * inotify_thd(void *p) +void Monitor::inject_event(bool is_add, const char *path) +{ + SDL_UserEvent e = { + .type = SDL_USEREVENT, + .code = (int) is_add, + .data1 = strdup(path), + .data2 = NULL, + }; + + /* Inject an user event, that will be handled as a "repaint" + * event by the InputManager */ + SDL_PushEvent((SDL_Event *) &e); +} + +bool Monitor::event_accepted(struct inotify_event &event) +{ + /* Don't bother other files than OPKs */ + size_t len = strlen(event.name); + return len >= 5 && !strncmp(event.name + len - 4, ".opk", 4); +} + +int Monitor::run(void) { - const char *path = (const char *) p; int wd, fd; - DEBUG("Starting inotify thread for path %s...\n", path); + DEBUG("Starting inotify thread for path %s...\n", path.c_str()); fd = inotify_init(); - if (fd == -1) { + if (fd < 0) { ERROR("Unable to start inotify\n"); - return NULL; + return fd; } - wd = inotify_add_watch(fd, path, IN_MOVED_FROM | IN_MOVED_TO | - IN_CLOSE_WRITE | IN_DELETE | IN_CREATE); - if (wd == -1) { + wd = inotify_add_watch(fd, path.c_str(), mask); + if (wd < 0) { ERROR("Unable to add inotify watch\n"); close(fd); - return NULL; + return wd; } - DEBUG("Starting watching directory %s\n", path); + DEBUG("Starting watching directory %s\n", path.c_str()); for (;;) { size_t len = sizeof(struct inotify_event) + NAME_MAX + 1; @@ -39,30 +58,29 @@ static void * inotify_thd(void *p) char buf[256]; read(fd, &event, len); - sprintf(buf, "%s/%s", path, event.name); + sprintf(buf, "%s/%s", path.c_str(), event.name); - /* Don't bother other files than OPKs */ - len = strlen(event.name); - if (len < 5 || strncmp(event.name + len - 4, ".opk", 4)) + if (!event_accepted(event)) continue; - SDL_UserEvent e = { - .type = SDL_USEREVENT, - .code = (int) (event.mask & - (IN_MOVED_TO | IN_CLOSE_WRITE | IN_CREATE)), - .data1 = strdup(buf), - .data2 = NULL, - }; - - /* Inject an user event, that will be handled as a "repaint" - * event by the InputManager */ - SDL_PushEvent((SDL_Event *) &e); + inject_event(event.mask & (IN_MOVED_TO | IN_CLOSE_WRITE | + IN_CREATE), buf); } + + return 0; } -Monitor::Monitor(std::string path) : path(path) +static void * inotify_thd(void *p) { - pthread_create(&thd, NULL, inotify_thd, (void *) path.c_str()); + Monitor *monitor = (Monitor *) p; + monitor->run(); + return NULL; +} + +Monitor::Monitor(std::string path, unsigned int flags) : path(path) +{ + mask = flags; + pthread_create(&thd, NULL, inotify_thd, (void *) this); } Monitor::~Monitor(void) diff --git a/src/monitor.h b/src/monitor.h index 8e35096..17ee06c 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -1,17 +1,28 @@ #ifndef __MONITOR_H__ #define __MONITOR_H__ +#ifdef ENABLE_INOTIFY -#include #include +#include +#include class Monitor { public: - Monitor(std::string path); - ~Monitor(); + Monitor(std::string path, unsigned int flags = IN_MOVE | + IN_CLOSE_WRITE | IN_DELETE | IN_CREATE); + virtual ~Monitor(); + + int run(void); private: std::string path; pthread_t thd; + +protected: + unsigned int mask; + virtual bool event_accepted(struct inotify_event &event); + virtual void inject_event(bool is_add, const char *path); }; +#endif #endif /* __MONITOR_H__ */