mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-18 20:40:28 +00:00
os2 linux begin
This commit is contained in:
236
core/os/os2/file_linux.odin
Normal file
236
core/os/os2/file_linux.odin
Normal file
@@ -0,0 +1,236 @@
|
||||
//+private
|
||||
package os2
|
||||
|
||||
import "core:io"
|
||||
import "core:time"
|
||||
import "core:sys/unix"
|
||||
|
||||
|
||||
_get_platform_error :: proc(res: int) -> Error {
|
||||
errno := unix.get_errno(res)
|
||||
return Platform_Error{i32(errno)}
|
||||
}
|
||||
|
||||
_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))
|
||||
}
|
||||
return handle, nil
|
||||
}
|
||||
|
||||
_close :: proc(fd: Handle) -> Error {
|
||||
res := unix.sys_close(int(fd))
|
||||
return _ok_or_error(res)
|
||||
}
|
||||
|
||||
_name :: proc(fd: Handle, allocator := context.allocator) -> string {
|
||||
//TODO
|
||||
return ""
|
||||
}
|
||||
|
||||
_seek :: proc(fd: Handle, offset: i64, whence: Seek_From) -> (ret: i64, err: Error) {
|
||||
res := unix.sys_lseek(int(fd), offset, int(whence))
|
||||
if res < 0 {
|
||||
return -1, _get_platform_error(int(res))
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
_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)))
|
||||
if n < 0 {
|
||||
return -1, unix.get_errno(n)
|
||||
}
|
||||
return bytes_read, 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
|
||||
for len(b) > 0 {
|
||||
m := _read(fd, b) or_return
|
||||
n += m
|
||||
b = b[m:]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
_read_from :: proc(fd: Handle, r: io.Reader) -> (n: i64, err: Error) {
|
||||
//TODO
|
||||
return
|
||||
}
|
||||
|
||||
_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)))
|
||||
if n < 0 {
|
||||
return -1, _get_platform_error(n)
|
||||
}
|
||||
return int(n), nil
|
||||
}
|
||||
|
||||
_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
|
||||
for len(b) > 0 {
|
||||
m := _write(fd, b) or_return
|
||||
n += m
|
||||
b = b[m:]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
_write_to :: proc(fd: Handle, w: io.Writer) -> (n: i64, err: Error) {
|
||||
//TODO
|
||||
return
|
||||
}
|
||||
|
||||
_file_size :: proc(fd: Handle) -> (n: i64, err: Error) {
|
||||
s, err := _fstat(fd) or_return
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return max(s.size, 0), nil
|
||||
}
|
||||
|
||||
_sync :: proc(fd: Handle) -> Error {
|
||||
return _ok_or_error(unix.sys_fsync(int(fd)))
|
||||
}
|
||||
|
||||
_flush :: proc(fd: Handle) -> Error {
|
||||
return _ok_or_error(unix.sys_fsync(int(fd)))
|
||||
}
|
||||
|
||||
_truncate :: proc(fd: Handle, size: i64) -> Error {
|
||||
return _ok_or_error(unix.sys_ftruncate(int(fd), size))
|
||||
}
|
||||
|
||||
_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))
|
||||
}
|
||||
return _ok_or_error(unix.sys_unlink(path_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))
|
||||
}
|
||||
|
||||
_link :: 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_link(old_name_cstr, new_name_cstr))
|
||||
}
|
||||
|
||||
_symlink :: 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_symlink(old_name_cstr, new_name_cstr))
|
||||
}
|
||||
|
||||
_read_link :: proc(name: string, allocator := context.allocator) -> (string, Error) {
|
||||
path_cstr := strings.clone_to_cstring(path)
|
||||
defer delete(path_cstr)
|
||||
|
||||
bufsz : uint = 256
|
||||
buf := make([]byte, bufsz, allocator)
|
||||
for {
|
||||
rc := unix.sys_readlink(path_cstr, &(buf[0]), bufsz)
|
||||
if rc < 0 {
|
||||
delete(buf)
|
||||
return "", unix.get_errno(rc)
|
||||
} else if rc == int(bufsz) {
|
||||
bufsz *= 2
|
||||
delete(buf)
|
||||
buf = make([]byte, bufsz, allocator)
|
||||
} else {
|
||||
return strings.string_from_ptr(&buf[0], rc), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_unlink :: proc(path: string) -> Error {
|
||||
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
||||
return _ok_or_error(unix.sys_unlink(path_cstr))
|
||||
}
|
||||
|
||||
_chdir :: proc(fd: Handle) -> Error {
|
||||
return _ok_or_error(unix.sys_fchdir(int(fd)))
|
||||
}
|
||||
|
||||
_chmod :: proc(fd: Handle, mode: File_Mode) -> Error {
|
||||
//TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
_chown :: proc(fd: Handle, uid, gid: int) -> Error {
|
||||
//TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
_lchown :: proc(name: string, uid, gid: int) -> Error {
|
||||
//TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
_chtimes :: proc(name: string, atime, mtime: time.Time) -> Error {
|
||||
//TODO
|
||||
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
|
||||
}
|
||||
|
||||
_is_file :: proc(fd: Handle) -> bool {
|
||||
s: OS_Stat
|
||||
res := unix.sys_fstat(int(fd), rawptr(&s))
|
||||
if res < 0 { // error
|
||||
return false
|
||||
}
|
||||
return S_ISREG(s.mode)
|
||||
}
|
||||
|
||||
_is_dir :: proc(fd: Handle) -> bool {
|
||||
s: OS_Stat
|
||||
res := unix.sys_fstat(int(fd), rawptr(&s))
|
||||
if res < 0 { // error
|
||||
return false
|
||||
}
|
||||
return S_ISDIR(s.mode)
|
||||
}
|
||||
116
core/os/os2/stat_linux.odin
Normal file
116
core/os/os2/stat_linux.odin
Normal file
@@ -0,0 +1,116 @@
|
||||
//+private
|
||||
package os2
|
||||
|
||||
import "core:time"
|
||||
import "core:sys/unix"
|
||||
|
||||
// File type
|
||||
S_IFMT :: 0o170000 // Type of file mask
|
||||
S_IFIFO :: 0o010000 // Named pipe (fifo)
|
||||
S_IFCHR :: 0o020000 // Character special
|
||||
S_IFDIR :: 0o040000 // Directory
|
||||
S_IFBLK :: 0o060000 // Block special
|
||||
S_IFREG :: 0o100000 // Regular
|
||||
S_IFLNK :: 0o120000 // Symbolic link
|
||||
S_IFSOCK :: 0o140000 // Socket
|
||||
|
||||
// File mode
|
||||
// Read, write, execute/search by owner
|
||||
S_IRWXU :: 0o0700 // RWX mask for owner
|
||||
S_IRUSR :: 0o0400 // R for owner
|
||||
S_IWUSR :: 0o0200 // W for owner
|
||||
S_IXUSR :: 0o0100 // X for owner
|
||||
|
||||
// Read, write, execute/search by group
|
||||
S_IRWXG :: 0o0070 // RWX mask for group
|
||||
S_IRGRP :: 0o0040 // R for group
|
||||
S_IWGRP :: 0o0020 // W for group
|
||||
S_IXGRP :: 0o0010 // X for group
|
||||
|
||||
// Read, write, execute/search by others
|
||||
S_IRWXO :: 0o0007 // RWX mask for other
|
||||
S_IROTH :: 0o0004 // R for other
|
||||
S_IWOTH :: 0o0002 // W for other
|
||||
S_IXOTH :: 0o0001 // X for other
|
||||
|
||||
S_ISUID :: 0o4000 // Set user id on execution
|
||||
S_ISGID :: 0o2000 // Set group id on execution
|
||||
S_ISVTX :: 0o1000 // Directory restrcted delete
|
||||
|
||||
|
||||
S_ISLNK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFLNK }
|
||||
S_ISREG :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFREG }
|
||||
S_ISDIR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFDIR }
|
||||
S_ISCHR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFCHR }
|
||||
S_ISBLK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK }
|
||||
S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO }
|
||||
S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK }
|
||||
|
||||
F_OK :: 0 // Test for file existance
|
||||
X_OK :: 1 // Test for execute permission
|
||||
W_OK :: 2 // Test for write permission
|
||||
R_OK :: 4 // Test for read permission
|
||||
|
||||
@private
|
||||
OS_Stat :: struct {
|
||||
device_id: u64, // ID of device containing file
|
||||
serial: u64, // File serial number
|
||||
nlink: u64, // Number of hard links
|
||||
mode: u32, // Mode of the file
|
||||
uid: u32, // User ID of the file's owner
|
||||
gid: u32, // Group ID of the file's group
|
||||
_padding: i32, // 32 bits of padding
|
||||
rdev: u64, // Device ID, if device
|
||||
size: i64, // Size of the file, in bytes
|
||||
block_size: i64, // Optimal bllocksize for I/O
|
||||
blocks: i64, // Number of 512-byte blocks allocated
|
||||
|
||||
last_access: Unix_File_Time, // Time of last access
|
||||
modified: Unix_File_Time, // Time of last modification
|
||||
status_change: Unix_File_Time, // Time of last status change
|
||||
|
||||
_reserve1,
|
||||
_reserve2,
|
||||
_reserve3: i64,
|
||||
}
|
||||
|
||||
_fstat :: proc(fd: Handle, allocator := context.allocator) -> (File_Info, Error) {
|
||||
}
|
||||
|
||||
_stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Error) {
|
||||
}
|
||||
|
||||
_lstat :: proc(name: string, allocator := context.allocator) -> (File_Info, Error) {
|
||||
cstr := strings.clone_to_cstring(path)
|
||||
defer delete(cstr)
|
||||
|
||||
s: OS_Stat
|
||||
result := unix.sys_lstat(cstr, &s)
|
||||
if result < 0 {
|
||||
return {}, unix.get_errno(result)
|
||||
}
|
||||
|
||||
fi := File_Info {
|
||||
fullpath = "",
|
||||
name = "",
|
||||
size = s.size,
|
||||
mode = 0,
|
||||
is_dir = S_ISDIR(s.mode),
|
||||
creation_time = nil, // linux does not track this
|
||||
//TODO
|
||||
modification_time = nil,
|
||||
access_time = nil,
|
||||
}
|
||||
|
||||
return fi, nil
|
||||
}
|
||||
|
||||
_same_file :: proc(fi1, fi2: File_Info) -> bool {
|
||||
return fi1.fullpath == fi2.fullpath
|
||||
}
|
||||
|
||||
_stat_internal :: proc(name: string) -> (s: OS_Stat, res: int) {
|
||||
name_cstr = strings.clone_to_cstring(name, context.temp_allocator)
|
||||
res = unix.sys_stat(name_cstr, &s)
|
||||
return
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 == .i386 {
|
||||
} else when ODIN_ARCH == "386" {
|
||||
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 false /*ODIN_ARCH == .arm*/ { // TODO
|
||||
} else when ODIN_ARCH == "arm" {
|
||||
SYS_restart_syscall : uintptr : 0
|
||||
SYS_exit : uintptr : 1
|
||||
SYS_fork : uintptr : 2
|
||||
@@ -1516,6 +1516,10 @@ when ODIN_ARCH == .amd64 {
|
||||
#panic("Unsupported architecture")
|
||||
}
|
||||
|
||||
AT_FDCWD :: -100
|
||||
AT_REMOVEDIR :: uintptr(0x200)
|
||||
AT_SYMLINK_NOFOLLOW :: uintptr(0x100)
|
||||
|
||||
sys_gettid :: proc "contextless" () -> int {
|
||||
return cast(int)intrinsics.syscall(SYS_gettid)
|
||||
}
|
||||
@@ -1523,3 +1527,129 @@ sys_gettid :: proc "contextless" () -> int {
|
||||
sys_getrandom :: proc "contextless" (buf: ^byte, buflen: int, flags: uint) -> int {
|
||||
return cast(int)intrinsics.syscall(SYS_getrandom, buf, cast(uintptr)(buflen), cast(uintptr)(flags))
|
||||
}
|
||||
|
||||
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)))
|
||||
} else { // NOTE: arm64 does not have open
|
||||
res := 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 {
|
||||
return int(intrinsics.syscall(SYS_close, uintptr(fd)))
|
||||
}
|
||||
|
||||
sys_read :: proc(fd: int, buf: rawptr, size: uint) -> int {
|
||||
return int(intrinsics.syscall(SYS_read, uintptr(fd), uintptr(buf), uintptr(size)))
|
||||
}
|
||||
|
||||
sys_write :: proc(fd: int, buf: rawptr, size: uint) -> int {
|
||||
return int(intrinsics.syscall(SYS_write, uintptr(fd), uintptr(buf), uintptr(size)))
|
||||
}
|
||||
|
||||
sys_lseek :: proc(fd: int, offset: i64, whence: int) -> i64 {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
sys_stat :: proc(path: cstring, stat: rawptr) -> int {
|
||||
when ODIN_ARCH == "amd64" {
|
||||
return int(intrinsics.syscall(SYS_stat, uintptr(rawptr(path)), uintptr(stat)))
|
||||
} 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))
|
||||
}
|
||||
}
|
||||
|
||||
sys_fstat :: proc(fd: int, stat: rawptr) -> int {
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
||||
sys_lstat :: proc(path: cstring, stat: rawptr) -> int {
|
||||
when ODIN_ARCH == "amd64" {
|
||||
return int(intrinsics.syscall(SYS_lstat, uintptr(rawptr(path)), uintptr(stat)))
|
||||
} 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))
|
||||
}
|
||||
}
|
||||
|
||||
sys_readlink :: proc(path: cstring, buf: rawptr, bufsiz: uint) -> int {
|
||||
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_access :: proc(path: cstring, mask: int) -> int {
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
||||
sys_getcwd :: proc(buf: rawptr, size: uint) -> int {
|
||||
return int(intrinsics.syscall(SYS_getcwd, uintptr(buf), uintptr(size)))
|
||||
}
|
||||
|
||||
sys_chdir :: proc(path: cstring) -> int {
|
||||
return int(intrinsics.syscall(SYS_chdir, uintptr(rawptr(path))))
|
||||
}
|
||||
|
||||
sys_rename :: proc(old, new: cstring) -> int {
|
||||
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_unlink :: proc(path: cstring) -> int {
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
||||
sys_rmdir :: proc(path: cstring) -> int {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
sys_mkdir :: proc(path: cstring, mode: u32 = 0o775) -> int {
|
||||
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
|
||||
|
||||
get_errno :: proc(res: int) -> i32 {
|
||||
if res < 0 && res > -4096 {
|
||||
return i32(-res)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user