Files
Odin/core/os/os_wasi.odin
T

143 lines
3.1 KiB
Odin

package os
import "core:sys/wasm/wasi"
Handle :: distinct i32
Errno :: distinct i32
ERROR_NONE :: Errno(wasi.errno_t.SUCCESS)
O_RDONLY :: 0x00000
O_WRONLY :: 0x00001
O_RDWR :: 0x00002
O_CREATE :: 0x00040
O_EXCL :: 0x00080
O_NOCTTY :: 0x00100
O_TRUNC :: 0x00200
O_NONBLOCK :: 0x00800
O_APPEND :: 0x00400
O_SYNC :: 0x01000
O_ASYNC :: 0x02000
O_CLOEXEC :: 0x80000
stdin: Handle = 0
stdout: Handle = 1
stderr: Handle = 2
write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
iovs := wasi.ciovec_t(data)
n, err := wasi.fd_write(wasi.fd_t(fd), {iovs})
return int(n), Errno(err)
}
read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
iovs := wasi.iovec_t(data)
n, err := wasi.fd_read(wasi.fd_t(fd), {iovs})
return int(n), Errno(err)
}
write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
iovs := wasi.ciovec_t(data)
n, err := wasi.fd_pwrite(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset))
return int(n), Errno(err)
}
read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
iovs := wasi.iovec_t(data)
n, err := wasi.fd_pread(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset))
return int(n), Errno(err)
}
open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
flags: wasi.oflags_t
fs_rights_base: wasi.rights_t
fs_rights_inheriting: wasi.rights_t
fdflags: wasi.fdflags_t
if mode & O_RDONLY == O_RDONLY {
fs_rights_base += {.FD_READ}
}
if mode & O_WRONLY == O_WRONLY {
fs_rights_base += {.FD_WRITE}
}
if mode & O_RDWR == O_RDWR {
fs_rights_base += {.FD_READ, .FD_WRITE}
}
if mode & O_CREATE == O_CREATE {
flags += {.CREATE}
fs_rights_base += {.FD_WRITE}
}
if mode & O_EXCL == O_EXCL {
flags += {.EXCL}
}
if mode & O_NOCTTY == O_NOCTTY {
}
if mode & O_TRUNC == O_TRUNC {
flags += {.TRUNC}
}
if mode & O_NONBLOCK == O_NONBLOCK {
fdflags += {.NONBLOCK}
}
if mode & O_APPEND == O_APPEND {
fdflags += {.APPEND}
}
if mode & O_SYNC == O_SYNC {
fdflags += {.DSYNC, .RSYNC, .SYNC}
}
if mode & O_ASYNC == O_ASYNC {
}
if mode & O_CLOEXEC == O_CLOEXEC {
}
fs_rights_inheriting = fs_rights_base
fd, err := wasi.path_open(0, {}, path, flags, fs_rights_base, fs_rights_inheriting, fdflags)
return Handle(fd), Errno(err)
}
close :: proc(fd: Handle) -> Errno {
err := wasi.fd_close(wasi.fd_t(fd))
return Errno(err)
}
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
n, err := wasi.fd_seek(wasi.fd_t(fd), wasi.filedelta_t(offset), wasi.whence_t(whence))
return i64(n), Errno(err)
}
current_thread_id :: proc "contextless" () -> int {
return 0
}
file_size :: proc(fd: Handle) -> (i64, Errno) {
stat, err := wasi.fd_filestat_get(wasi.fd_t(fd))
if err != nil {
return 0, Errno(err)
}
return i64(stat.size), 0
}
heap_alloc :: proc(size: int) -> rawptr {
return nil
}
heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
if new_size == 0 {
heap_free(ptr)
return nil
}
if ptr == nil {
return heap_alloc(new_size)
}
return nil
}
heap_free :: proc(ptr: rawptr) {
if ptr == nil {
return
}
}
exit :: proc "contextless" (code: int) -> ! {
wasi.proc_exit(wasi.exitcode_t(code))
}