diff options
author | Himbeer <himbeer@disroot.org> | 2024-07-10 16:06:53 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-07-10 16:06:53 +0200 |
commit | 16282fe4dce325acb293b23d02d5fa4bab9481ff (patch) | |
tree | c0788e90c334f53a0fa6d962e495f9ac68dff9b2 | |
parent | 6b1eef5e7e4c2ee0f51ee1d5a258e86b08b22298 (diff) |
vfs: Support providing sub-resources of dirhooks
-rw-r--r-- | src/lib/sysexchange.zig | 13 | ||||
-rw-r--r-- | src/lib/vfs.zig | 13 |
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; |