This commit is contained in:
jasonkercher
2022-03-04 17:11:53 -05:00
parent e51bb4ef12
commit 658a605c75
11 changed files with 557 additions and 88 deletions

View File

@@ -0,0 +1,28 @@
//+private
package os2
_get_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) {
//TODO
return
}
_set_env :: proc(key, value: string) -> bool {
//TODO
return false
}
_unset_env :: proc(key: string) -> bool {
//TODO
return false
}
_clear_env :: proc() {
//TODO
}
_environ :: proc(allocator := context.allocator) -> []string {
//TODO
return nil
}

View File

@@ -0,0 +1,134 @@
//+private
package os2
EPERM :: 1
ENOENT :: 2
ESRCH :: 3
EINTR :: 4
EIO :: 5
ENXIO :: 6
EBADF :: 9
EAGAIN :: 11
ENOMEM :: 12
EACCES :: 13
EFAULT :: 14
EEXIST :: 17
ENODEV :: 19
ENOTDIR :: 20
EISDIR :: 21
EINVAL :: 22
ENFILE :: 23
EMFILE :: 24
ETXTBSY :: 26
EFBIG :: 27
ENOSPC :: 28
ESPIPE :: 29
EROFS :: 30
EPIPE :: 32
ERANGE :: 34 /* Result too large */
EDEADLK :: 35 /* Resource deadlock would occur */
ENAMETOOLONG :: 36 /* File name too long */
ENOLCK :: 37 /* No record locks available */
ENOSYS :: 38 /* Invalid system call number */
ENOTEMPTY :: 39 /* Directory not empty */
ELOOP :: 40 /* Too many symbolic links encountered */
EWOULDBLOCK :: EAGAIN /* Operation would block */
ENOMSG :: 42 /* No message of desired type */
EIDRM :: 43 /* Identifier removed */
ECHRNG :: 44 /* Channel number out of range */
EL2NSYNC :: 45 /* Level 2 not synchronized */
EL3HLT :: 46 /* Level 3 halted */
EL3RST :: 47 /* Level 3 reset */
ELNRNG :: 48 /* Link number out of range */
EUNATCH :: 49 /* Protocol driver not attached */
ENOCSI :: 50 /* No CSI structure available */
EL2HLT :: 51 /* Level 2 halted */
EBADE :: 52 /* Invalid exchange */
EBADR :: 53 /* Invalid request descriptor */
EXFULL :: 54 /* Exchange full */
ENOANO :: 55 /* No anode */
EBADRQC :: 56 /* Invalid request code */
EBADSLT :: 57 /* Invalid slot */
EDEADLOCK :: EDEADLK
EBFONT :: 59 /* Bad font file format */
ENOSTR :: 60 /* Device not a stream */
ENODATA :: 61 /* No data available */
ETIME :: 62 /* Timer expired */
ENOSR :: 63 /* Out of streams resources */
ENONET :: 64 /* Machine is not on the network */
ENOPKG :: 65 /* Package not installed */
EREMOTE :: 66 /* Object is remote */
ENOLINK :: 67 /* Link has been severed */
EADV :: 68 /* Advertise error */
ESRMNT :: 69 /* Srmount error */
ECOMM :: 70 /* Communication error on send */
EPROTO :: 71 /* Protocol error */
EMULTIHOP :: 72 /* Multihop attempted */
EDOTDOT :: 73 /* RFS specific error */
EBADMSG :: 74 /* Not a data message */
EOVERFLOW :: 75 /* Value too large for defined data type */
ENOTUNIQ :: 76 /* Name not unique on network */
EBADFD :: 77 /* File descriptor in bad state */
EREMCHG :: 78 /* Remote address changed */
ELIBACC :: 79 /* Can not access a needed shared library */
ELIBBAD :: 80 /* Accessing a corrupted shared library */
ELIBSCN :: 81 /* .lib section in a.out corrupted */
ELIBMAX :: 82 /* Attempting to link in too many shared libraries */
ELIBEXEC :: 83 /* Cannot exec a shared library directly */
EILSEQ :: 84 /* Illegal byte sequence */
ERESTART :: 85 /* Interrupted system call should be restarted */
ESTRPIPE :: 86 /* Streams pipe error */
EUSERS :: 87 /* Too many users */
ENOTSOCK :: 88 /* Socket operation on non-socket */
EDESTADDRREQ :: 89 /* Destination address required */
EMSGSIZE :: 90 /* Message too long */
EPROTOTYPE :: 91 /* Protocol wrong type for socket */
ENOPROTOOPT :: 92 /* Protocol not available */
EPROTONOSUPPORT:: 93 /* Protocol not supported */
ESOCKTNOSUPPORT:: 94 /* Socket type not supported */
EOPNOTSUPP :: 95 /* Operation not supported on transport endpoint */
EPFNOSUPPORT :: 96 /* Protocol family not supported */
EAFNOSUPPORT :: 97 /* Address family not supported by protocol */
EADDRINUSE :: 98 /* Address already in use */
EADDRNOTAVAIL :: 99 /* Cannot assign requested address */
ENETDOWN :: 100 /* Network is down */
ENETUNREACH :: 101 /* Network is unreachable */
ENETRESET :: 102 /* Network dropped connection because of reset */
ECONNABORTED :: 103 /* Software caused connection abort */
ECONNRESET :: 104 /* Connection reset by peer */
ENOBUFS :: 105 /* No buffer space available */
EISCONN :: 106 /* Transport endpoint is already connected */
ENOTCONN :: 107 /* Transport endpoint is not connected */
ESHUTDOWN :: 108 /* Cannot send after transport endpoint shutdown */
ETOOMANYREFS :: 109 /* Too many references: cannot splice */
ETIMEDOUT :: 110 /* Connection timed out */
ECONNREFUSED :: 111 /* Connection refused */
EHOSTDOWN :: 112 /* Host is down */
EHOSTUNREACH :: 113 /* No route to host */
EALREADY :: 114 /* Operation already in progress */
EINPROGRESS :: 115 /* Operation now in progress */
ESTALE :: 116 /* Stale file handle */
EUCLEAN :: 117 /* Structure needs cleaning */
ENOTNAM :: 118 /* Not a XENIX named type file */
ENAVAIL :: 119 /* No XENIX semaphores available */
EISNAM :: 120 /* Is a named type file */
EREMOTEIO :: 121 /* Remote I/O error */
EDQUOT :: 122 /* Quota exceeded */
ENOMEDIUM :: 123 /* No medium found */
EMEDIUMTYPE :: 124 /* Wrong medium type */
ECANCELED :: 125 /* Operation Canceled */
ENOKEY :: 126 /* Required key not available */
EKEYEXPIRED :: 127 /* Key has expired */
EKEYREVOKED :: 128 /* Key has been revoked */
EKEYREJECTED :: 129 /* Key was rejected by service */
EOWNERDEAD :: 130 /* Owner died */
ENOTRECOVERABLE:: 131 /* State not recoverable */
ERFKILL :: 132 /* Operation not possible due to RF-kill */
EHWPOISON :: 133 /* Memory page has hardware error */
_error_string :: proc(errno: i32) -> string {
if errno == 0 {
return ""
}
return "Error"
}

