Root/src/monitor.cpp

Source at commit 73ceffa51d3450d2d20ce933e7fc6da187e09fc8 created 7 years 5 months ago.
By Maarten ter Huurne, Fix bug in section directory creation method
1#ifdef ENABLE_INOTIFY
2#include "debug.h"
3
4#include <climits>
5#include <dirent.h>
6#include <pthread.h>
7#include <SDL.h>
8#include <signal.h>
9#include <sys/inotify.h>
10#include <unistd.h>
11
12#include "inputmanager.h"
13#include "monitor.h"
14#include "utilities.h"
15
16void Monitor::inject_event(bool is_add, const char *path)
17{
18    if (is_add)
19        inject_user_event(OPEN_PACKAGE, strdup(path));
20    else
21        inject_user_event(REMOVE_LINKS, strdup(path));
22}
23
24bool Monitor::event_accepted(struct inotify_event &event)
25{
26    /* Don't bother other files than OPKs */
27    size_t len = strlen(event.name);
28    return len >= 5 && !strncmp(event.name + len - 4, ".opk", 4);
29}
30
31int Monitor::run()
32{
33    DEBUG("Starting inotify thread for path %s...\n", path.c_str());
34
35    int fd = inotify_init1(IN_CLOEXEC);
36    if (fd < 0) {
37        ERROR("Unable to start inotify\n");
38        return fd;
39    }
40
41    int wd = inotify_add_watch(fd, path.c_str(), mask);
42    if (wd < 0) {
43        ERROR("Unable to add inotify watch on '%s': %s\n",
44                path.c_str(), strerror(errno));
45        close(fd);
46        return wd;
47    }
48
49    DEBUG("Starting watching directory %s\n", path.c_str());
50
51    for (;;) {
52        size_t len = sizeof(struct inotify_event) + NAME_MAX + 1;
53        struct inotify_event event;
54        char buf[256];
55
56        read(fd, &event, len);
57
58        if (event.mask & (IN_DELETE_SELF | IN_MOVE_SELF)) {
59            inject_event(false, path.c_str());
60            break;
61        }
62
63        sprintf(buf, "%s/%s", path.c_str(), event.name);
64
65        if (!event_accepted(event))
66            continue;
67
68        inject_event(event.mask & (IN_MOVED_TO | IN_CLOSE_WRITE | IN_CREATE), buf);
69    }
70
71    return 0;
72}
73
74static void * inotify_thd(void *p)
75{
76    Monitor *monitor = (Monitor *) p;
77    monitor->run();
78    return NULL;
79}
80
81Monitor::Monitor(std::string path, unsigned int flags) : path(path)
82{
83    mask = flags;
84    pthread_create(&thd, NULL, inotify_thd, (void *) this);
85}
86
87Monitor::~Monitor()
88{
89    pthread_cancel(thd);
90    pthread_join(thd, NULL);
91    DEBUG("Monitor thread stopped (was watching %s)\n", path.c_str());
92}
93#endif
94

Archive Download this file



interactive