mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-14 23:33:15 +00:00
compiles
This commit is contained in:
28
core/os/os2/env_linux.odin
Normal file
28
core/os/os2/env_linux.odin
Normal 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
|
||||
}
|
||||
|
||||
|
||||
134
core/os/os2/errors_linux.odin
Normal file
134
core/os/os2/errors_linux.odin
Normal 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"
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
27
core/os/os2/heap_linux.odin
Normal file
27
core/os/os2/heap_linux.odin
Normal 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
|
||||
}
|
||||
85
core/os/os2/path_linux.odin
Normal file
85
core/os/os2/path_linux.odin
Normal 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))
|
||||
}
|
||||
7
core/os/os2/pipe_linux.odin
Normal file
7
core/os/os2/pipe_linux.odin
Normal file
@@ -0,0 +1,7 @@
|
||||
//+private
|
||||
package os2
|
||||
|
||||
_pipe :: proc() -> (r, w: Handle, err: Error) {
|
||||
return INVALID_HANDLE, INVALID_HANDLE, nil
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
18
core/os/os2/temp_file_linux.odin
Normal file
18
core/os/os2/temp_file_linux.odin
Normal 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 ""
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user