Archived
1
0
Fork 0
This repository has been archived on 2026-05-10. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
archived/src/inotify.c
Henrik Hautakoski f46ae1970b Change indentation to follow the updated standard.
Alot of mixed indentation. use 4 chars wide soft tabs.
2011-03-19 12:28:48 +02:00

145 lines
3.7 KiB
C

#include <stdlib.h>
#include "log.h"
#include "path.h"
#include "queue.h"
#include "path.h"
#include "inotify-backend.h"
#include "inotify-map.h"
#include "inotify.h"
static queue_t event_queue;
int inotify_init(void) {
inotify_backend_init();
event_queue = queue_init();
return 1;
}
void inotify_exit(void) {
inotify_backend_exit();
if (event_queue) {
notify_event *e;
while((e = queue_dequeue(event_queue)))
notify_event_del(e);
queue_destroy(event_queue);
event_queue = NULL;
}
}
int inotify_watch(const char *path) {
int wd = inotify_backend_watch(path);
if (wd > 0)
inotify_map(wd, path);
return wd;
}
int inotify_ignore(const char *path) {
int wd = inotify_map_get_wd(path);
if (wd <= 0)
return -1;
/* unmap and remove watch */
if (inotify_unmap_path(path) == 0) {
logmsg(LOG_DEBUG, "remove watch: %i %s", wd, path);
if (inotify_backend_ignore(wd) < 0)
return -1;
}
return 0;
}
static void proc_event(struct inotify_event *iev) {
int i;
struct list *watch_list;
logmsg(LOG_DEBUG, "RAW EVENT: %i, %x, %s", iev->wd, iev->mask, iev->name);
if (iev->mask & IN_IGNORED) {
inotify_unmap_wd(iev->wd);
return;
}
/* lookup watch descriptors */
watch_list = inotify_map_get_path(iev->wd);
if (!watch_list) {
logmsg(LOG_WARN, "-- IGNORING EVENT -- invalid watchdescriptor %i", iev->wd);
return;
}
for(i=0; i < watch_list->nr; i++) {
struct watch *watch = watch_list->items[i];
notify_event *event = notify_event_new();
notify_event_set_path(event, watch->path);
notify_event_set_filename(event, iev->name);
/*
* Because of limitation on the information we get from inotify
* We must do something else to find out what type a "file/link" should be.
*
* if CREATE or MOVED_TO:
* The file is present on the filesystem, so we
* only need to perform a simple system call.
*
* if DELETE or MOVED_FROM:
* The file is no longer present on the filesystem, but
* we will treat the symlink as a directory if we are
* watching the path. since we only watch directories.
* otherwise it may be a symlink we simple do not care about
* or some other file.
*/
if (iev->mask & IN_CREATE || iev->mask & IN_MOVED_TO) {
event->dir = (iev->mask & IN_ISDIR) ? 1 :
is_dir(mkpath("%s/%s", event->path, event->filename));
event->type = NOTIFY_CREATE;
} else if (iev->mask & IN_DELETE || iev->mask & IN_MOVED_FROM) {
if (iev->mask & IN_ISDIR) {
event->dir = 1;
} else {
const char *path = mkpath("%s%s/", event->path, event->filename);
if (inotify_map_get_wd(path) > 0) {
inotify_unmap_path(path);
event->dir = 1;
} else {
event->dir = 0;
}
}
event->type = NOTIFY_DELETE;
} else {
event->type = NOTIFY_UNKNOWN;
}
queue_enqueue(event_queue, event);
}
list_destroy(watch_list);
}
notify_event* inotify_read(void) {
char buf[4096];
int read, offset = 0;
read = inotify_backend_read(buf, sizeof(buf));
while(read > offset) {
struct inotify_event *ev = (struct inotify_event*) &buf[offset];
proc_event(ev);
offset += sizeof(struct inotify_event) + ev->len;
}
return queue_dequeue(event_queue);
}