aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/sysexchange.zig6
-rw-r--r--src/lib/vfs.zig41
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();
}