Implement a subroutine for reporting filesystem events
authorcoderain <coderain@sdf.org>
Fri, 21 Jul 2017 05:06:03 +0000 (07:06 +0200)
committercoderain <coderain@sdf.org>
Fri, 21 Jul 2017 05:06:03 +0000 (07:06 +0200)
kernel/include/filesystem.h
kernel/src/filesystem.c

index 786a53289ff4a9bed9c10b4c6006271f872364a6..8d3c7410e9e97274e606b85c6e9918019049e90d 100644 (file)
@@ -167,5 +167,6 @@ dword_t read_file(handle_t handle, void *buffer, qword_t offset, size_t size, si
 dword_t write_file(handle_t handle, const void *buffer, qword_t offset, size_t size, size_t *bytes_written);
 dword_t mount(const char *device, const char *mountpoint, const char *filesystem, dword_t flags);
 dword_t unmount(const char *device);
+void report_filesystem_event(const char *path, dword_t type);
 
 #endif
index 47dd3dec9df511fbe0b7352fac8083d83ece117e..db5a6875215463093582225842489f433030eba5 100644 (file)
@@ -38,6 +38,44 @@ static inline int count_delimiters(const char *string)
     return count;
 }
 
+void report_filesystem_event(const char *path, dword_t type)
+{
+    list_entry_t *ptr;
+    int path_length = strlen(path);
+    acquire_lock(&event_watch_list_lock);
+
+    for (ptr = event_watch_list.next; ptr != &event_watch_list; ptr = ptr->next)
+    {
+        event_watch_entry_t *watch = CONTAINER_OF(ptr, event_watch_entry_t, list);
+        reference(&watch->directory->header);
+        int prefix_length = strlen(watch->directory->global->path);
+
+        if (strncmp(path, watch->directory->global->path, prefix_length) == 0
+            && path[prefix_length] == PATH_DELIMITER_CHAR)
+        {
+            event_queue_entry_t *entry = (event_queue_entry_t*)malloc(sizeof(event_queue_entry_t) + path_length + 1);
+            entry->event.type = type;
+            strcpy(entry->event.filename, path);
+
+            acquire_lock(&watch->lock);
+            list_append(&watch->event_queue, &entry->list);
+            release_lock(&watch->lock);
+
+            if (release_semaphore(&watch->event_semaphore, 1) == ERR_INVALID)
+            {
+                acquire_lock(&watch->lock);
+                list_remove(&entry->list);
+                release_lock(&watch->lock);
+                free(entry);
+            }
+        }
+
+        dereference(&watch->directory->header);
+    }
+
+    release_lock(&event_watch_list_lock);
+}
+
 void file_cleanup(file_t *file)
 {
     acquire_resource_exclusive(&file->volume->resource);