aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/process.zig1
-rw-r--r--src/lib/syscall.zig28
-rw-r--r--src/lib/vfs.zig28
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) {