summaryrefslogtreecommitdiff
path: root/Kernel/Process.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-07-22 20:01:11 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-07-22 20:01:11 +0200
commitc8e2bb5605adea7fff02a0e51b8246f944ba29ad (patch)
treeac7155364208f7dd559a5d594e1a47df93427cd0 /Kernel/Process.cpp
parenta9adf4c95b8ee3ba892878daec81d6cfc809be75 (diff)
downloadserenity-c8e2bb5605adea7fff02a0e51b8246f944ba29ad.zip
Kernel: Add a mechanism for listening for changes to an inode.
The syscall is quite simple: int watch_file(const char* path, int path_length); It returns a file descriptor referring to a "InodeWatcher" object in the kernel. It becomes readable whenever something changes about the inode. Currently this is implemented by hooking the "metadata dirty bit" in Inode which isn't perfect, but it's a start. :^)
Diffstat (limited to 'Kernel/Process.cpp')
-rw-r--r--Kernel/Process.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index e32d6b50cd..b0720f928e 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -10,6 +10,7 @@
#include <Kernel/FileSystem/Custody.h>
#include <Kernel/FileSystem/FIFO.h>
#include <Kernel/FileSystem/FileDescription.h>
+#include <Kernel/FileSystem/InodeWatcher.h>
#include <Kernel/FileSystem/SharedMemory.h>
#include <Kernel/FileSystem/VirtualFileSystem.h>
#include <Kernel/IO.h>
@@ -2638,6 +2639,26 @@ int Process::sys$ftruncate(int fd, off_t length)
return description->truncate(length);
}
+int Process::sys$watch_file(const char* path, int path_length)
+{
+ if (!validate_read(path, path_length))
+ return -EFAULT;
+
+ auto custody_or_error = VFS::the().resolve_path({ path, path_length }, current_directory());
+ if (custody_or_error.is_error())
+ return custody_or_error.error();
+
+ auto& custody = custody_or_error.value();
+ auto& inode = custody->inode();
+
+ int fd = alloc_fd();
+ if (fd < 0)
+ return fd;
+
+ m_fds[fd].set(FileDescription::create(*InodeWatcher::create(inode)));
+ return fd;
+}
+
int Process::sys$systrace(pid_t pid)
{
InterruptDisabler disabler;