1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
//! Attach invocation - Open attachment
const afs = @import("../../fs/afs/afs.zig");
const ahci = @import("../../drivers/ahci/ahci.zig");
const attachment_const = @import("../../common/constants/attachment.zig");
const attachment_util = @import("../../utils/kata/attachment.zig");
const compare = @import("../../utils/string/compare.zig");
const copy = @import("../../utils/mem/copy.zig");
const handler = @import("../handler.zig");
const heap = @import("../../memory/heap.zig");
const int = @import("../../utils/types/int.zig");
const kata_attachment = @import("../../kata/attachment.zig");
const kata_mod = @import("../../kata/kata.zig");
const location_util = @import("../../utils/fs/location.zig");
const result = @import("../../utils/types/result.zig");
const sensei = @import("../../kata/sensei/sensei.zig");
const string_copy = @import("../../utils/string/copy.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 kata = sensei.get_current_kata() orelse return result.set_error(ctx);
const location_ptr = ctx.rdi;
const flags = int.u32_of(ctx.rsi);
var location_buf: [256]u8 = undefined;
const location_len = string_copy.from_kata(&location_buf, location_ptr) catch return result.set_error(ctx);
const location = location_buf[0..location_len];
if (location_util.is_device(location)) {
const fd = open_device(kata, location, flags) catch return result.set_error(ctx);
return result.set_value(ctx, fd);
}
const fd = open_unit(kata, location, flags) catch return result.set_error(ctx);
result.set_value(ctx, fd);
}
fn open_device(kata: *kata_mod.Kata, location: []const u8, flags: u32) !u32 {
const name = location_util.device_name(location);
const device_type: kata_attachment.DeviceType =
if (compare.equals(name, "source")) .Source else if (compare.equals(name, "stream")) .Stream else if (compare.equals(name, "trace")) .Trace else if (compare.equals(name, "void")) .Void else if (compare.equals(name, "chaos")) .Chaos else if (compare.equals(name, "zero")) .Zero else if (compare.equals(name, "console")) .Console else return error.UnknownDevice;
const fd = try attachment_util.allocate(kata);
const entry = kata_attachment.alloc() orelse return error.OutOfMemory;
entry.* = .{
.attachment_type = .Device,
.device_type = device_type,
.flags = flags,
};
kata.attachments[fd] = entry;
return fd;
}
fn open_unit(kata: *kata_mod.Kata, location: []const u8, flags: u32) !u32 {
const fs = afs_instance orelse return error.NoFilesystem;
var full_location_buf: [512]u8 = undefined;
const full_location = location_util.resolve(kata, location, &full_location_buf);
const fd = try attachment_util.allocate(kata);
const entry = kata_attachment.alloc() orelse return error.OutOfMemory;
var unit_buffer: [1024 * 1024]u8 = undefined;
const bytes_read = fs.view_unit_at(full_location, &unit_buffer) catch {
if (flags & attachment_const.CREATE != 0) {
fs.create_unit(full_location) catch {
kata_attachment.free(entry);
return error.CannotCreate;
};
entry.* = .{
.attachment_type = .Unit,
.unit_size = 0,
.position = 0,
.flags = flags,
.location_len = location.len,
};
copy.bytes(entry.location[0..location.len], location);
kata.attachments[fd] = entry;
return fd;
}
kata_attachment.free(entry);
return error.UnitNotFound;
};
const unit_data = heap.alloc(bytes_read) orelse {
kata_attachment.free(entry);
return error.OutOfMemory;
};
copy.bytes(unit_data[0..bytes_read], unit_buffer[0..bytes_read]);
entry.* = .{
.attachment_type = .Unit,
.buffer = unit_data[0..bytes_read],
.unit_size = bytes_read,
.position = if (flags & attachment_const.EXTEND != 0) bytes_read else 0,
.flags = flags,
.location_len = location.len,
};
copy.bytes(entry.location[0..location.len], location);
kata.attachments[fd] = entry;
return fd;
}
|