159 lines
4.5 KiB
Plaintext
159 lines
4.5 KiB
Plaintext
const std = #import("std");
|
|
const linux = std.os.linux;
|
|
const macos = std.os.macos;
|
|
const builtin = #import("builtin");
|
|
const os = builtin.os;
|
|
|
|
const Error = switch (os) {
|
|
.linux => linux.Error,
|
|
.macos => macos.Error,
|
|
else => #error("OS not supported"),
|
|
};
|
|
|
|
const unwrap_syscall = fn(syscall_result: ssize) Error!usize {
|
|
if (syscall_result == -1) {
|
|
const absolute_error: u64 = #cast(-syscall_result);
|
|
const error_int: u32 = #cast(absolute_error);
|
|
const err: Error = #cast(error_int);
|
|
return err;
|
|
} else {
|
|
const result: usize = #cast(syscall_result);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
const MapFlags = switch (os) {
|
|
.macos => bitfield(u32){
|
|
shared: bool = false,
|
|
private: bool = false,
|
|
reserved: u2 = 0,
|
|
fixed: bool = false,
|
|
reserved0: bool = 0,
|
|
noreserve: bool = false,
|
|
reserved1: u2 = 0,
|
|
has_semaphore: bool = false,
|
|
no_cache: bool = false,
|
|
reserved2: u1 = 0,
|
|
anonymous: bool = false,
|
|
reserved3: u19 = 0,
|
|
},
|
|
.linux => linux.MapFlags,
|
|
else => #error("OS not supported"),
|
|
};
|
|
|
|
const AccessMode = enum(u2) {
|
|
read_only = 0,
|
|
write_only = 1,
|
|
read_write = 2,
|
|
};
|
|
|
|
const OpenFlags = switch (os) {
|
|
.macos => bitfield(u32) {
|
|
access_mode: AccessMode,
|
|
non_block: bool = false,
|
|
append: bool = false,
|
|
shared_lock: bool = false,
|
|
exclusive_lock: bool = false,
|
|
async: bool = false,
|
|
sync: bool = false,
|
|
no_follow: bool = false,
|
|
creat: bool = false,
|
|
truncate: bool = false,
|
|
exclusive: bool = false,
|
|
_: u3 = 0,
|
|
evt_only: bool = false,
|
|
_: u1 = 0,
|
|
no_ctty: bool = false,
|
|
_: u2 = 0,
|
|
directory: bool = false,
|
|
symlink: bool = false,
|
|
dsync: bool = false,
|
|
_: u1 = 0,
|
|
cloexec: bool = false,
|
|
_: u4 = 0,
|
|
alert: bool = false,
|
|
_: u1 = 0,
|
|
popup: bool = false,
|
|
},
|
|
.linux => linux.OpenFlags,
|
|
else => #error("OS not supported"),
|
|
};
|
|
|
|
const TimeSpec = struct{
|
|
seconds: s64,
|
|
nanoseconds: s64,
|
|
};
|
|
|
|
const Stat = switch (os) {
|
|
.macos => struct{
|
|
dev: s32,
|
|
mode: u16,
|
|
nlink: u16,
|
|
|
|
inode: u64,
|
|
uid: u32,
|
|
gid: u32,
|
|
rdev: s32,
|
|
|
|
a_timespec: TimeSpec,
|
|
m_timespec: TimeSpec,
|
|
c_timespec: TimeSpec,
|
|
birth_timespec: TimeSpec,
|
|
size: s64,
|
|
blocks: s64,
|
|
block_size: s32,
|
|
flags: u32,
|
|
gen: u32,
|
|
lspare: s32,
|
|
qspare: [2]s64,
|
|
},
|
|
.linux => linux.Stat,
|
|
else => #error("OS not supported"),
|
|
};
|
|
|
|
|
|
const FileDescriptor = s32;
|
|
const ProcessId = s32;
|
|
const MAP_FAILED = 0xffffffffffffffff;
|
|
|
|
const ProtectionFlags = bitfield(u32) {
|
|
read: bool,
|
|
write: bool,
|
|
execute: bool,
|
|
};
|
|
|
|
const get_protection_flags = fn(flags: std.os.ProtectionFlags) ProtectionFlags {
|
|
return ProtectionFlags{
|
|
.read = flags.read,
|
|
.write = flags.write,
|
|
.execute = flags.execute,
|
|
};
|
|
}
|
|
|
|
const get_map_flags = fn(flags: std.os.MapFlags) MapFlags{
|
|
return MapFlags{
|
|
.shared = false,
|
|
.private = true,
|
|
.fixed = false,
|
|
.noreserve = false,
|
|
.has_semaphore = false,
|
|
.no_cache = false,
|
|
.anonymous = true,
|
|
};
|
|
}
|
|
|
|
const open :: extern = fn cc(.c) (path: [&:0]const u8, flags: OpenFlags) s32;
|
|
const read :: extern = fn cc(.c) (file_descriptor: FileDescriptor, bytes_ptr: [&]const u8, byte_count: usize) ssize;
|
|
const write :: extern = fn cc(.c) (file_descriptor: FileDescriptor, bytes_ptr: [&]const u8, byte_count: usize) ssize;
|
|
const exit :: extern = fn cc(.c) (exit_code: s32) noreturn;
|
|
const fork :: extern = fn cc(.c) () ProcessId;
|
|
const mmap :: extern = fn cc(.c) (address: ?[&]const u8, length: usize, protection_flags: ProtectionFlags, map_flags: MapFlags, file_descriptor: FileDescriptor, offset: u64) usize;
|
|
const munmap :: extern = fn cc(.c) (address: [&]const u8, length: usize) s32;
|
|
const execve :: extern = fn cc(.c) (path: [&:0]const u8, argv: [&:null]const ?[&:0]const u8, env: [&:null]const ?[&:null]const u8) s32;
|
|
const realpath :: extern = fn cc(.c) (path: [&:0]const u8, resolved_path: [&:0]u8) ?[&:0]u8;
|
|
const waitpid :: extern = fn cc(.c) (pid: ProcessId, status: &s32, flags: s32) s32;
|
|
const mprotect :: extern = fn cc(.c) (address: &any, size: usize, flags: ProtectionFlags) s32;
|
|
const fstat :: extern = fn cc(.c) (file_descriptor: FileDescriptor, stat: &Stat) s32;
|
|
|
|
const _NSGetExecutablePath :: extern = fn cc(.c) (buffer: [&:0]u8, buffer_size: &u32) s32;
|