aboutsummaryrefslogtreecommitdiff
path: root/mirai.old/invocations/fs/setlocation.zig
diff options
context:
space:
mode:
Diffstat (limited to 'mirai.old/invocations/fs/setlocation.zig')
-rw-r--r--mirai.old/invocations/fs/setlocation.zig64
1 files changed, 64 insertions, 0 deletions
diff --git a/mirai.old/invocations/fs/setlocation.zig b/mirai.old/invocations/fs/setlocation.zig
new file mode 100644
index 0000000..f2164fd
--- /dev/null
+++ b/mirai.old/invocations/fs/setlocation.zig
@@ -0,0 +1,64 @@
+//! Setlocation invocation - Change current stack location
+
+const afs = @import("../../fs/afs/afs.zig");
+const ahci = @import("../../drivers/ahci/ahci.zig");
+const copy = @import("../../utils/mem/copy.zig");
+const fs_limits = @import("../../common/limits/fs.zig");
+const handler = @import("../handler.zig");
+const heap = @import("../../memory/heap.zig");
+const kata_mod = @import("../../kata/kata.zig");
+const location = @import("../../utils/fs/location.zig");
+const memory_limits = @import("../../common/limits/memory.zig");
+const result = @import("../../utils/types/result.zig");
+const sensei = @import("../../kata/sensei/sensei.zig");
+
+var afs_instance: ?*afs.AFS(ahci.BlockDevice) = null;
+
+pub fn set_afs_instance(fs: *afs.AFS(ahci.BlockDevice)) void {
+ afs_instance = fs;
+}
+
+pub fn invoke(ctx: *handler.InvocationContext) void {
+ const fs = afs_instance orelse return result.set_error(ctx);
+
+ const location_ptr = ctx.rdi;
+ const location_len = ctx.rsi;
+
+ if (!memory_limits.is_valid_kata_pointer(location_ptr)) return result.set_error(ctx);
+ if (location_len > fs_limits.MAX_LOCATION_LENGTH) return result.set_error(ctx);
+
+ const kata = sensei.get_current_kata() orelse return result.set_error(ctx);
+
+ var location_buf: [fs_limits.MAX_LOCATION_LENGTH]u8 = undefined;
+ copy.from_ptr(&location_buf, location_ptr, location_len);
+ const loc = location_buf[0..location_len];
+
+ const target_cluster = location.resolve_to_cluster(fs, loc, kata.current_cluster) orelse {
+ return result.set_error(ctx);
+ };
+
+ const canonical = location.canonicalize(kata.current_location[0..kata.current_location_len], loc);
+
+ copy.bytes(kata.current_location[0..canonical.len], canonical.buf[0..canonical.len]);
+ kata.current_location_len = canonical.len;
+ kata.current_cluster = target_cluster;
+
+ if (kata.parent_id != 0) {
+ if (kata_mod.get_kata(kata.parent_id)) |parent| {
+ const len: u16 = @intCast(canonical.len);
+ if (parent.letter_capacity < len) {
+ if (parent.letter_data) |old| {
+ heap.free(@ptrCast(old), parent.letter_capacity);
+ }
+ const new_buf = heap.alloc(len) orelse return result.set_error(ctx);
+ parent.letter_data = new_buf;
+ parent.letter_capacity = len;
+ }
+ parent.letter_type = 1;
+ parent.letter_len = len;
+ copy.bytes(parent.letter_data.?[0..len], canonical.buf[0..canonical.len]);
+ }
+ }
+
+ result.set_ok(ctx);
+}