diff options
-rw-r--r-- | src/lib/sysexchange.zig | 6 | ||||
-rw-r--r-- | src/lib/vfs.zig | 41 |
2 files changed, 32 insertions, 15 deletions
diff --git a/src/lib/sysexchange.zig b/src/lib/sysexchange.zig index d509e7a..5647663 100644 --- a/src/lib/sysexchange.zig +++ b/src/lib/sysexchange.zig @@ -66,6 +66,8 @@ pub const Status = enum(usize) { detached, orphaned, already_exists, + is_a_hook, + is_a_container, unknown = std.math.maxInt(usize), pub fn fromError(err: anyerror) Status { @@ -128,6 +130,8 @@ pub const Status = enum(usize) { error.Detached => .detached, error.Orphaned => .orphaned, error.AlreadyExists => .already_exists, + error.IsAHook => .is_a_hook, + error.IsAContainer => .is_a_container, else => .unknown, }; } @@ -195,6 +199,8 @@ pub const Status = enum(usize) { .detached => error.Detached, .orphaned => error.Orphaned, .already_exists => error.AlreadyExists, + .is_a_hook => error.IsAHook, + .is_a_container => error.IsAContainer, .unknown => error.Unknown, }; } diff --git a/src/lib/vfs.zig b/src/lib/vfs.zig index 2e3e844..10c961c 100644 --- a/src/lib/vfs.zig +++ b/src/lib/vfs.zig @@ -45,6 +45,8 @@ pub const Error = error{ Detached, Orphaned, AlreadyExists, + IsAHook, + IsAContainer, }; // A stream is a resource that provides a shared data stream with a driver. @@ -181,10 +183,13 @@ pub const ResourceDescriptor = struct { } pub fn read(self: ResourceDescriptor, proc: *process.Info, buffer: []u8) !usize { - return readHooked(self, proc, buffer, crossProcessReturn); + return readHooked(self, proc, buffer, .{ + .hookFn = crossProcessReturn, + .context = proc, + }); } - pub fn readHooked(self: ResourceDescriptor, proc: *process.Info, buffer: []u8, hookFn: TermHook.HookFn) !usize { + pub fn readHooked(self: ResourceDescriptor, proc: *process.Info, buffer: []u8, hook: TermHook) !usize { if (self.inode.flags.detached and self.inode.options.reclaimable) { return Error.Detached; } @@ -209,10 +214,7 @@ pub const ResourceDescriptor = struct { .cleanupFn = moveBack, .buffer = buffer, .copy = copy, - }, .{ - .hookFn = hookFn, - .context = proc, - }); + }, hook); }, .hook => Error.ReadNotSupported, else => Error.ReadNotSupported, @@ -220,10 +222,13 @@ pub const ResourceDescriptor = struct { } pub fn write(self: ResourceDescriptor, proc: *process.Info, bytes: []const u8) !usize { - return writeHooked(self, proc, bytes, crossProcessReturn); + return writeHooked(self, proc, bytes, .{ + .hookFn = crossProcessReturn, + .context = proc, + }); } - pub fn writeHooked(self: ResourceDescriptor, proc: *process.Info, bytes: []const u8, hookFn: TermHook.HookFn) !usize { + pub fn writeHooked(self: ResourceDescriptor, proc: *process.Info, bytes: []const u8, hook: TermHook) !usize { if (self.inode.flags.detached and self.inode.options.reclaimable) { return Error.Detached; } @@ -244,10 +249,7 @@ pub const ResourceDescriptor = struct { const copy = try driver.copyBytes(bytes); proc.state = .suspended; - try call(driver, writeFn, .{ copy.ptr, copy.len }, null, .{ - .hookFn = hookFn, - .context = proc, - }); + try call(driver, writeFn, .{ copy.ptr, copy.len }, null, hook); }, .hook => Error.WriteNotSupported, else => Error.WriteNotSupported, @@ -383,6 +385,17 @@ pub fn openZ(proc: *process.Info, path_c: [*:0]const u8, pid: u16, data: usize) return open(proc, mem.sliceTo(path_c, 0), pid, data); } +pub fn openNonHook(path: []const u8) !ResourceDescriptor { + const inode = find(path) orelse return Error.NotFound; + if (inode.resource.tag == .hook) return Error.IsAHook; + + return ResourceDescriptor.init(inode); +} + +pub fn openNonHookZ(path_c: [*:0]const u8) !ResourceDescriptor { + return openNonHook(mem.sliceTo(path_c, 0)); +} + fn call(proc: *process.Info, function: *const anyopaque, args: anytype, cleanup_hook: ?process.Info.CleanupHook, term_hook: ?process.Info.TermHook) !noreturn { const callback_thread = try proc.createThread(null); callback_thread.call(@intFromPtr(function), args, cleanup_hook, term_hook); @@ -392,7 +405,5 @@ fn crossProcessReturn(context: *anyopaque, driver: *const process.Info) void { const proc: *process.Info = @alignCast(@ptrCast(context)); proc.trap_frame.general_purpose_registers[10] = driver.trap_frame.general_purpose_registers[12]; proc.trap_frame.general_purpose_registers[11] = driver.trap_frame.general_purpose_registers[13]; - proc.pc += 4; // Skip ecall instruction - proc.state = .waiting; - // Scheduler is called by the "terminate" syscall after two layers of returning. + proc.allowResume(); } |