From 05cfc89283a3d9d19801119b7a87e40b6b930524 Mon Sep 17 00:00:00 2001 From: avanspector Date: Sun, 25 Feb 2024 18:20:03 +0100 Subject: [PATCH] fix core:os --- core/os/os_haiku.odin | 98 ++++++++++++++++++++++++++++++++++++++++++ core/os/stat_unix.odin | 2 +- core/os/stream.odin | 6 +-- 3 files changed, 102 insertions(+), 4 deletions(-) diff --git a/core/os/os_haiku.odin b/core/os/os_haiku.odin index 2646de0f8..9cc56b0a2 100644 --- a/core/os/os_haiku.odin +++ b/core/os/os_haiku.odin @@ -22,6 +22,59 @@ stdin: Handle = 0 stdout: Handle = 1 stderr: Handle = 2 +pid_t :: distinct i32 +off_t :: distinct i64 +dev_t :: distinct i32 +ino_t :: distinct i64 +mode_t :: distinct u32 +nlink_t :: distinct i32 +uid_t :: distinct u32 +gid_t :: distinct u32 +blksize_t :: distinct i32 +blkcnt_t :: distinct i64 + + +Unix_File_Time :: struct { + seconds: time_t, + nanoseconds: c.long, +} + +OS_Stat :: struct { + device_id: dev_t, // device ID that this file resides on + serial: ino_t, // this file's serial inode ID + mode: mode_t, // file mode (rwx for user, group, etc) + nlink: nlink_t, // number of hard links to this file + uid: uid_t, // user ID of the file's owner + gid: gid_t, // group ID of the file's group + size: off_t, // file size, in bytes + rdev: dev_t, // device type (not used) + block_size: blksize_t, // optimal blocksize for I/O + + last_access: Unix_File_Time, // time of last access + modified: Unix_File_Time, // time of last data modification + status_change: Unix_File_Time, // time of last file status change + birthtime: Unix_File_Time, // time of file creation + + type: u32 // attribute/index type + + blocks: blkcnt_t, // blocks allocated for file +} + +/* file access modes for open() */ +O_RDONLY :: 0x0000 /* read only */ +O_WRONLY :: 0x0001 /* write only */ +O_RDWR :: 0x0002 /* read and write */ +O_ACCMODE :: 0x0003 /* mask to get the access modes above */ +O_RWMASK :: O_ACCMODE + +/* flags for open() */ +O_EXCL :: 0x0100 /* exclusive creat */ +O_CREAT :: 0x0200 /* create and open file */ +O_TRUNC :: 0x0400 /* open with truncation */ +O_NOCTTY :: 0x1000 /* don't make tty the controlling tty */ +O_NOTRAVERSE :: 0x2000 /* do not traverse leaf link */ + + foreign libc { @(link_name="_errnop") __error :: proc() -> ^c.int --- @@ -102,6 +155,51 @@ close :: proc(fd: Handle) -> Errno { return ERROR_NONE } +// In practice a read/write call would probably never read/write these big buffers all at once, +// which is why the number of bytes is returned and why there are procs that will call this in a +// loop for you. +// We set a max of 1GB to keep alignment and to be safe. +@(private) +MAX_RW :: 1 << 30 + +read :: proc(fd: Handle, data: []byte) -> (int, Errno) { + to_read := min(c.size_t(len(data)), MAX_RW) + bytes_read := _unix_read(fd, &data[0], to_read) + if bytes_read == -1 { + return -1, Errno(get_last_error()) + } + return int(bytes_read), ERROR_NONE +} + +write :: proc(fd: Handle, data: []byte) -> (int, Errno) { + if len(data) == 0 { + return 0, ERROR_NONE + } + + to_write := min(c.size_t(len(data)), MAX_RW) + bytes_written := _unix_write(fd, &data[0], to_write) + if bytes_written == -1 { + return -1, Errno(get_last_error()) + } + return int(bytes_written), ERROR_NONE +} + +seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { + res := _unix_seek(fd, offset, c.int(whence)) + if res == -1 { + return -1, Errno(get_last_error()) + } + return res, ERROR_NONE +} + +file_size :: proc(fd: Handle) -> (i64, Errno) { + s, err := _fstat(fd) + if err != ERROR_NONE { + return -1, err + } + return s.size, ERROR_NONE +} + _alloc_command_line_arguments :: proc() -> []string { res := make([]string, len(runtime.args__)) for arg, i in runtime.args__ { diff --git a/core/os/stat_unix.odin b/core/os/stat_unix.odin index dae7ab2fb..5e83c0e16 100644 --- a/core/os/stat_unix.odin +++ b/core/os/stat_unix.odin @@ -1,4 +1,4 @@ -//+build linux, darwin, freebsd, openbsd +//+build linux, darwin, freebsd, openbsd, haiku package os import "core:time" diff --git a/core/os/stream.odin b/core/os/stream.odin index d7ce11d26..25f31218c 100644 --- a/core/os/stream.odin +++ b/core/os/stream.odin @@ -32,7 +32,7 @@ _file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, } case .Read_At: - when !(ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD) { + when !(ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku) { n_int, os_err = read_at(fd, p, offset) n = i64(n_int) if n == 0 && os_err == 0 { @@ -46,7 +46,7 @@ _file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, err = .EOF } case .Write_At: - when !(ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD) { + when !(ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku) { n_int, os_err = write_at(fd, p, offset) n = i64(n_int) if n == 0 && os_err == 0 { @@ -60,7 +60,7 @@ _file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, case .Destroy: err = .Empty case .Query: - when ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD { + when ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku { return io.query_utility({.Close, .Flush, .Read, .Write, .Seek, .Size, .Query}) } else { return io.query_utility({.Close, .Flush, .Read, .Read_At, .Write, .Write_At, .Seek, .Size, .Query})