aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-07-10 16:06:53 +0200
committerHimbeer <himbeer@disroot.org>2024-07-10 16:06:53 +0200
commit16282fe4dce325acb293b23d02d5fa4bab9481ff (patch)
treec0788e90c334f53a0fa6d962e495f9ac68dff9b2
parent6b1eef5e7e4c2ee0f51ee1d5a258e86b08b22298 (diff)
vfs: Support providing sub-resources of dirhooks
-rw-r--r--src/lib/sysexchange.zig13
-rw-r--r--src/lib/vfs.zig13
2 files changed, 24 insertions, 2 deletions
diff --git a/src/lib/sysexchange.zig b/src/lib/sysexchange.zig
index 01220b0..0abf7bc 100644
--- a/src/lib/sysexchange.zig
+++ b/src/lib/sysexchange.zig
@@ -15,6 +15,15 @@ pub const Status = enum(usize) {
else => .unknown,
};
}
+
+ // Calling this on the "success" variant is safety-checked
+ // undefined behavior at runtime.
+ pub fn toError(self: Status) anyerror {
+ return switch (self) {
+ .success => unreachable,
+ .unknown => error.Unknown,
+ };
+ }
};
pub fn Result(comptime T: type) type {
@@ -46,6 +55,10 @@ pub fn Result(comptime T: type) type {
},
};
}
+
+ pub fn toErrorUnion(self: Self) !T {
+ return if (self.status == .success) self.value else self.status.toError();
+ }
};
}
diff --git a/src/lib/vfs.zig b/src/lib/vfs.zig
index 4285b79..3c3099a 100644
--- a/src/lib/vfs.zig
+++ b/src/lib/vfs.zig
@@ -62,7 +62,7 @@ pub const DirHook = extern struct {
findFn: FindFn,
removeFn: RemoveFn,
- pub const ProvideFn = *allowzero const fn (inode: Inode) callconv(.C) sysexchange.Result(void);
+ pub const ProvideFn = *allowzero const fn (name_ptr: [*]const u8, name_len: usize, inode: Inode) callconv(.C) sysexchange.Result(void);
pub const FindFn = *allowzero const fn (name_ptr: [*]const u8, name_len: usize) callconv(.C) ?*Inode;
pub const RemoveFn = *allowzero const fn (name_ptr: [*]const u8, name_len: usize) callconv(.C) sysexchange.Result(void);
};
@@ -252,18 +252,27 @@ pub fn provideResource(path: []const u8, resource: Resource, pid: u16) !void {
const dirname = std.fs.path.dirnamePosix(path) orelse return Error.NoAbsoluteContainingDirectory;
if (find(dirname)) |inode| {
+ const basename = std.fs.path.basenamePosix(path);
return switch (inode.resource.tag) {
.dir => blk: {
const dir = inode.resource.data.dir;
break :blk dir.provideResource(.{
- .name = std.fs.path.basenamePosix(path),
+ .name = basename,
.inode = .{
.resource = resource,
.pid = pid,
},
});
},
+ .dir_hook => blk: {
+ const dir_hook = inode.resource.data.dir_hook;
+
+ break :blk dir_hook.provideFn(basename.ptr, basename.len, .{
+ .resource = resource,
+ .pid = pid,
+ }).toErrorUnion();
+ },
else => Error.NotADirectory,
};
} else return Error.NotFound;