View File

@@ -61,6 +61,10 @@ create :: proc(name: string, perm: File_Mode = 0) -> (Handle, Error) {
return open(name, {.Read, .Write, .Create}, perm)
}
opendir :: proc(name: string) -> (Handle, Error) {
return _opendir(name)
}
open :: proc(name: string, flags := File_Flags{.Read}, perm: File_Mode = 0) -> (Handle, Error) {
flags := flags
if .Write not_in flags {

View File

@@ -3,6 +3,7 @@ package os2
import "core:io"
import "core:time"
import "core:strings"
import "core:sys/unix"
@@ -15,13 +16,64 @@ _ok_or_error :: proc(res: int) -> Error {
return res >= 0 ? nil : _get_platform_error(res)
}
_open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (Handle, Error) {
cstr := strings.clone_to_cstring(path, context.temp_allocator)
handle := Handle(unix.sys_open(cstr, int(flags), int(perm)))
if handle < 0 {
return Handle(-1), _get_platform_error(int(handle))
_std_handle :: proc(kind: Std_Handle_Kind) -> Handle {
switch kind {
case .stdin: return Handle(0)
case .stdout: return Handle(1)
case .stderr: return Handle(2)
}
return handle, nil
unreachable()
}
_O_RDONLY :: 0o0
_O_WRONLY :: 0o1
_O_RDWR :: 0o2
_O_CREAT :: 0o100
_O_EXCL :: 0o200
_O_TRUNC :: 0o1000
_O_APPEND :: 0o2000
_O_NONBLOCK :: 0o4000
_O_LARGEFILE :: 0o100000
_O_DIRECTORY :: 0o200000
_O_SYNC :: 0o4010000
_O_CLOEXEC :: 0o2000000
_opendir :: proc(name: string) -> (Handle, Error) {
cstr := strings.clone_to_cstring(name, context.temp_allocator)
flags := _O_RDONLY|_O_NONBLOCK|_O_DIRECTORY|_O_LARGEFILE|_O_CLOEXEC
handle_i := unix.sys_open(cstr, flags)
if handle_i < 0 {
return INVALID_HANDLE, _get_platform_error(handle_i)
}
return Handle(handle_i), nil
}
_open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (Handle, Error) {
cstr := strings.clone_to_cstring(name, context.temp_allocator)
flags_i: int
switch flags & O_RDONLY|O_WRONLY|O_RDWR {
case O_RDONLY: flags_i = _O_RDONLY
case O_WRONLY: flags_i = _O_WRONLY
case O_RDWR: flags_i = _O_RDWR
}
flags_i |= (_O_APPEND * int(.Append in flags))
flags_i |= (_O_CREAT * int(.Create in flags))
flags_i |= (_O_EXCL * int(.Excl in flags))
flags_i |= (_O_SYNC * int(.Sync in flags))
flags_i |= (_O_TRUNC * int(.Trunc in flags))
flags_i |= (_O_CLOEXEC * int(.Close_On_Exec in flags))
handle_i := unix.sys_open(cstr, flags_i, int(perm))
if handle_i < 0 {
return INVALID_HANDLE, _get_platform_error(handle_i)
}
return Handle(handle_i), nil
}
_close :: proc(fd: Handle) -> Error {
@@ -46,30 +98,27 @@ _read :: proc(fd: Handle, p: []byte) -> (n: int, err: Error) {
if len(p) == 0 {
return 0, nil
}
n = unix.sys_read(fd, &data[0], c.size_t(len(data)))
n = unix.sys_read(int(fd), &p[0], len(p))
if n < 0 {
return -1, unix.get_errno(n)
return -1, _get_platform_error(int(unix.get_errno(n)))
}
return bytes_read, nil
return n, nil
}
_read_at :: proc(fd: Handle, p: []byte, offset: i64) -> (n: int, err: Error) {
if offset < 0 {
return 0, .Invalid_Offset
}
curr_offset, err := _seek(fd, 0, .Current)
if err != nil {
return 0, err
}
defer _seek(fd, curr_offset, .Start)
_seek(fd, offset, .Start)
b := p
b, offset := p, offset
for len(b) > 0 {
m := _read(fd, b) or_return
m := unix.sys_pread(int(fd), &b[0], len(b), offset)
if m < 0 {
return -1, _get_platform_error(m)
}
n += m
b = b[m:]
offset += i64(m)
}
return
}
@@ -83,7 +132,7 @@ _write :: proc(fd: Handle, p: []byte) -> (n: int, err: Error) {
if len(p) == 0 {
return 0, nil
}
n = unix.sys_write(fd, &p[0], uint(len(p)))
n = unix.sys_write(int(fd), &p[0], uint(len(p)))
if n < 0 {
return -1, _get_platform_error(n)
}
@@ -94,19 +143,16 @@ _write_at :: proc(fd: Handle, p: []byte, offset: i64) -> (n: int, err: Error) {
if offset < 0 {
return 0, .Invalid_Offset
}
curr_offset, err := _seek(fd, 0, .Current)
if err != nil {
return 0, err
}
defer _seek(fd, curr_offset, .Start)
_seek(fd, offset, .Start)
b := p
b, offset := p, offset
for len(b) > 0 {
m := _write(fd, b) or_return
m := unix.sys_pwrite(int(fd), &b[0], len(b), offset)
if m < 0 {
return -1, _get_platform_error(m)
}
n += m
b = b[m:]
offset += i64(m)
}
return
}
@@ -117,11 +163,12 @@ _write_to :: proc(fd: Handle, w: io.Writer) -> (n: i64, err: Error) {
}
_file_size :: proc(fd: Handle) -> (n: i64, err: Error) {
s, err := _fstat(fd) or_return
if err != nil {
return 0, err
s: OS_Stat = ---
res := unix.sys_fstat(int(fd), &s)
if res < 0 {
return -1, _get_platform_error(res)
}
return max(s.size, 0), nil
return s.size, nil
}
_sync :: proc(fd: Handle) -> Error {
@@ -137,17 +184,25 @@ _truncate :: proc(fd: Handle, size: i64) -> Error {
}
_remove :: proc(name: string) -> Error {
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
if _is_dir(name) {
return _ok_or_error(unix.sys_rmdir(path_cstr))
name_cstr := strings.clone_to_cstring(name, context.temp_allocator)
handle_i := unix.sys_open(name_cstr, int(File_Flags.Read))
if handle_i < 0 {
return _get_platform_error(handle_i)
}
return _ok_or_error(unix.sys_unlink(path_cstr))
defer unix.sys_close(handle_i)
/* TODO: THIS WILL NOT WORK */
if _is_dir(Handle(handle_i)) {
return _ok_or_error(unix.sys_rmdir(name_cstr))
}
return _ok_or_error(unix.sys_unlink(name_cstr))
}
_rename :: proc(old_path, new_path: string) -> Error {
old_path_cstr := strings.clone_to_cstring(old_path, context.temp_allocator)
new_path_cstr := strings.clone_to_cstring(new_path, context.temp_allocator)
return _ok_or_error(unix.sys_rename(old_path_cstr, new_path_cstr))
_rename :: proc(old_name, new_name: string) -> Error {
old_name_cstr := strings.clone_to_cstring(old_name, context.temp_allocator)
new_name_cstr := strings.clone_to_cstring(new_name, context.temp_allocator)
return _ok_or_error(unix.sys_rename(old_name_cstr, new_name_cstr))
}
_link :: proc(old_name, new_name: string) -> Error {
@@ -163,16 +218,16 @@ _symlink :: proc(old_name, new_name: string) -> Error {
}
_read_link :: proc(name: string, allocator := context.allocator) -> (string, Error) {
path_cstr := strings.clone_to_cstring(path)
defer delete(path_cstr)
name_cstr := strings.clone_to_cstring(name)
defer delete(name_cstr)
bufsz : uint = 256
buf := make([]byte, bufsz, allocator)
for {
rc := unix.sys_readlink(path_cstr, &(buf[0]), bufsz)
rc := unix.sys_readlink(name_cstr, &(buf[0]), bufsz)
if rc < 0 {
delete(buf)
return "", unix.get_errno(rc)
return "", _get_platform_error(int(unix.get_errno(rc)))
} else if rc == int(bufsz) {
bufsz *= 2
delete(buf)
@@ -183,9 +238,9 @@ _read_link :: proc(name: string, allocator := context.allocator) -> (string, Err
}
}
_unlink :: proc(path: string) -> Error {
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
return _ok_or_error(unix.sys_unlink(path_cstr))
_unlink :: proc(name: string) -> Error {
name_cstr := strings.clone_to_cstring(name, context.temp_allocator)
return _ok_or_error(unix.sys_unlink(name_cstr))
}
_chdir :: proc(fd: Handle) -> Error {
@@ -193,18 +248,16 @@ _chdir :: proc(fd: Handle) -> Error {
}
_chmod :: proc(fd: Handle, mode: File_Mode) -> Error {
//TODO
return nil
return _ok_or_error(unix.sys_fchmod(int(fd), int(mode)))
}
_chown :: proc(fd: Handle, uid, gid: int) -> Error {
//TODO
return nil
return _ok_or_error(unix.sys_fchown(int(fd), uid, gid))
}
_lchown :: proc(name: string, uid, gid: int) -> Error {
//TODO
return nil
name_cstr := strings.clone_to_cstring(name, context.temp_allocator)
return _ok_or_error(unix.sys_lchown(name_cstr, uid, gid))
}
_chtimes :: proc(name: string, atime, mtime: time.Time) -> Error {
@@ -212,14 +265,14 @@ _chtimes :: proc(name: string, atime, mtime: time.Time) -> Error {
return nil
}
_exists :: proc(path: string) -> bool {
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
return unix.sys_access(path_cstr, F_OK) == 0
_exists :: proc(name: string) -> bool {
name_cstr := strings.clone_to_cstring(name, context.temp_allocator)
return unix.sys_access(name_cstr, F_OK) == 0
}
_is_file :: proc(fd: Handle) -> bool {
s: OS_Stat
res := unix.sys_fstat(int(fd), rawptr(&s))
res := unix.sys_fstat(int(fd), &s)
if res < 0 { // error
return false
}
@@ -228,7 +281,7 @@ _is_file :: proc(fd: Handle) -> bool {
_is_dir :: proc(fd: Handle) -> bool {
s: OS_Stat
res := unix.sys_fstat(int(fd), rawptr(&s))
res := unix.sys_fstat(int(fd), &s)
if res < 0 { // error
return false
}

View File

@@ -36,6 +36,11 @@ _std_handle :: proc(kind: Std_Handle_Kind) -> Handle {
unreachable()
}
_opendir :: proc(path: string) -> (handle: Handle, err: Error) {
return INVALID_HANDLE, .Invalid_Argument
}
_open :: proc(path: string, flags: File_Flags, perm: File_Mode) -> (handle: Handle, err: Error) {
handle = INVALID_HANDLE
if len(path) == 0 {

View File

@@ -0,0 +1,27 @@
//+private
package os2
import "core:mem"
heap_alloc :: proc(size: int) -> rawptr {
// TODO
return nil
}
heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
// TODO
return nil
}
heap_free :: proc(ptr: rawptr) {
if ptr == nil {
return
}
// TODO
}
_heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
size, alignment: int,
old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, mem.Allocator_Error) {
// TODO
return nil, nil
}

View File

@@ -0,0 +1,85 @@
//+private
package os2
import "core:fmt"
import "core:strings"
import "core:sys/unix"
import "core:path/filepath"
_Path_Separator :: '/'
_Path_List_Separator :: ':'
_is_path_separator :: proc(c: byte) -> bool {
return c == '/'
}
_mkdir :: proc(path: string, perm: File_Mode) -> Error {
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
//TODO file_mode
return _ok_or_error(unix.sys_mkdir(path_cstr))
}
_mkdir_all :: proc(path: string, perm: File_Mode) -> Error {
_mkdir_all_stat :: proc(path: string, s: ^OS_Stat, perm: File_Mode) -> Error {
if len(path) == 0 {
return nil
}
path := path[len(path)-1] == '/' ? path[:len(path)-1] : path
dir, _ := filepath.split(path)
if len(dir) == 0 {
return _mkdir(path, perm)
}
dir_cstr := strings.clone_to_cstring(dir, context.temp_allocator)
errno := int(unix.get_errno(unix.sys_stat(dir_cstr, s)))
switch errno {
case 0:
if !S_ISDIR(s.mode) {
return .Exist
}
return _mkdir(path, perm)
case ENOENT:
_mkdir_all_stat(dir, s, perm) or_return
return _mkdir(path, perm)
case:
return _get_platform_error(errno)
}
unreachable()
}
// OS_Stat is fat. Make one and re-use it.
s: OS_Stat = ---
return _mkdir_all_stat(path, &s, perm)
}
_remove_all :: proc(path: string) -> Error {
// TODO
return nil
}
_getwd :: proc(allocator := context.allocator) -> (dir: string, err: Error) {
// NOTE(tetra): I would use PATH_MAX here, but I was not able to find
// an authoritative value for it across all systems.
// The largest value I could find was 4096, so might as well use the page size.
// NOTE(jason): Avoiding libc, so just use 4096 directly
PATH_MAX :: 4096
buf := make([dynamic]u8, PATH_MAX, allocator)
for {
#no_bounds_check res := unix.sys_getcwd(&buf[0], uint(len(buf)))
if res >= 0 {
return strings.string_from_nul_terminated_ptr(&buf[0], len(buf)), nil
}
if errno := int(unix.get_errno(res)); errno != ERANGE {
return "", _get_platform_error(errno)
}
resize(&buf, len(buf)+PATH_MAX)
}
unreachable()
}
_setwd :: proc(dir: string) -> (err: Error) {
dir_cstr := strings.clone_to_cstring(dir, context.temp_allocator)
return _ok_or_error(unix.sys_chdir(dir_cstr))
}

View File

@@ -0,0 +1,7 @@
//+private
package os2
_pipe :: proc() -> (r, w: Handle, err: Error) {
return INVALID_HANDLE, INVALID_HANDLE, nil
}

View File

@@ -2,7 +2,9 @@
package os2
import "core:time"
import "core:strings"
import "core:sys/unix"
import "core:path/filepath"
// File type
S_IFMT :: 0o170000 // Type of file mask
@@ -51,6 +53,12 @@ X_OK :: 1 // Test for execute permission
W_OK :: 2 // Test for write permission
R_OK :: 4 // Test for read permission
@private
Unix_File_Time :: struct {
seconds: i64,
nanoseconds: i64,
}
@private
OS_Stat :: struct {
device_id: u64, // ID of device containing file
@@ -75,19 +83,21 @@ OS_Stat :: struct {
}
_fstat :: proc(fd: Handle, allocator := context.allocator) -> (File_Info, Error) {
return File_Info{}, nil
}
_stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Error) {
return File_Info{}, nil
}
_lstat :: proc(name: string, allocator := context.allocator) -> (File_Info, Error) {
cstr := strings.clone_to_cstring(path)
cstr := strings.clone_to_cstring(name)
defer delete(cstr)
s: OS_Stat
result := unix.sys_lstat(cstr, &s)
if result < 0 {
return {}, unix.get_errno(result)
return {}, _get_platform_error(int(unix.get_errno(result)))
}
fi := File_Info {
@@ -96,10 +106,10 @@ _lstat :: proc(name: string, allocator := context.allocator) -> (File_Info, Erro
size = s.size,
mode = 0,
is_dir = S_ISDIR(s.mode),
creation_time = nil, // linux does not track this
creation_time = time.Time{0}, // linux does not track this
//TODO
modification_time = nil,
access_time = nil,
modification_time = time.Time{0},
access_time = time.Time{0},
}
return fi, nil
@@ -110,7 +120,7 @@ _same_file :: proc(fi1, fi2: File_Info) -> bool {
}
_stat_internal :: proc(name: string) -> (s: OS_Stat, res: int) {
name_cstr = strings.clone_to_cstring(name, context.temp_allocator)
name_cstr := strings.clone_to_cstring(name, context.temp_allocator)
res = unix.sys_stat(name_cstr, &s)
return
}

View File

@@ -0,0 +1,18 @@
//+private
package os2
_create_temp :: proc(dir, pattern: string) -> (Handle, Error) {
//TODO
return 0, nil
}
_mkdir_temp :: proc(dir, pattern: string, allocator := context.allocator) -> (string, Error) {
//TODO
return "", nil
}
_temp_dir :: proc(allocator := context.allocator) -> string {
//TODO
return ""
}

View File

@@ -15,7 +15,7 @@ import "core:intrinsics"
// 386: arch/x86/entry/syscalls/sycall_32.tbl
// arm: arch/arm/tools/syscall.tbl
when ODIN_ARCH == "amd64" {
when ODIN_ARCH == .amd64 {
SYS_read : uintptr : 0
SYS_write : uintptr : 1
SYS_open : uintptr : 2
@@ -33,8 +33,8 @@ when ODIN_ARCH == "amd64" {
SYS_rt_sigprocmask : uintptr : 14
SYS_rt_sigreturn : uintptr : 15
SYS_ioctl : uintptr : 16
SYS_pread : uintptr : 17
SYS_pwrite : uintptr : 18
SYS_pread64 : uintptr : 17
SYS_pwrite64 : uintptr : 18
SYS_readv : uintptr : 19
SYS_writev : uintptr : 20
SYS_access : uintptr : 21
@@ -374,7 +374,7 @@ when ODIN_ARCH == "amd64" {
SYS_landlock_add_rule : uintptr : 445
SYS_landlock_restrict_self : uintptr : 446
SYS_memfd_secret : uintptr : 447
} else when ODIN_ARCH == "arm64" {
} else when ODIN_ARCH == .arm64 {
SYS_io_setup : uintptr : 0
SYS_io_destroy : uintptr : 1
SYS_io_submit : uintptr : 2
@@ -675,7 +675,7 @@ when ODIN_ARCH == "amd64" {
SYS_landlock_create_ruleset : uintptr : 444
SYS_landlock_add_rule : uintptr : 445
SYS_landlock_restrict_self : uintptr : 446
} else when ODIN_ARCH == "386" {
} else when ODIN_ARCH == .i386 {
SYS_restart_syscall : uintptr : 0
SYS_exit : uintptr : 1
SYS_fork : uintptr : 2
@@ -1112,7 +1112,7 @@ when ODIN_ARCH == "amd64" {
SYS_landlock_add_rule : uintptr : 445
SYS_landlock_restrict_self : uintptr : 446
SYS_memfd_secret : uintptr : 447
} else when ODIN_ARCH == "arm" {
} else when ODIN_ARCH == .arm {
SYS_restart_syscall : uintptr : 0
SYS_exit : uintptr : 1
SYS_fork : uintptr : 2
@@ -1518,6 +1518,7 @@ when ODIN_ARCH == "amd64" {
AT_FDCWD :: -100
AT_REMOVEDIR :: uintptr(0x200)
AT_SYMLINK_FOLLOW :: uintptr(0x400)
AT_SYMLINK_NOFOLLOW :: uintptr(0x100)
sys_gettid :: proc "contextless" () -> int {
@@ -1529,12 +1530,11 @@ sys_getrandom :: proc "contextless" (buf: ^byte, buflen: int, flags: uint) -> in
}
sys_open :: proc(path: cstring, flags: int, mode: int = 0o000) -> int {
when ODIN_ARCH != "arm64" {
res := int(intrinsics.syscall(SYS_open, uintptr(rawptr(path)), uintptr(flags), uintptr(mode)))
when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_open, uintptr(rawptr(path)), uintptr(flags), uintptr(mode)))
} else { // NOTE: arm64 does not have open
res := int(intrinsics.syscall(SYS_openat, uintptr(AT_FDCWD), uintptr(rawptr(path), uintptr(flags), uintptr(mode))))
return int(intrinsics.syscall(SYS_openat, uintptr(AT_FDCWD), uintptr(rawptr(path), uintptr(flags), uintptr(mode))))
}
return -1 if res < 0 else res
}
sys_close :: proc(fd: int) -> int {
@@ -1545,26 +1545,46 @@ sys_read :: proc(fd: int, buf: rawptr, size: uint) -> int {
return int(intrinsics.syscall(SYS_read, uintptr(fd), uintptr(buf), uintptr(size)))
}
sys_pread :: proc(fd: int, buf: rawptr, size: uint, offset: i64) -> int {
when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 {
return int(intrinsics.syscall(SYS_pread64, uintptr(fd), uintptr(buf), uintptr(size), uintptr(offset)))
} else {
low := uintptr(offset & 0xFFFFFFFF)
high := uintptr(offset >> 32)
return int(intrinsics.syscall(SYS_pread64, uintptr(fd), uintptr(buf), uintptr(size), high, low))
}
}
sys_write :: proc(fd: int, buf: rawptr, size: uint) -> int {
return int(intrinsics.syscall(SYS_write, uintptr(fd), uintptr(buf), uintptr(size)))
}
sys_pwrite :: proc(fd: int, buf: rawptr, size: uint, offset: i64) -> int {
when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 {
return int(intrinsics.syscall(SYS_pwrite64, uintptr(fd), uintptr(buf), uintptr(size), uintptr(offset)))
} else {
low := uintptr(offset & 0xFFFFFFFF)
high := uintptr(offset >> 32)
return int(intrinsics.syscall(SYS_pwrite64, uintptr(fd), uintptr(buf), uintptr(size), high, low))
}
}
sys_lseek :: proc(fd: int, offset: i64, whence: int) -> i64 {
when ODIN_ARCH == "amd64" || ODIN_ARCH == "arm64" {
when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 {
return i64(intrinsics.syscall(SYS_lseek, uintptr(fd), uintptr(offset), uintptr(whence)))
} else {
low := uintptr(offset & 0xFFFFFFFF)
high := uintptr(offset >> 32)
result: i64
res := i64(intrinsics.syscall(SYS__llseek, uintptr(fd), high, low, &result, uintptr(whence)))
return -1 if res < 0 else result
return res if res < 0 else result
}
}
sys_stat :: proc(path: cstring, stat: rawptr) -> int {
when ODIN_ARCH == "amd64" {
when ODIN_ARCH == .amd64 {
return int(intrinsics.syscall(SYS_stat, uintptr(rawptr(path)), uintptr(stat)))
} else when ODIN_ARCH != "arm64" {
} else when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_stat64, uintptr(rawptr(path)), uintptr(stat)))
} else { // NOTE: arm64 does not have stat
return int(intrinsics.syscall(SYS_fstatat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(stat), 0))
@@ -1572,7 +1592,7 @@ sys_stat :: proc(path: cstring, stat: rawptr) -> int {
}
sys_fstat :: proc(fd: int, stat: rawptr) -> int {
when ODIN_ARCH == "amd64" || ODIN_ARCH == "arm64" {
when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 {
return int(intrinsics.syscall(SYS_fstat, uintptr(fd), uintptr(stat)))
} else {
return int(intrinsics.syscall(SYS_fstat64, uintptr(fd), uintptr(stat)))
@@ -1580,9 +1600,9 @@ sys_fstat :: proc(fd: int, stat: rawptr) -> int {
}
sys_lstat :: proc(path: cstring, stat: rawptr) -> int {
when ODIN_ARCH == "amd64" {
when ODIN_ARCH == .amd64 {
return int(intrinsics.syscall(SYS_lstat, uintptr(rawptr(path)), uintptr(stat)))
} else when ODIN_ARCH != "arm64" {
} else when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_lstat64, uintptr(rawptr(path)), uintptr(stat)))
} else { // NOTE: arm64 does not have any lstat
return int(intrinsics.syscall(SYS_fstatat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(stat), AT_SYMLINK_NOFOLLOW))
@@ -1590,15 +1610,23 @@ sys_lstat :: proc(path: cstring, stat: rawptr) -> int {
}
sys_readlink :: proc(path: cstring, buf: rawptr, bufsiz: uint) -> int {
when ODIN_ARCH != "arm64" {
when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_readlink, uintptr(rawptr(path)), uintptr(buf), uintptr(bufsiz)))
} else { // NOTE: arm64 does not have readlink
return int(intrinsics.syscall(SYS_readlinkat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(buf), uintptr(bufsiz)))
}
}
sys_symlink :: proc(old_name: cstring, new_name: cstring) -> int {
when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_symlink, uintptr(rawptr(old_name)), uintptr(rawptr(new_name))))
} else { // NOTE: arm64 does not have symlink
return int(intrinsics.syscall(SYS_symlinkat, uintptr(rawptr(old_name)), uintptr(AT_FDCWD), uintptr(rawptr(new_name))))
}
}
sys_access :: proc(path: cstring, mask: int) -> int {
when ODIN_ARCH != "arm64" {
when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_access, uintptr(rawptr(path)), uintptr(mask)))
} else { // NOTE: arm64 does not have access
return int(intrinsics.syscall(SYS_faccessat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(mask)))
@@ -1613,16 +1641,60 @@ sys_chdir :: proc(path: cstring) -> int {
return int(intrinsics.syscall(SYS_chdir, uintptr(rawptr(path))))
}
sys_fchdir :: proc(fd: int) -> int {
return int(intrinsics.syscall(SYS_fchdir, uintptr(fd)))
}
sys_chmod :: proc(path: cstring, mode: int) -> int {
when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_chmod, uintptr(rawptr(path)), uintptr(mode)))
} else { // NOTE: arm64 does not have chmod
return int(intrinsics.syscall(SYS_fchmodat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(mode)))
}
}
sys_fchmod :: proc(fd: int, mode: int) -> int {
return int(intrinsics.syscall(SYS_fchmod, uintptr(fd), uintptr(mode)))
}
sys_chown :: proc(path: cstring, user: int, group: int) -> int {
when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_chown, uintptr(rawptr(path)), uintptr(user), uintptr(group)))
} else { // NOTE: arm64 does not have chown
return int(intrinsics.syscall(SYS_fchownat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(user), uintptr(group), 0))
}
}
sys_fchown :: proc(fd: int, user: int, group: int) -> int {
return int(intrinsics.syscall(SYS_fchown, uintptr(fd), uintptr(user), uintptr(group)))
}
sys_lchown :: proc(path: cstring, user: int, group: int) -> int {
when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_lchown, uintptr(rawptr(path)), uintptr(user), uintptr(group)))
} else { // NOTE: arm64 does not have lchown
return int(intrinsics.syscall(SYS_fchownat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(user), uintptr(group), AT_SYMLINK_NOFOLLOW))
}
}
sys_rename :: proc(old, new: cstring) -> int {
when ODIN_ARCH != "arm64" {
when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_rename, uintptr(rawptr(old)), uintptr(rawptr(new))))
} else { // NOTE: arm64 does not have rename
return int(intrinsics.syscall(SYS_renameat, uintptr(AT_FDCWD), uintptr(rawptr(old)), uintptr(rawptr(new))))
}
}
sys_link :: proc(old_name: cstring, new_name: cstring) -> int {
when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_link, uintptr(rawptr(old_name)), uintptr(rawptr(new_name))))
} else { // NOTE: arm64 does not have link
return int(intrinsics.syscall(SYS_linkat, uintptr(AT_FDCWD), uintptr(rawptr(old_name)), uintptr(AT_FDCWD), uintptr(rawptr(new_name)), AT_SYMLINK_FOLLOW))
}
}
sys_unlink :: proc(path: cstring) -> int {
when ODIN_ARCH != "arm64" {
when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_unlink, uintptr(rawptr(path))))
} else { // NOTE: arm64 does not have unlink
return int(intrinsics.syscall(SYS_unlinkat, uintptr(AT_FDCWD), uintptr(rawptr(path), 0)))
@@ -1630,7 +1702,7 @@ sys_unlink :: proc(path: cstring) -> int {
}
sys_rmdir :: proc(path: cstring) -> int {
when ODIN_ARCH != "arm64" {
when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_rmdir, uintptr(rawptr(path))))
} else { // NOTE: arm64 does not have rmdir
return int(intrinsics.syscall(SYS_unlinkat, uintptr(AT_FDCWD), uintptr(rawptr(path)), AT_REMOVEDIR))
@@ -1638,14 +1710,40 @@ sys_rmdir :: proc(path: cstring) -> int {
}
sys_mkdir :: proc(path: cstring, mode: u32 = 0o775) -> int {
when ODIN_ARCH != "arm64" {
when ODIN_ARCH != .arm64 {
return int(intrinsics.syscall(SYS_mkdir, uintptr(rawptr(path)), uintptr(mode)))
} else { // NOTE: arm64 does not have mkdir
return int(intrinsics.syscall(SYS_mkdirat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(mode)))
}
}
//TODO: ftruncate, symlink, readlink, fchdir, fchmod, chown, fchown, lchown
sys_truncate :: proc(path: cstring, length: i64) -> int {
when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 {
return int(intrinsics.syscall(SYS_truncate, uintptr(rawptr(path)), uintptr(length)))
} else {
low := uintptr(length & 0xFFFFFFFF)
high := uintptr(length >> 32)
return int(intrinsics.syscall(SYS_truncate64, uintptr(rawptr(path)), high, low))
}
}
sys_ftruncate :: proc(fd: int, length: i64) -> int {
when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 {
return int(intrinsics.syscall(SYS_ftruncate, uintptr(fd), uintptr(length)))
} else {
low := uintptr(length & 0xFFFFFFFF)
high := uintptr(length >> 32)
return int(intrinsics.syscall(SYS_ftruncate64, uintptr(fd), high, low))
}
}
sys_fsync :: proc(fd: int) -> int {
return int(intrinsics.syscall(SYS_fsync, uintptr(fd)))
}
sys_getdents64 :: proc(fd: int, dirent: rawptr, count: int) -> int {
return int(intrinsics.syscall(SYS_getdents64, uintptr(fd), uintptr(dirent), uintptr(count)))
}
get_errno :: proc(res: int) -> i32 {
if res < 0 && res > -4096 {