diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/process.zig | 1 | ||||
-rw-r--r-- | src/lib/syscall.zig | 28 | ||||
-rw-r--r-- | src/lib/vfs.zig | 28 |
3 files changed, 57 insertions, 0 deletions
diff --git a/src/lib/process.zig b/src/lib/process.zig index fe5e3cf..13f7b06 100644 --- a/src/lib/process.zig +++ b/src/lib/process.zig @@ -28,6 +28,7 @@ pub const Error = error{ pub const ProcessError = error{ TooManyResourceDescriptors, + BadRdHandle, }; pub const ExeError = error{ diff --git a/src/lib/syscall.zig b/src/lib/syscall.zig index 55a7da3..8dda736 100644 --- a/src/lib/syscall.zig +++ b/src/lib/syscall.zig @@ -24,6 +24,8 @@ pub fn handler(proc: *process.Info, trap_frame: *trap.Frame) !void { 100006 => mkdir(trap_frame), 100007 => provideDirHook(trap_frame), 100008 => remove(trap_frame), + 100009 => read(proc, trap_frame), + 100010 => write(proc, trap_frame), else => return Error.UnknownSyscall, } } @@ -163,3 +165,29 @@ fn remove(trap_frame: *const trap.Frame) void { _ = path; unreachable; } + +// read(handle: usize, buffer: [*]u8, len: usize) Result(usize) +fn read(proc: *const process.Info, trap_frame: *trap.Frame) void { + const handle = trap_frame.general_purpose_registers[10]; + const buffer: [*]u8 = @ptrFromInt(trap_frame.general_purpose_registers[11]); + const len = trap_frame.general_purpose_registers[12]; + + const rd = proc.rds.get(handle) orelse { + sysexchange.frameReturn(usize, trap_frame, process.ProcessError.BadRdHandle); + return; + }; + sysexchange.frameReturnResult(usize, trap_frame, rd.read(buffer[0..len])); +} + +// write(handle: usize, bytes: [*]u8, len: usize) Result(usize) +fn write(proc: *const process.Info, trap_frame: *trap.Frame) void { + const handle = trap_frame.general_purpose_registers[10]; + const bytes: [*]u8 = @ptrFromInt(trap_frame.general_purpose_registers[11]); + const len = trap_frame.general_purpose_registers[12]; + + const rd = proc.rds.get(handle) orelse { + sysexchange.frameReturn(usize, trap_frame, process.ProcessError.BadRdHandle); + return; + }; + sysexchange.frameReturnResult(usize, trap_frame, rd.write(bytes[0..len])); +} diff --git a/src/lib/vfs.zig b/src/lib/vfs.zig index 56834d6..3a1fbff 100644 --- a/src/lib/vfs.zig +++ b/src/lib/vfs.zig @@ -16,6 +16,8 @@ pub const Error = error{ NotADirectory, NoAbsoluteContainingDirectory, TooManyReferences, + ReadNotSupported, + WriteNotSupported, }; // A stream is a resource that provides a shared data stream with a driver. @@ -127,6 +129,32 @@ pub const ResourceDescriptor = struct { pub fn deinit(self: ResourceDescriptor) void { self.inode.refs -|= 1; } + + pub fn read(self: ResourceDescriptor, buffer: []u8) sysexchange.Result(usize) { + const err_unsupported = sysexchange.Result(usize).fromAnyTypeOrError(Error.ReadNotSupported); + + return switch (self.inode.resource) { + .stream => |stream| blk: { + const readFn = stream.readFn orelse return err_unsupported; + break :blk readFn(buffer); + }, + .hook => err_unsupported, + else => err_unsupported, + }; + } + + pub fn write(self: ResourceDescriptor, bytes: []const u8) sysexchange.Result(usize) { + const err_unsupported = sysexchange.Result(usize).fromAnyTypeOrError(Error.WriteNotSupported); + + return switch (self.inode.resource) { + .stream => |stream| blk: { + const writeFn = stream.writeFn orelse return err_unsupported; + break :blk writeFn(bytes); + }, + .hook => err_unsupported, + else => err_unsupported, + }; + } }; pub const UserInfo = union(enum) { |