mirror of
https://github.com/odin-lang/Odin.git
synced 2026-05-24 16:59:11 -04:00
removed core:sys/haiku package
also removes Haiku from core:sys/info, core:os/old, core:path/filepath, core:dynlib, core:time, core:testing, and core:terminal (minor changes) Signed-off-by: Ignacy Koper <ignacy423@gmail.com>
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
#+build haiku
|
||||
#+private
|
||||
package dynlib
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
_LIBRARY_FILE_EXTENSION :: ""
|
||||
|
||||
_load_library :: proc(path: string, global_symbols: bool, allocator: runtime.Allocator) -> (Library, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
_unload_library :: proc(library: Library) -> bool {
|
||||
return false
|
||||
}
|
||||
|
||||
_symbol_address :: proc(library: Library, symbol: string, allocator: runtime.Allocator) -> (ptr: rawptr, found: bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
_last_error :: proc() -> string {
|
||||
return ""
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#+build darwin, linux, netbsd, freebsd, openbsd, haiku
|
||||
#+build darwin, linux, netbsd, freebsd, openbsd
|
||||
package os_old
|
||||
|
||||
import "core:strings"
|
||||
|
||||
@@ -1,544 +0,0 @@
|
||||
package os_old
|
||||
|
||||
foreign import lib "system:c"
|
||||
|
||||
import "base:runtime"
|
||||
import "core:c"
|
||||
import "core:c/libc"
|
||||
import "core:strings"
|
||||
import "core:sys/haiku"
|
||||
import "core:sys/posix"
|
||||
|
||||
Handle :: i32
|
||||
Pid :: i32
|
||||
File_Time :: i64
|
||||
_Platform_Error :: haiku.Errno
|
||||
|
||||
MAX_PATH :: haiku.PATH_MAX
|
||||
|
||||
ENOSYS :: _Platform_Error(haiku.Errno.ENOSYS)
|
||||
|
||||
INVALID_HANDLE :: ~Handle(0)
|
||||
|
||||
stdin: Handle = 0
|
||||
stdout: Handle = 1
|
||||
stderr: Handle = 2
|
||||
|
||||
pid_t :: haiku.pid_t
|
||||
off_t :: haiku.off_t
|
||||
dev_t :: haiku.dev_t
|
||||
ino_t :: haiku.ino_t
|
||||
mode_t :: haiku.mode_t
|
||||
nlink_t :: haiku.nlink_t
|
||||
uid_t :: haiku.uid_t
|
||||
gid_t :: haiku.gid_t
|
||||
blksize_t :: haiku.blksize_t
|
||||
blkcnt_t :: haiku.blkcnt_t
|
||||
time_t :: haiku.time_t
|
||||
|
||||
|
||||
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_CREATE :: 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 */
|
||||
|
||||
// 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
|
||||
S_ISVTX :: 0o001000 // Save swapped text even after use
|
||||
|
||||
// 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_ISTXT :: 0o1000 // Sticky bit
|
||||
|
||||
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 }
|
||||
|
||||
__error :: libc.errno
|
||||
_unix_open :: posix.open
|
||||
|
||||
foreign lib {
|
||||
@(link_name="fork") _unix_fork :: proc() -> pid_t ---
|
||||
@(link_name="getthrid") _unix_getthrid :: proc() -> int ---
|
||||
|
||||
@(link_name="close") _unix_close :: proc(fd: Handle) -> c.int ---
|
||||
@(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t ---
|
||||
@(link_name="pread") _unix_pread :: proc(fd: Handle, buf: rawptr, size: c.size_t, offset: i64) -> c.ssize_t ---
|
||||
@(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t ---
|
||||
@(link_name="pwrite") _unix_pwrite :: proc(fd: Handle, buf: rawptr, size: c.size_t, offset: i64) -> c.ssize_t ---
|
||||
@(link_name="lseek") _unix_seek :: proc(fd: Handle, offset: off_t, whence: c.int) -> off_t ---
|
||||
@(link_name="stat") _unix_stat :: proc(path: cstring, sb: ^OS_Stat) -> c.int ---
|
||||
@(link_name="fstat") _unix_fstat :: proc(fd: Handle, sb: ^OS_Stat) -> c.int ---
|
||||
@(link_name="lstat") _unix_lstat :: proc(path: cstring, sb: ^OS_Stat) -> c.int ---
|
||||
@(link_name="readlink") _unix_readlink :: proc(path: cstring, buf: ^byte, bufsiz: c.size_t) -> c.ssize_t ---
|
||||
@(link_name="access") _unix_access :: proc(path: cstring, mask: c.int) -> c.int ---
|
||||
@(link_name="getcwd") _unix_getcwd :: proc(buf: cstring, len: c.size_t) -> cstring ---
|
||||
@(link_name="chdir") _unix_chdir :: proc(path: cstring) -> c.int ---
|
||||
@(link_name="rename") _unix_rename :: proc(old, new: cstring) -> c.int ---
|
||||
@(link_name="unlink") _unix_unlink :: proc(path: cstring) -> c.int ---
|
||||
@(link_name="rmdir") _unix_rmdir :: proc(path: cstring) -> c.int ---
|
||||
@(link_name="mkdir") _unix_mkdir :: proc(path: cstring, mode: mode_t) -> c.int ---
|
||||
@(link_name="fsync") _unix_fsync :: proc(fd: Handle) -> c.int ---
|
||||
|
||||
@(link_name="getpagesize") _unix_getpagesize :: proc() -> c.int ---
|
||||
@(link_name="sysconf") _sysconf :: proc(name: c.int) -> c.long ---
|
||||
@(link_name="fdopendir") _unix_fdopendir :: proc(fd: Handle) -> Dir ---
|
||||
@(link_name="closedir") _unix_closedir :: proc(dirp: Dir) -> c.int ---
|
||||
@(link_name="rewinddir") _unix_rewinddir :: proc(dirp: Dir) ---
|
||||
@(link_name="readdir_r") _unix_readdir_r :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int ---
|
||||
@(link_name="dup") _unix_dup :: proc(fd: Handle) -> Handle ---
|
||||
|
||||
@(link_name="malloc") _unix_malloc :: proc(size: c.size_t) -> rawptr ---
|
||||
@(link_name="calloc") _unix_calloc :: proc(num, size: c.size_t) -> rawptr ---
|
||||
@(link_name="free") _unix_free :: proc(ptr: rawptr) ---
|
||||
@(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr ---
|
||||
|
||||
@(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring ---
|
||||
@(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: [^]byte = nil) -> cstring ---
|
||||
|
||||
@(link_name="exit") _unix_exit :: proc(status: c.int) -> ! ---
|
||||
|
||||
@(link_name="dlopen") _unix_dlopen :: proc(filename: cstring, flags: c.int) -> rawptr ---
|
||||
@(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: cstring) -> rawptr ---
|
||||
@(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> c.int ---
|
||||
@(link_name="dlerror") _unix_dlerror :: proc() -> cstring ---
|
||||
}
|
||||
|
||||
MAXNAMLEN :: haiku.NAME_MAX
|
||||
|
||||
Dirent :: struct {
|
||||
dev: dev_t,
|
||||
pdef: dev_t,
|
||||
ino: ino_t,
|
||||
pino: ino_t,
|
||||
reclen: u16,
|
||||
name: [MAXNAMLEN + 1]byte, // name
|
||||
}
|
||||
|
||||
Dir :: distinct rawptr // DIR*
|
||||
|
||||
@(require_results)
|
||||
is_path_separator :: proc(r: rune) -> bool {
|
||||
return r == '/'
|
||||
}
|
||||
|
||||
@(require_results, no_instrumentation)
|
||||
get_last_error :: proc "contextless" () -> Error {
|
||||
return Platform_Error(__error()^)
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
fork :: proc() -> (Pid, Error) {
|
||||
pid := _unix_fork()
|
||||
if pid == -1 {
|
||||
return Pid(-1), get_last_error()
|
||||
}
|
||||
return Pid(pid), nil
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Error) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
||||
handle := cast(Handle)_unix_open(cstr, transmute(posix.O_Flags)i32(flags), transmute(posix.mode_t)i32(mode))
|
||||
if handle == -1 {
|
||||
return INVALID_HANDLE, get_last_error()
|
||||
}
|
||||
return handle, nil
|
||||
}
|
||||
|
||||
close :: proc(fd: Handle) -> Error {
|
||||
result := _unix_close(fd)
|
||||
if result == -1 {
|
||||
return get_last_error()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
flush :: proc(fd: Handle) -> Error {
|
||||
result := _unix_fsync(fd)
|
||||
if result == -1 {
|
||||
return get_last_error()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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, Error) {
|
||||
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, get_last_error()
|
||||
}
|
||||
return int(bytes_read), nil
|
||||
}
|
||||
|
||||
write :: proc(fd: Handle, data: []byte) -> (int, Error) {
|
||||
if len(data) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
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, get_last_error()
|
||||
}
|
||||
return int(bytes_written), nil
|
||||
}
|
||||
|
||||
read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) {
|
||||
if len(data) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
to_read := min(uint(len(data)), MAX_RW)
|
||||
|
||||
bytes_read := _unix_pread(fd, raw_data(data), to_read, offset)
|
||||
if bytes_read < 0 {
|
||||
return -1, get_last_error()
|
||||
}
|
||||
return bytes_read, nil
|
||||
}
|
||||
|
||||
write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) {
|
||||
if len(data) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
to_write := min(uint(len(data)), MAX_RW)
|
||||
|
||||
bytes_written := _unix_pwrite(fd, raw_data(data), to_write, offset)
|
||||
if bytes_written < 0 {
|
||||
return -1, get_last_error()
|
||||
}
|
||||
return bytes_written, nil
|
||||
}
|
||||
|
||||
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
|
||||
switch whence {
|
||||
case SEEK_SET, SEEK_CUR, SEEK_END:
|
||||
break
|
||||
case:
|
||||
return 0, .Invalid_Whence
|
||||
}
|
||||
res := _unix_seek(fd, offset, c.int(whence))
|
||||
if res == -1 {
|
||||
errno := get_last_error()
|
||||
switch errno {
|
||||
case .BAD_VALUE:
|
||||
return 0, .Invalid_Offset
|
||||
}
|
||||
return 0, errno
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
file_size :: proc(fd: Handle) -> (i64, Error) {
|
||||
s, err := _fstat(fd)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return s.size, nil
|
||||
}
|
||||
|
||||
// "Argv" arguments converted to Odin strings
|
||||
args := _alloc_command_line_arguments()
|
||||
|
||||
@(private, require_results)
|
||||
_alloc_command_line_arguments :: proc "contextless" () -> []string {
|
||||
context = runtime.default_context()
|
||||
res := make([]string, len(runtime.args__))
|
||||
for arg, i in runtime.args__ {
|
||||
res[i] = string(arg)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@(private, fini)
|
||||
_delete_command_line_arguments :: proc "contextless" () {
|
||||
context = runtime.default_context()
|
||||
delete(args)
|
||||
}
|
||||
|
||||
@(private, require_results, no_sanitize_memory)
|
||||
_stat :: proc(path: string) -> (OS_Stat, Error) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
||||
|
||||
// deliberately uninitialized
|
||||
s: OS_Stat = ---
|
||||
res := _unix_stat(cstr, &s)
|
||||
if res == -1 {
|
||||
return s, get_last_error()
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@(private, require_results, no_sanitize_memory)
|
||||
_lstat :: proc(path: string) -> (OS_Stat, Error) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
||||
|
||||
// deliberately uninitialized
|
||||
s: OS_Stat = ---
|
||||
res := _unix_lstat(cstr, &s)
|
||||
if res == -1 {
|
||||
return s, get_last_error()
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@(private, require_results, no_sanitize_memory)
|
||||
_fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
|
||||
// deliberately uninitialized
|
||||
s: OS_Stat = ---
|
||||
res := _unix_fstat(fd, &s)
|
||||
if res == -1 {
|
||||
return s, get_last_error()
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@(private)
|
||||
_fdopendir :: proc(fd: Handle) -> (Dir, Error) {
|
||||
dirp := _unix_fdopendir(fd)
|
||||
if dirp == cast(Dir)nil {
|
||||
return nil, get_last_error()
|
||||
}
|
||||
return dirp, nil
|
||||
}
|
||||
|
||||
@(private)
|
||||
_closedir :: proc(dirp: Dir) -> Error {
|
||||
rc := _unix_closedir(dirp)
|
||||
if rc != 0 {
|
||||
return get_last_error()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@(private)
|
||||
_rewinddir :: proc(dirp: Dir) {
|
||||
_unix_rewinddir(dirp)
|
||||
}
|
||||
|
||||
@(private, require_results)
|
||||
_readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) {
|
||||
result: ^Dirent
|
||||
rc := _unix_readdir_r(dirp, &entry, &result)
|
||||
|
||||
if rc != 0 {
|
||||
err = get_last_error()
|
||||
return
|
||||
}
|
||||
|
||||
if result == nil {
|
||||
end_of_stream = true
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@(private, require_results)
|
||||
_readlink :: proc(path: string) -> (string, Error) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator)
|
||||
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
||||
|
||||
bufsz : uint = MAX_PATH
|
||||
buf := make([]byte, MAX_PATH)
|
||||
for {
|
||||
rc := _unix_readlink(path_cstr, &(buf[0]), bufsz)
|
||||
if rc == -1 {
|
||||
delete(buf)
|
||||
return "", get_last_error()
|
||||
} else if rc == int(bufsz) {
|
||||
bufsz += MAX_PATH
|
||||
delete(buf)
|
||||
buf = make([]byte, bufsz)
|
||||
} else {
|
||||
return strings.string_from_ptr(&buf[0], rc), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) {
|
||||
return "", Error(ENOSYS)
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
absolute_path_from_relative :: proc(rel: string, allocator := context.allocator) -> (path: string, err: Error) {
|
||||
rel := rel
|
||||
if rel == "" {
|
||||
rel = "."
|
||||
}
|
||||
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator)
|
||||
rel_cstr := strings.clone_to_cstring(rel, context.temp_allocator)
|
||||
|
||||
path_ptr := _unix_realpath(rel_cstr, nil)
|
||||
if path_ptr == nil {
|
||||
return "", get_last_error()
|
||||
}
|
||||
defer _unix_free(rawptr(path_ptr))
|
||||
|
||||
path_cstr := cstring(path_ptr)
|
||||
return strings.clone(string(path_cstr), allocator)
|
||||
}
|
||||
|
||||
access :: proc(path: string, mask: int) -> (bool, Error) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
||||
res := _unix_access(cstr, c.int(mask))
|
||||
if res == -1 {
|
||||
return false, get_last_error()
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
lookup_env_alloc :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == allocator)
|
||||
path_str := strings.clone_to_cstring(key, context.temp_allocator)
|
||||
// NOTE(tetra): Lifetime of 'cstr' is unclear, but _unix_free(cstr) segfaults.
|
||||
cstr := _unix_getenv(path_str)
|
||||
if cstr == nil {
|
||||
return "", false
|
||||
}
|
||||
return strings.clone(string(cstr), allocator), true
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
lookup_env_buffer :: proc(buf: []u8, key: string) -> (value: string, err: Error) {
|
||||
if len(key) + 1 > len(buf) {
|
||||
return "", .Buffer_Full
|
||||
} else {
|
||||
copy(buf, key)
|
||||
buf[len(key)] = 0
|
||||
}
|
||||
|
||||
if value = string(_unix_getenv(cstring(raw_data(buf)))); value == "" {
|
||||
return "", .Env_Var_Not_Found
|
||||
} else {
|
||||
if len(value) > len(buf) {
|
||||
return "", .Buffer_Full
|
||||
} else {
|
||||
copy(buf, value)
|
||||
return string(buf[:len(value)]), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
lookup_env :: proc{lookup_env_alloc, lookup_env_buffer}
|
||||
|
||||
@(require_results)
|
||||
get_env_alloc :: proc(key: string, allocator := context.allocator) -> (value: string) {
|
||||
value, _ = lookup_env(key, allocator)
|
||||
return
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
get_env_buf :: proc(buf: []u8, key: string) -> (value: string) {
|
||||
value, _ = lookup_env(buf, key)
|
||||
return
|
||||
}
|
||||
get_env :: proc{get_env_alloc, get_env_buf}
|
||||
|
||||
|
||||
@(private, require_results)
|
||||
_processor_core_count :: proc() -> int {
|
||||
info: haiku.system_info
|
||||
haiku.get_system_info(&info)
|
||||
return int(info.cpu_count)
|
||||
}
|
||||
|
||||
exit :: proc "contextless" (code: int) -> ! {
|
||||
runtime._cleanup_runtime_contextless()
|
||||
_unix_exit(i32(code))
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
current_thread_id :: proc "contextless" () -> int {
|
||||
return int(haiku.find_thread(nil))
|
||||
}
|
||||
|
||||
@(private, require_results)
|
||||
_dup :: proc(fd: Handle) -> (Handle, Error) {
|
||||
dup := _unix_dup(fd)
|
||||
if dup == -1 {
|
||||
return INVALID_HANDLE, get_last_error()
|
||||
}
|
||||
return dup, nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
|
||||
#+build linux, darwin, freebsd, openbsd, netbsd
|
||||
package os_old
|
||||
|
||||
import "core:time"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
|
||||
#+build linux, darwin, freebsd, openbsd, netbsd
|
||||
package filepath
|
||||
|
||||
SEPARATOR :: '/'
|
||||
SEPARATOR_STRING :: `/`
|
||||
LIST_SEPARATOR :: ':'
|
||||
LIST_SEPARATOR :: ':'
|
||||
|
||||
@@ -1,302 +0,0 @@
|
||||
#+build haiku
|
||||
package sys_haiku
|
||||
|
||||
import "core:sys/posix"
|
||||
|
||||
foreign import libroot "system:c"
|
||||
|
||||
USE_POSITIVE_POSIX_ERRORS :: posix._HAIKU_USE_POSITIVE_POSIX_ERRORS
|
||||
POSIX_ERROR_FACTOR :: posix._POSIX_ERROR_FACTOR
|
||||
|
||||
// Error baselines
|
||||
GENERAL_ERROR_BASE :: min(i32)
|
||||
OS_ERROR_BASE :: GENERAL_ERROR_BASE + 0x1000
|
||||
APP_ERROR_BASE :: GENERAL_ERROR_BASE + 0x2000
|
||||
INTERFACE_ERROR_BASE :: GENERAL_ERROR_BASE + 0x3000
|
||||
MEDIA_ERROR_BASE :: GENERAL_ERROR_BASE + 0x4000
|
||||
TRANSLATION_ERROR_BASE :: GENERAL_ERROR_BASE + 0x4800
|
||||
MIDI_ERROR_BASE :: GENERAL_ERROR_BASE + 0x5000
|
||||
STORAGE_ERROR_BASE :: GENERAL_ERROR_BASE + 0x6000
|
||||
POSIX_ERROR_BASE :: GENERAL_ERROR_BASE + 0x7000
|
||||
MAIL_ERROR_BASE :: GENERAL_ERROR_BASE + 0x8000
|
||||
PRINT_ERROR_BASE :: GENERAL_ERROR_BASE + 0x9000
|
||||
DEVICE_ERROR_BASE :: GENERAL_ERROR_BASE + 0xA000
|
||||
|
||||
// Developer-defined errors start at (ERRORS_END+1)
|
||||
ERRORS_END :: GENERAL_ERROR_BASE + 0xFFFF
|
||||
|
||||
Errno :: enum i32 {
|
||||
// General Errors
|
||||
NO_MEMORY = GENERAL_ERROR_BASE + 0,
|
||||
IO_ERROR = GENERAL_ERROR_BASE + 1,
|
||||
PERMISSION_DENIED = GENERAL_ERROR_BASE + 2,
|
||||
BAD_INDEX = GENERAL_ERROR_BASE + 3,
|
||||
BAD_TYPE = GENERAL_ERROR_BASE + 4,
|
||||
BAD_VALUE = GENERAL_ERROR_BASE + 5,
|
||||
MISMATCHED_VALUES = GENERAL_ERROR_BASE + 6,
|
||||
NAME_NOT_FOUND = GENERAL_ERROR_BASE + 7,
|
||||
NAME_IN_USE = GENERAL_ERROR_BASE + 8,
|
||||
TIMED_OUT = GENERAL_ERROR_BASE + 9,
|
||||
INTERRUPTED = GENERAL_ERROR_BASE + 10,
|
||||
WOULD_BLOCK = GENERAL_ERROR_BASE + 11,
|
||||
CANCELED = GENERAL_ERROR_BASE + 12,
|
||||
NO_INIT = GENERAL_ERROR_BASE + 13,
|
||||
NOT_INITIALIZED = GENERAL_ERROR_BASE + 13,
|
||||
BUSY = GENERAL_ERROR_BASE + 14,
|
||||
NOT_ALLOWED = GENERAL_ERROR_BASE + 15,
|
||||
BAD_DATA = GENERAL_ERROR_BASE + 16,
|
||||
DONT_DO_THAT = GENERAL_ERROR_BASE + 17,
|
||||
|
||||
ERROR = -1,
|
||||
OK = 0,
|
||||
NO_ERROR = 0,
|
||||
|
||||
// Kernel Kit Errors
|
||||
BAD_SEM_ID = OS_ERROR_BASE + 0,
|
||||
NO_MORE_SEMS = OS_ERROR_BASE + 1,
|
||||
BAD_THREAD_ID = OS_ERROR_BASE + 0x100,
|
||||
NO_MORE_THREADS = OS_ERROR_BASE + 0x101,
|
||||
BAD_THREAD_STATE = OS_ERROR_BASE + 0x102,
|
||||
BAD_TEAM_ID = OS_ERROR_BASE + 0x103,
|
||||
NO_MORE_TEAMS = OS_ERROR_BASE + 0x104,
|
||||
BAD_PORT_ID = OS_ERROR_BASE + 0x200,
|
||||
NO_MORE_PORTS = OS_ERROR_BASE + 0x201,
|
||||
BAD_IMAGE_ID = OS_ERROR_BASE + 0x300,
|
||||
BAD_ADDRESS = OS_ERROR_BASE + 0x301,
|
||||
NOT_AN_EXECUTABLE = OS_ERROR_BASE + 0x302,
|
||||
MISSING_LIBRARY = OS_ERROR_BASE + 0x303,
|
||||
MISSING_SYMBOL = OS_ERROR_BASE + 0x304,
|
||||
UNKNOWN_EXECUTABLE = OS_ERROR_BASE + 0x305,
|
||||
LEGACY_EXECUTABLE = OS_ERROR_BASE + 0x306,
|
||||
|
||||
DEBUGGER_ALREADY_INSTALLED = OS_ERROR_BASE + 0x400,
|
||||
|
||||
// Application Kit Errors
|
||||
BAD_REPLY = APP_ERROR_BASE + 0,
|
||||
DUPLICATE_REPLY = APP_ERROR_BASE + 1,
|
||||
MESSAGE_TO_SELF = APP_ERROR_BASE + 2,
|
||||
BAD_HANDLER = APP_ERROR_BASE + 3,
|
||||
ALREADY_RUNNING = APP_ERROR_BASE + 4,
|
||||
LAUNCH_FAILED = APP_ERROR_BASE + 5,
|
||||
AMBIGUOUS_APP_LAUNCH = APP_ERROR_BASE + 6,
|
||||
UNKNOWN_MIME_TYPE = APP_ERROR_BASE + 7,
|
||||
BAD_SCRIPT_SYNTAX = APP_ERROR_BASE + 8,
|
||||
LAUNCH_FAILED_NO_RESOLVE_LINK = APP_ERROR_BASE + 9,
|
||||
LAUNCH_FAILED_EXECUTABLE = APP_ERROR_BASE + 10,
|
||||
LAUNCH_FAILED_APP_NOT_FOUND = APP_ERROR_BASE + 11,
|
||||
LAUNCH_FAILED_APP_IN_TRASH = APP_ERROR_BASE + 12,
|
||||
LAUNCH_FAILED_NO_PREFERRED_APP = APP_ERROR_BASE + 13,
|
||||
LAUNCH_FAILED_FILES_APP_NOT_FOUND = APP_ERROR_BASE + 14,
|
||||
BAD_MIME_SNIFFER_RULE = APP_ERROR_BASE + 15,
|
||||
NOT_A_MESSAGE = APP_ERROR_BASE + 16,
|
||||
SHUTDOWN_CANCELLED = APP_ERROR_BASE + 17,
|
||||
SHUTTING_DOWN = APP_ERROR_BASE + 18,
|
||||
|
||||
// Storage Kit/File System Errors
|
||||
FILE_ERROR = STORAGE_ERROR_BASE + 0,
|
||||
// 1 was B_FILE_NOT_FOUND (deprecated)
|
||||
FILE_EXISTS = STORAGE_ERROR_BASE + 2,
|
||||
ENTRY_NOT_FOUND = STORAGE_ERROR_BASE + 3,
|
||||
NAME_TOO_LONG = STORAGE_ERROR_BASE + 4,
|
||||
NOT_A_DIRECTORY = STORAGE_ERROR_BASE + 5,
|
||||
DIRECTORY_NOT_EMPTY = STORAGE_ERROR_BASE + 6,
|
||||
DEVICE_FULL = STORAGE_ERROR_BASE + 7,
|
||||
READ_ONLY_DEVICE = STORAGE_ERROR_BASE + 8,
|
||||
IS_A_DIRECTORY = STORAGE_ERROR_BASE + 9,
|
||||
NO_MORE_FDS = STORAGE_ERROR_BASE + 10,
|
||||
CROSS_DEVICE_LINK = STORAGE_ERROR_BASE + 11,
|
||||
LINK_LIMIT = STORAGE_ERROR_BASE + 12,
|
||||
BUSTED_PIPE = STORAGE_ERROR_BASE + 13,
|
||||
UNSUPPORTED = STORAGE_ERROR_BASE + 14,
|
||||
PARTITION_TOO_SMALL = STORAGE_ERROR_BASE + 15,
|
||||
PARTIAL_READ = STORAGE_ERROR_BASE + 16,
|
||||
PARTIAL_WRITE = STORAGE_ERROR_BASE + 17,
|
||||
|
||||
EIO = posix.EIO,
|
||||
EACCES = posix.EACCES,
|
||||
EINVAL = posix.EINVAL,
|
||||
ETIMEDOUT = posix.ETIMEDOUT,
|
||||
EINTR = posix.EINTR,
|
||||
EAGAIN = posix.EAGAIN,
|
||||
EWOULDBLOCK = posix.EWOULDBLOCK,
|
||||
EBUSY = posix.EBUSY,
|
||||
EPERM = posix.EPERM,
|
||||
EFAULT = posix.EFAULT,
|
||||
ENOEXEC = posix.ENOEXEC,
|
||||
EBADF = posix.EBADF,
|
||||
EEXIST = posix.EEXIST,
|
||||
ENOENT = posix.ENOENT,
|
||||
ENAMETOOLONG = posix.ENAMETOOLONG,
|
||||
ENOTDIR = posix.ENOTDIR,
|
||||
ENOTEMPTY = posix.ENOTEMPTY,
|
||||
ENOSPC = posix.ENOSPC,
|
||||
EROFS = posix.EROFS,
|
||||
EISDIR = posix.EISDIR,
|
||||
EMFILE = posix.EMFILE,
|
||||
EXDEV = posix.EXDEV,
|
||||
ELOOP = posix.ELOOP,
|
||||
EPIPE = posix.EPIPE,
|
||||
ENOMEM = posix.ENOMEM,
|
||||
E2BIG = posix.E2BIG,
|
||||
ECHILD = posix.ECHILD,
|
||||
EDEADLK = posix.EDEADLK,
|
||||
EFBIG = posix.EFBIG,
|
||||
EMLINK = posix.EMLINK,
|
||||
ENFILE = posix.ENFILE,
|
||||
ENODEV = posix.ENODEV,
|
||||
ENOLCK = posix.ENOLCK,
|
||||
ENOSYS = posix.ENOSYS,
|
||||
ENOTTY = posix.ENOTTY,
|
||||
ENXIO = posix.ENXIO,
|
||||
ESPIPE = posix.ESPIPE,
|
||||
ESRCH = posix.ESRCH,
|
||||
EDOM = posix.EDOM,
|
||||
ERANGE = posix.ERANGE,
|
||||
EPROTOTYPE = posix.EPROTOTYPE,
|
||||
EPROTONOSUPPORT = posix.EPROTONOSUPPORT,
|
||||
EAFNOSUPPORT = posix.EAFNOSUPPORT,
|
||||
EADDRINUSE = posix.EADDRINUSE,
|
||||
EADDRNOTAVAIL = posix.EADDRNOTAVAIL,
|
||||
ENETDOWN = posix.ENETDOWN,
|
||||
ENETUNREACH = posix.ENETUNREACH,
|
||||
ENETRESET = posix.ENETRESET,
|
||||
ECONNABORTED = posix.ECONNABORTED,
|
||||
ECONNRESET = posix.ECONNRESET,
|
||||
EISCONN = posix.EISCONN,
|
||||
ENOTCONN = posix.ENOTCONN,
|
||||
ECONNREFUSED = posix.ECONNREFUSED,
|
||||
EHOSTUNREACH = posix.EHOSTUNREACH,
|
||||
ENOPROTOOPT = posix.ENOPROTOOPT,
|
||||
ENOBUFS = posix.ENOBUFS,
|
||||
EINPROGRESS = posix.EINPROGRESS,
|
||||
EALREADY = posix.EALREADY,
|
||||
EILSEQ = posix.EILSEQ,
|
||||
ENOMSG = posix.ENOMSG,
|
||||
ESTALE = posix.ESTALE,
|
||||
EOVERFLOW = posix.EOVERFLOW,
|
||||
EMSGSIZE = posix.EMSGSIZE,
|
||||
EOPNOTSUPP = posix.EOPNOTSUPP,
|
||||
ENOTSOCK = posix.ENOTSOCK,
|
||||
EBADMSG = posix.EBADMSG,
|
||||
ECANCELED = posix.ECANCELED,
|
||||
EDESTADDRREQ = posix.EDESTADDRREQ,
|
||||
EDQUOT = posix.EDQUOT,
|
||||
EIDRM = posix.EIDRM,
|
||||
EMULTIHOP = posix.EMULTIHOP,
|
||||
ENODATA = posix.ENODATA,
|
||||
ENOLINK = posix.ENOLINK,
|
||||
ENOSR = posix.ENOSR,
|
||||
ENOSTR = posix.ENOSTR,
|
||||
ENOTSUP = posix.ENOTSUP,
|
||||
EPROTO = posix.EPROTO,
|
||||
ETIME = posix.ETIME,
|
||||
ETXTBSY = posix.ETXTBSY,
|
||||
ENOTRECOVERABLE = posix.ENOTRECOVERABLE,
|
||||
EOWNERDEAD = posix.EOWNERDEAD,
|
||||
|
||||
// New error codes that can be mapped to POSIX errors
|
||||
TOO_MANY_ARGS = POSIX_ERROR_FACTOR * E2BIG,
|
||||
FILE_TOO_LARGE = POSIX_ERROR_FACTOR * EFBIG,
|
||||
DEVICE_NOT_FOUND = POSIX_ERROR_FACTOR * ENODEV,
|
||||
RESULT_NOT_REPRESENTABLE = POSIX_ERROR_FACTOR * ERANGE,
|
||||
BUFFER_OVERFLOW = POSIX_ERROR_FACTOR * EOVERFLOW,
|
||||
NOT_SUPPORTED = POSIX_ERROR_FACTOR * EOPNOTSUPP,
|
||||
|
||||
// Media Kit Errors
|
||||
STREAM_NOT_FOUND = MEDIA_ERROR_BASE + 0,
|
||||
SERVER_NOT_FOUND = MEDIA_ERROR_BASE + 1,
|
||||
RESOURCE_NOT_FOUND = MEDIA_ERROR_BASE + 2,
|
||||
RESOURCE_UNAVAILABLE = MEDIA_ERROR_BASE + 3,
|
||||
BAD_SUBSCRIBER = MEDIA_ERROR_BASE + 4,
|
||||
SUBSCRIBER_NOT_ENTERED = MEDIA_ERROR_BASE + 5,
|
||||
BUFFER_NOT_AVAILABLE = MEDIA_ERROR_BASE + 6,
|
||||
LAST_BUFFER_ERROR = MEDIA_ERROR_BASE + 7,
|
||||
MEDIA_SYSTEM_FAILURE = MEDIA_ERROR_BASE + 100,
|
||||
MEDIA_BAD_NODE = MEDIA_ERROR_BASE + 101,
|
||||
MEDIA_NODE_BUSY = MEDIA_ERROR_BASE + 102,
|
||||
MEDIA_BAD_FORMAT = MEDIA_ERROR_BASE + 103,
|
||||
MEDIA_BAD_BUFFER = MEDIA_ERROR_BASE + 104,
|
||||
MEDIA_TOO_MANY_NODES = MEDIA_ERROR_BASE + 105,
|
||||
MEDIA_TOO_MANY_BUFFERS = MEDIA_ERROR_BASE + 106,
|
||||
MEDIA_NODE_ALREADY_EXISTS = MEDIA_ERROR_BASE + 107,
|
||||
MEDIA_BUFFER_ALREADY_EXISTS = MEDIA_ERROR_BASE + 108,
|
||||
MEDIA_CANNOT_SEEK = MEDIA_ERROR_BASE + 109,
|
||||
MEDIA_CANNOT_CHANGE_RUN_MODE = MEDIA_ERROR_BASE + 110,
|
||||
MEDIA_APP_ALREADY_REGISTERED = MEDIA_ERROR_BASE + 111,
|
||||
MEDIA_APP_NOT_REGISTERED = MEDIA_ERROR_BASE + 112,
|
||||
MEDIA_CANNOT_RECLAIM_BUFFERS = MEDIA_ERROR_BASE + 113,
|
||||
MEDIA_BUFFERS_NOT_RECLAIMED = MEDIA_ERROR_BASE + 114,
|
||||
MEDIA_TIME_SOURCE_STOPPED = MEDIA_ERROR_BASE + 115,
|
||||
MEDIA_TIME_SOURCE_BUSY = MEDIA_ERROR_BASE + 116,
|
||||
MEDIA_BAD_SOURCE = MEDIA_ERROR_BASE + 117,
|
||||
MEDIA_BAD_DESTINATION = MEDIA_ERROR_BASE + 118,
|
||||
MEDIA_ALREADY_CONNECTED = MEDIA_ERROR_BASE + 119,
|
||||
MEDIA_NOT_CONNECTED = MEDIA_ERROR_BASE + 120,
|
||||
MEDIA_BAD_CLIP_FORMAT = MEDIA_ERROR_BASE + 121,
|
||||
MEDIA_ADDON_FAILED = MEDIA_ERROR_BASE + 122,
|
||||
MEDIA_ADDON_DISABLED = MEDIA_ERROR_BASE + 123,
|
||||
MEDIA_CHANGE_IN_PROGRESS = MEDIA_ERROR_BASE + 124,
|
||||
MEDIA_STALE_CHANGE_COUNT = MEDIA_ERROR_BASE + 125,
|
||||
MEDIA_ADDON_RESTRICTED = MEDIA_ERROR_BASE + 126,
|
||||
MEDIA_NO_HANDLER = MEDIA_ERROR_BASE + 127,
|
||||
MEDIA_DUPLICATE_FORMAT = MEDIA_ERROR_BASE + 128,
|
||||
MEDIA_REALTIME_DISABLED = MEDIA_ERROR_BASE + 129,
|
||||
MEDIA_REALTIME_UNAVAILABLE = MEDIA_ERROR_BASE + 130,
|
||||
|
||||
// Mail Kit Errors
|
||||
MAIL_NO_DAEMON = MAIL_ERROR_BASE + 0,
|
||||
MAIL_UNKNOWN_USER = MAIL_ERROR_BASE + 1,
|
||||
MAIL_WRONG_PASSWORD = MAIL_ERROR_BASE + 2,
|
||||
MAIL_UNKNOWN_HOST = MAIL_ERROR_BASE + 3,
|
||||
MAIL_ACCESS_ERROR = MAIL_ERROR_BASE + 4,
|
||||
MAIL_UNKNOWN_FIELD = MAIL_ERROR_BASE + 5,
|
||||
MAIL_NO_RECIPIENT = MAIL_ERROR_BASE + 6,
|
||||
MAIL_INVALID_MAIL = MAIL_ERROR_BASE + 7,
|
||||
|
||||
// Printing Errors
|
||||
NO_PRINT_SERVER = PRINT_ERROR_BASE + 0,
|
||||
|
||||
// Device Kit Errors
|
||||
DEV_INVALID_IOCTL = DEVICE_ERROR_BASE + 0,
|
||||
DEV_NO_MEMORY = DEVICE_ERROR_BASE + 1,
|
||||
DEV_BAD_DRIVE_NUM = DEVICE_ERROR_BASE + 2,
|
||||
DEV_NO_MEDIA = DEVICE_ERROR_BASE + 3,
|
||||
DEV_UNREADABLE = DEVICE_ERROR_BASE + 4,
|
||||
DEV_FORMAT_ERROR = DEVICE_ERROR_BASE + 5,
|
||||
DEV_TIMEOUT = DEVICE_ERROR_BASE + 6,
|
||||
DEV_RECALIBRATE_ERROR = DEVICE_ERROR_BASE + 7,
|
||||
DEV_SEEK_ERROR = DEVICE_ERROR_BASE + 8,
|
||||
DEV_ID_ERROR = DEVICE_ERROR_BASE + 9,
|
||||
DEV_READ_ERROR = DEVICE_ERROR_BASE + 10,
|
||||
DEV_WRITE_ERROR = DEVICE_ERROR_BASE + 11,
|
||||
DEV_NOT_READY = DEVICE_ERROR_BASE + 12,
|
||||
DEV_MEDIA_CHANGED = DEVICE_ERROR_BASE + 13,
|
||||
DEV_MEDIA_CHANGE_REQUESTED = DEVICE_ERROR_BASE + 14,
|
||||
DEV_RESOURCE_CONFLICT = DEVICE_ERROR_BASE + 15,
|
||||
DEV_CONFIGURATION_ERROR = DEVICE_ERROR_BASE + 16,
|
||||
DEV_DISABLED_BY_USER = DEVICE_ERROR_BASE + 17,
|
||||
DEV_DOOR_OPEN = DEVICE_ERROR_BASE + 18,
|
||||
DEV_INVALID_PIPE = DEVICE_ERROR_BASE + 19,
|
||||
DEV_CRC_ERROR = DEVICE_ERROR_BASE + 20,
|
||||
DEV_STALLED = DEVICE_ERROR_BASE + 21,
|
||||
DEV_BAD_PID = DEVICE_ERROR_BASE + 22,
|
||||
DEV_UNEXPECTED_PID = DEVICE_ERROR_BASE + 23,
|
||||
DEV_DATA_OVERRUN = DEVICE_ERROR_BASE + 24,
|
||||
DEV_DATA_UNDERRUN = DEVICE_ERROR_BASE + 25,
|
||||
DEV_FIFO_OVERRUN = DEVICE_ERROR_BASE + 26,
|
||||
DEV_FIFO_UNDERRUN = DEVICE_ERROR_BASE + 27,
|
||||
DEV_PENDING = DEVICE_ERROR_BASE + 28,
|
||||
DEV_MULTIPLE_ERRORS = DEVICE_ERROR_BASE + 29,
|
||||
DEV_TOO_LATE = DEVICE_ERROR_BASE + 30,
|
||||
|
||||
// Translation Kit Errors
|
||||
TRANSLATION_BASE_ERROR = TRANSLATION_ERROR_BASE + 0,
|
||||
NO_TRANSLATOR = TRANSLATION_ERROR_BASE + 1,
|
||||
ILLEGAL_DATA = TRANSLATION_ERROR_BASE + 2,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libroot {
|
||||
_to_positive_error :: proc(error: i32) -> i32 ---
|
||||
_to_negative_error :: proc(error: i32) -> i32 ---
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
#+build haiku
|
||||
package sys_haiku
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
foreign import libroot "system:c"
|
||||
|
||||
directory_which :: enum i32 {
|
||||
// Per volume directories
|
||||
DESKTOP_DIRECTORY = 0,
|
||||
TRASH_DIRECTORY,
|
||||
|
||||
// System directories
|
||||
SYSTEM_DIRECTORY = 1000,
|
||||
SYSTEM_ADDONS_DIRECTORY = 1002,
|
||||
SYSTEM_BOOT_DIRECTORY,
|
||||
SYSTEM_FONTS_DIRECTORY,
|
||||
SYSTEM_LIB_DIRECTORY,
|
||||
SYSTEM_SERVERS_DIRECTORY,
|
||||
SYSTEM_APPS_DIRECTORY,
|
||||
SYSTEM_BIN_DIRECTORY,
|
||||
SYSTEM_DOCUMENTATION_DIRECTORY = 1010,
|
||||
SYSTEM_PREFERENCES_DIRECTORY,
|
||||
SYSTEM_TRANSLATORS_DIRECTORY,
|
||||
SYSTEM_MEDIA_NODES_DIRECTORY,
|
||||
SYSTEM_SOUNDS_DIRECTORY,
|
||||
SYSTEM_DATA_DIRECTORY,
|
||||
SYSTEM_DEVELOP_DIRECTORY,
|
||||
SYSTEM_PACKAGES_DIRECTORY,
|
||||
SYSTEM_HEADERS_DIRECTORY,
|
||||
SYSTEM_ETC_DIRECTORY = 2008,
|
||||
SYSTEM_SETTINGS_DIRECTORY = 2010,
|
||||
SYSTEM_LOG_DIRECTORY = 2012,
|
||||
SYSTEM_SPOOL_DIRECTORY,
|
||||
SYSTEM_TEMP_DIRECTORY,
|
||||
SYSTEM_VAR_DIRECTORY,
|
||||
SYSTEM_CACHE_DIRECTORY = 2020,
|
||||
SYSTEM_NONPACKAGED_DIRECTORY = 2023,
|
||||
SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
|
||||
SYSTEM_NONPACKAGED_TRANSLATORS_DIRECTORY,
|
||||
SYSTEM_NONPACKAGED_MEDIA_NODES_DIRECTORY,
|
||||
SYSTEM_NONPACKAGED_BIN_DIRECTORY,
|
||||
SYSTEM_NONPACKAGED_DATA_DIRECTORY,
|
||||
SYSTEM_NONPACKAGED_FONTS_DIRECTORY,
|
||||
SYSTEM_NONPACKAGED_SOUNDS_DIRECTORY,
|
||||
SYSTEM_NONPACKAGED_DOCUMENTATION_DIRECTORY,
|
||||
SYSTEM_NONPACKAGED_LIB_DIRECTORY,
|
||||
SYSTEM_NONPACKAGED_HEADERS_DIRECTORY,
|
||||
SYSTEM_NONPACKAGED_DEVELOP_DIRECTORY,
|
||||
|
||||
// User directories. These are interpreted in the context of the user making the find_directory call.
|
||||
USER_DIRECTORY = 3000,
|
||||
USER_CONFIG_DIRECTORY,
|
||||
USER_ADDONS_DIRECTORY,
|
||||
USER_BOOT_DIRECTORY,
|
||||
USER_FONTS_DIRECTORY,
|
||||
USER_LIB_DIRECTORY,
|
||||
USER_SETTINGS_DIRECTORY,
|
||||
USER_DESKBAR_DIRECTORY,
|
||||
USER_PRINTERS_DIRECTORY,
|
||||
USER_TRANSLATORS_DIRECTORY,
|
||||
USER_MEDIA_NODES_DIRECTORY,
|
||||
USER_SOUNDS_DIRECTORY,
|
||||
USER_DATA_DIRECTORY,
|
||||
USER_CACHE_DIRECTORY,
|
||||
USER_PACKAGES_DIRECTORY,
|
||||
USER_HEADERS_DIRECTORY,
|
||||
USER_NONPACKAGED_DIRECTORY,
|
||||
USER_NONPACKAGED_ADDONS_DIRECTORY,
|
||||
USER_NONPACKAGED_TRANSLATORS_DIRECTORY,
|
||||
USER_NONPACKAGED_MEDIA_NODES_DIRECTORY,
|
||||
USER_NONPACKAGED_BIN_DIRECTORY,
|
||||
USER_NONPACKAGED_DATA_DIRECTORY,
|
||||
USER_NONPACKAGED_FONTS_DIRECTORY,
|
||||
USER_NONPACKAGED_SOUNDS_DIRECTORY,
|
||||
USER_NONPACKAGED_DOCUMENTATION_DIRECTORY,
|
||||
USER_NONPACKAGED_LIB_DIRECTORY,
|
||||
USER_NONPACKAGED_HEADERS_DIRECTORY,
|
||||
USER_NONPACKAGED_DEVELOP_DIRECTORY,
|
||||
USER_DEVELOP_DIRECTORY,
|
||||
USER_DOCUMENTATION_DIRECTORY,
|
||||
USER_SERVERS_DIRECTORY,
|
||||
USER_APPS_DIRECTORY,
|
||||
USER_BIN_DIRECTORY,
|
||||
USER_PREFERENCES_DIRECTORY,
|
||||
USER_ETC_DIRECTORY,
|
||||
USER_LOG_DIRECTORY,
|
||||
USER_SPOOL_DIRECTORY,
|
||||
USER_VAR_DIRECTORY,
|
||||
|
||||
// Global directories
|
||||
APPS_DIRECTORY = 4000,
|
||||
PREFERENCES_DIRECTORY,
|
||||
UTILITIES_DIRECTORY,
|
||||
PACKAGE_LINKS_DIRECTORY,
|
||||
|
||||
// Obsolete: Legacy BeOS definition to be phased out
|
||||
BEOS_DIRECTORY = 1000,
|
||||
BEOS_SYSTEM_DIRECTORY,
|
||||
BEOS_ADDONS_DIRECTORY,
|
||||
BEOS_BOOT_DIRECTORY,
|
||||
BEOS_FONTS_DIRECTORY,
|
||||
BEOS_LIB_DIRECTORY,
|
||||
BEOS_SERVERS_DIRECTORY,
|
||||
BEOS_APPS_DIRECTORY,
|
||||
BEOS_BIN_DIRECTORY,
|
||||
BEOS_ETC_DIRECTORY,
|
||||
BEOS_DOCUMENTATION_DIRECTORY,
|
||||
BEOS_PREFERENCES_DIRECTORY,
|
||||
BEOS_TRANSLATORS_DIRECTORY,
|
||||
BEOS_MEDIA_NODES_DIRECTORY,
|
||||
BEOS_SOUNDS_DIRECTORY,
|
||||
}
|
||||
|
||||
find_path_flag :: enum u32 {
|
||||
CREATE_DIRECTORY = intrinsics.constant_log2(0x0001),
|
||||
CREATE_PARENT_DIRECTORY = intrinsics.constant_log2(0x0002),
|
||||
EXISTING_ONLY = intrinsics.constant_log2(0x0004),
|
||||
|
||||
// find_paths() only
|
||||
SYSTEM_ONLY = intrinsics.constant_log2(0x0010),
|
||||
USER_ONLY = intrinsics.constant_log2(0x0020),
|
||||
}
|
||||
find_path_flags :: distinct bit_set[find_path_flag; u32]
|
||||
|
||||
path_base_directory :: enum i32 {
|
||||
INSTALLATION_LOCATION_DIRECTORY,
|
||||
ADD_ONS_DIRECTORY,
|
||||
APPS_DIRECTORY,
|
||||
BIN_DIRECTORY,
|
||||
BOOT_DIRECTORY,
|
||||
CACHE_DIRECTORY,
|
||||
DATA_DIRECTORY,
|
||||
DEVELOP_DIRECTORY,
|
||||
DEVELOP_LIB_DIRECTORY,
|
||||
DOCUMENTATION_DIRECTORY,
|
||||
ETC_DIRECTORY,
|
||||
FONTS_DIRECTORY,
|
||||
HEADERS_DIRECTORY,
|
||||
LIB_DIRECTORY,
|
||||
LOG_DIRECTORY,
|
||||
MEDIA_NODES_DIRECTORY,
|
||||
PACKAGES_DIRECTORY,
|
||||
PREFERENCES_DIRECTORY,
|
||||
SERVERS_DIRECTORY,
|
||||
SETTINGS_DIRECTORY,
|
||||
SOUNDS_DIRECTORY,
|
||||
SPOOL_DIRECTORY,
|
||||
TRANSLATORS_DIRECTORY,
|
||||
VAR_DIRECTORY,
|
||||
|
||||
// find_path() only
|
||||
IMAGE_PATH = 1000,
|
||||
PACKAGE_PATH,
|
||||
}
|
||||
|
||||
// value that can be used instead of a pointer to a symbol in the program image
|
||||
APP_IMAGE_SYMBOL :: rawptr(addr_t(0))
|
||||
// pointer to a symbol in the callers image (same as B_CURRENT_IMAGE_SYMBOL)
|
||||
current_image_symbol :: proc "contextless" () -> rawptr { return rawptr(current_image_symbol) }
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libroot {
|
||||
find_directory :: proc(which: directory_which, volume: dev_t, createIt: bool, pathString: [^]byte, length: i32) -> status_t ---
|
||||
find_path :: proc(codePointer: rawptr, baseDirectory: path_base_directory, subPath: cstring, pathBuffer: [^]byte, bufferSize: uint) -> status_t ---
|
||||
find_path_etc :: proc(codePointer: rawptr, dependency: cstring, architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, pathBuffer: [^]byte, bufferSize: uint) -> status_t ---
|
||||
find_path_for_path :: proc(path: cstring, baseDirectory: path_base_directory, subPath: cstring, pathBuffer: [^]byte, bufferSize: uint) -> status_t ---
|
||||
find_path_for_path_etc :: proc(path: cstring, dependency: cstring, architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, pathBuffer: [^]byte, bufferSize: uint) -> status_t ---
|
||||
find_paths :: proc(baseDirectory: path_base_directory, subPath: cstring, _paths: ^[^][^]byte, _pathCount: ^uint) -> status_t ---
|
||||
find_paths_etc :: proc(architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, _paths: ^[^][^]byte, _pathCount: ^uint) -> status_t ---
|
||||
}
|
||||
@@ -1,498 +0,0 @@
|
||||
#+build haiku
|
||||
package sys_haiku
|
||||
|
||||
import "base:intrinsics"
|
||||
import "core:sys/posix"
|
||||
|
||||
foreign import libroot "system:c"
|
||||
|
||||
PATH_MAX :: 1024
|
||||
NAME_MAX :: 256
|
||||
MAXPATHLEN :: PATH_MAX
|
||||
|
||||
FILE_NAME_LENGTH :: NAME_MAX
|
||||
PATH_NAME_LENGTH :: MAXPATHLEN
|
||||
OS_NAME_LENGTH :: 32
|
||||
|
||||
// Areas
|
||||
|
||||
area_info :: struct {
|
||||
area: area_id,
|
||||
name: [OS_NAME_LENGTH]byte,
|
||||
size: uint,
|
||||
lock: u32,
|
||||
protection: u32,
|
||||
team: team_id,
|
||||
ram_size: u32,
|
||||
copy_count: u32,
|
||||
in_count: u32,
|
||||
out_count: u32,
|
||||
address: rawptr,
|
||||
}
|
||||
|
||||
area_locking :: enum u32 {
|
||||
NO_LOCK = 0,
|
||||
LAZY_LOCK = 1,
|
||||
FULL_LOCK = 2,
|
||||
CONTIGUOUS = 3,
|
||||
LOMEM = 4, // CONTIGUOUS, < 16 MB physical address
|
||||
_32_BIT_FULL_LOCK = 5, // FULL_LOCK, < 4 GB physical addresses
|
||||
_32_BIT_CONTIGUOUS = 6, // CONTIGUOUS, < 4 GB physical address
|
||||
}
|
||||
|
||||
// for create_area() and clone_area()
|
||||
address_spec :: enum u32 {
|
||||
ANY_ADDRESS = 0,
|
||||
EXACT_ADDRESS = 1,
|
||||
BASE_ADDRESS = 2,
|
||||
CLONE_ADDRESS = 3,
|
||||
ANY_KERNEL_ADDRESS = 4,
|
||||
// ANY_KERNEL_BLOCK_ADDRESS = 5,
|
||||
RANDOMIZED_ANY_ADDRESS = 6,
|
||||
RANDOMIZED_BASE_ADDRESS = 7,
|
||||
}
|
||||
|
||||
area_protection_flag :: enum u32 {
|
||||
READ_AREA = 0,
|
||||
WRITE_AREA = 1,
|
||||
EXECUTE_AREA = 2,
|
||||
// "stack" protection is not available on most platforms - it's used
|
||||
// to only commit memory as needed, and have guard pages at the
|
||||
// bottom of the stack.
|
||||
STACK_AREA = 3,
|
||||
CLONEABLE_AREA = 8,
|
||||
}
|
||||
area_protection_flags :: distinct bit_set[area_protection_flag; u32]
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libroot {
|
||||
create_area :: proc(name: cstring, startAddress: ^rawptr, addressSpec: address_spec, size: uint, lock: area_locking, protection: area_protection_flags) -> area_id ---
|
||||
clone_area :: proc(name: cstring, destAddress: ^rawptr, addressSpec: address_spec, protection: area_protection_flags, source: area_id) -> area_id ---
|
||||
find_area :: proc(name: cstring) -> area_id ---
|
||||
area_for :: proc(address: rawptr) -> area_id ---
|
||||
delete_area :: proc(id: area_id) -> status_t ---
|
||||
resize_area :: proc(id: area_id, newSize: uint) -> status_t ---
|
||||
set_area_protection :: proc(id: area_id, newProtection: area_protection_flags) -> status_t ---
|
||||
_get_area_info :: proc(id: area_id, areaInfo: ^area_info, size: uint) -> status_t ---
|
||||
_get_next_area_info :: proc(team: team_id, cookie: ^int, areaInfo: ^area_info, size: uint) -> status_t ---
|
||||
}
|
||||
|
||||
// Ports
|
||||
|
||||
port_info :: struct {
|
||||
port: port_id,
|
||||
team: team_id,
|
||||
name: [OS_NAME_LENGTH]byte,
|
||||
capacity: i32, // queue depth
|
||||
queue_count: i32, // # msgs waiting to be read
|
||||
total_count: i32, // total # msgs read so far
|
||||
}
|
||||
|
||||
port_flag :: enum u32 {
|
||||
USE_USER_MEMCPY = intrinsics.constant_log2(0x80000000),
|
||||
// read the message, but don't remove it; kernel-only; memory must be locked
|
||||
PEEK_PORT_MESSAGE = intrinsics.constant_log2(0x100),
|
||||
}
|
||||
port_flags :: distinct bit_set[port_flag; u32]
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libroot {
|
||||
create_port :: proc(capacity: i32, name: cstring) -> port_id ---
|
||||
find_port :: proc(name: cstring) -> port_id ---
|
||||
read_port :: proc(port: port_id, code: ^i32, buffer: rawptr, bufferSize: uint) -> int ---
|
||||
read_port_etc :: proc(port: port_id, code: ^i32, buffer: rawptr, bufferSize: uint, flags: port_flags, timeout: bigtime_t) -> int ---
|
||||
write_port :: proc(port: port_id, code: i32, buffer: rawptr, bufferSize: uint) -> status_t ---
|
||||
write_port_etc :: proc(port: port_id, code: i32, buffer: rawptr, bufferSize: uint, flags: port_flags, timeout: bigtime_t) -> status_t ---
|
||||
close_port :: proc(port: port_id) -> status_t ---
|
||||
delete_port :: proc(port: port_id) -> status_t ---
|
||||
port_buffer_size :: proc(port: port_id) -> int ---
|
||||
port_buffer_size_etc :: proc(port: port_id, flags: port_flags, timeout: bigtime_t) -> int ---
|
||||
port_count :: proc(port: port_id) -> int ---
|
||||
set_port_owner :: proc(port: port_id, team: team_id) -> status_t ---
|
||||
_get_port_info :: proc(port: port_id, portInfo: ^port_info, portInfoSize: uint) -> status_t ---
|
||||
_get_next_port_info :: proc(team: team_id, cookie: ^i32, portInfo: ^port_info, portInfoSize: uint) -> status_t ---
|
||||
}
|
||||
|
||||
// Semaphores
|
||||
|
||||
sem_info :: struct {
|
||||
sem: sem_id,
|
||||
team: team_id,
|
||||
name: [OS_NAME_LENGTH]byte,
|
||||
count: i32,
|
||||
latest_holder: thread_id,
|
||||
}
|
||||
|
||||
semaphore_flag :: enum u32 {
|
||||
CAN_INTERRUPT = intrinsics.constant_log2(0x01), // acquisition of the semaphore can be interrupted (system use only)
|
||||
CHECK_PERMISSION = intrinsics.constant_log2(0x04), // ownership will be checked (system use only)
|
||||
KILL_CAN_INTERRUPT = intrinsics.constant_log2(0x20), // acquisition of the semaphore can be interrupted by SIGKILL[THR], even if not CAN_INTERRUPT (system use only)
|
||||
|
||||
// release_sem_etc() only flags
|
||||
DO_NOT_RESCHEDULE = intrinsics.constant_log2(0x02), // thread is not rescheduled
|
||||
RELEASE_ALL = intrinsics.constant_log2(0x08), // all waiting threads will be woken up, count will be zeroed
|
||||
RELEASE_IF_WAITING_ONLY = intrinsics.constant_log2(0x10), // release count only if there are any threads waiting
|
||||
}
|
||||
semaphore_flags :: distinct bit_set[semaphore_flag; u32]
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libroot {
|
||||
create_sem :: proc(count: i32, name: cstring) -> sem_id ---
|
||||
delete_sem :: proc(id: sem_id) -> status_t ---
|
||||
acquire_sem :: proc(id: sem_id) -> status_t ---
|
||||
acquire_sem_etc :: proc(id: sem_id, count: i32, flags: semaphore_flags, timeout: bigtime_t) -> status_t ---
|
||||
release_sem :: proc(id: sem_id) -> status_t ---
|
||||
release_sem_etc :: proc(id: sem_id, count: i32, flags: semaphore_flags) -> status_t ---
|
||||
switch_sem :: proc(semToBeReleased: sem_id) -> status_t ---
|
||||
switch_sem_etc :: proc(semToBeReleased: sem_id, id: sem_id, count: i32, flags: semaphore_flags, timeout: bigtime_t) -> status_t ---
|
||||
get_sem_count :: proc(id: sem_id, threadCount: ^i32) -> status_t ---
|
||||
set_sem_owner :: proc(id: sem_id, team: team_id) -> status_t ---
|
||||
_get_sem_info :: proc(id: sem_id, info: ^sem_info, infoSize: uint) -> status_t ---
|
||||
_get_next_sem_info :: proc(team: team_id, cookie: ^i32, info: ^sem_info, infoSize: uint) -> status_t ---
|
||||
}
|
||||
|
||||
// Teams
|
||||
|
||||
team_info :: struct {
|
||||
team: team_id,
|
||||
thread_count: i32,
|
||||
image_count: i32,
|
||||
area_count: i32,
|
||||
debugger_nub_thread: thread_id,
|
||||
debugger_nub_port: port_id,
|
||||
argc: i32,
|
||||
args: [64]byte,
|
||||
uid: uid_t,
|
||||
gid: gid_t,
|
||||
|
||||
// Haiku R1 extensions
|
||||
real_uid: uid_t,
|
||||
real_gid: gid_t,
|
||||
group_id: pid_t,
|
||||
session_id: pid_t,
|
||||
parent: team_id,
|
||||
name: [OS_NAME_LENGTH]byte,
|
||||
start_time: bigtime_t,
|
||||
}
|
||||
|
||||
CURRENT_TEAM :: 0
|
||||
SYSTEM_TEAM :: 1
|
||||
|
||||
team_usage_info :: struct {
|
||||
user_time: bigtime_t,
|
||||
kernel_time: bigtime_t,
|
||||
}
|
||||
|
||||
team_usage_who :: enum i32 {
|
||||
// compatible to sys/resource.h RUSAGE_SELF and RUSAGE_CHILDREN
|
||||
SELF = 0,
|
||||
CHILDREN = -1,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libroot {
|
||||
// see also: send_signal()
|
||||
kill_team :: proc(team: team_id) -> status_t ---
|
||||
_get_team_info :: proc(id: team_id, info: ^team_info, size: uint) -> status_t ---
|
||||
_get_next_team_info :: proc(cookie: ^i32, info: ^team_info, size: uint) -> status_t ---
|
||||
_get_team_usage_info :: proc(id: team_id, who: team_usage_who, info: ^team_usage_info, size: uint) -> status_t ---
|
||||
}
|
||||
|
||||
// Threads
|
||||
|
||||
thread_state :: enum i32 {
|
||||
RUNNING = 1,
|
||||
READY,
|
||||
RECEIVING,
|
||||
ASLEEP,
|
||||
SUSPENDED,
|
||||
WAITING,
|
||||
}
|
||||
|
||||
thread_info :: struct {
|
||||
thread: thread_id,
|
||||
team: team_id,
|
||||
name: [OS_NAME_LENGTH]byte,
|
||||
state: thread_state,
|
||||
priority: thread_priority,
|
||||
sem: sem_id,
|
||||
user_time: bigtime_t,
|
||||
kernel_time: bigtime_t,
|
||||
stack_base: rawptr,
|
||||
stack_end: rawptr,
|
||||
}
|
||||
|
||||
thread_priority :: enum i32 {
|
||||
IDLE_PRIORITY = 0,
|
||||
LOWEST_ACTIVE_PRIORITY = 1,
|
||||
LOW_PRIORITY = 5,
|
||||
NORMAL_PRIORITY = 10,
|
||||
DISPLAY_PRIORITY = 15,
|
||||
URGENT_DISPLAY_PRIORITY = 20,
|
||||
REAL_TIME_DISPLAY_PRIORITY = 100,
|
||||
URGENT_PRIORITY = 110,
|
||||
REAL_TIME_PRIORITY = 120,
|
||||
}
|
||||
|
||||
FIRST_REAL_TIME_PRIORITY :: thread_priority.REAL_TIME_PRIORITY
|
||||
|
||||
// time base for snooze_*(), compatible with the clockid_t constants defined in <time.h>
|
||||
SYSTEM_TIMEBASE :: 0
|
||||
|
||||
thread_func :: #type proc "c" (rawptr) -> status_t
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libroot {
|
||||
spawn_thread :: proc(thread_func, name: cstring, priority: thread_priority, data: rawptr) -> thread_id ---
|
||||
kill_thread :: proc(thread: thread_id) -> status_t ---
|
||||
resume_thread :: proc(thread: thread_id) -> status_t ---
|
||||
suspend_thread :: proc(thread: thread_id) -> status_t ---
|
||||
rename_thread :: proc(thread: thread_id, newName: cstring) -> status_t ---
|
||||
set_thread_priority :: proc(thread: thread_id, newPriority: thread_priority) -> status_t ---
|
||||
exit_thread :: proc(status: status_t) ---
|
||||
wait_for_thread :: proc(thread: thread_id, returnValue: ^status_t) -> status_t ---
|
||||
// FIXME: Find and define those flags.
|
||||
wait_for_thread_etc :: proc(id: thread_id, flags: u32, timeout: bigtime_t, _returnCode: ^status_t) -> status_t ---
|
||||
on_exit_thread :: proc(callback: proc "c" (rawptr), data: rawptr) -> status_t ---
|
||||
find_thread :: proc(name: cstring) -> thread_id ---
|
||||
send_data :: proc(thread: thread_id, code: i32, buffer: rawptr, bufferSize: uint) -> status_t ---
|
||||
receive_data :: proc(sender: ^thread_id, buffer: rawptr, bufferSize: uint) -> i32 ---
|
||||
has_data :: proc(thread: thread_id) -> bool ---
|
||||
snooze :: proc(amount: bigtime_t) -> status_t ---
|
||||
// FIXME: Find and define those flags.
|
||||
snooze_etc :: proc(amount: bigtime_t, timeBase: i32, flags: u32) -> status_t ---
|
||||
snooze_until :: proc(time: bigtime_t, timeBase: i32) -> status_t ---
|
||||
_get_thread_info :: proc(id: thread_id, info: ^thread_info, size: uint) -> status_t ---
|
||||
_get_next_thread_info :: proc(team: team_id, cookie: ^i32, info: ^thread_info, size: uint) -> status_t ---
|
||||
// bridge to the pthread API
|
||||
get_pthread_thread_id :: proc(thread: pthread_t) -> thread_id ---
|
||||
}
|
||||
|
||||
// Time
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libroot {
|
||||
real_time_clock :: proc() -> uint ---
|
||||
set_real_time_clock :: proc(secsSinceJan1st1970: uint) ---
|
||||
real_time_clock_usecs :: proc() -> bigtime_t ---
|
||||
// time since booting in microseconds
|
||||
system_time :: proc() -> bigtime_t ---
|
||||
// time since booting in nanoseconds
|
||||
system_time_nsecs :: proc() -> nanotime_t ---
|
||||
}
|
||||
|
||||
// Alarm
|
||||
|
||||
alarm_mode :: enum u32 {
|
||||
ONE_SHOT_ABSOLUTE_ALARM = 1,
|
||||
ONE_SHOT_RELATIVE_ALARM,
|
||||
PERIODIC_ALARM, // "when" specifies the period
|
||||
}
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libroot {
|
||||
set_alarm :: proc(_when: bigtime_t, mode: alarm_mode) -> bigtime_t ---
|
||||
}
|
||||
|
||||
// Debugger
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libroot {
|
||||
debugger :: proc(message: cstring) ---
|
||||
/*
|
||||
calling this function with a non-zero value will cause your thread
|
||||
to receive signals for any exceptional conditions that occur (i.e.
|
||||
you'll get SIGSEGV for data access exceptions, SIGFPE for floating
|
||||
point errors, SIGILL for illegal instructions, etc).
|
||||
|
||||
to re-enable the default debugger pass a zero.
|
||||
*/
|
||||
disable_debugger :: proc(state: i32) -> i32 ---
|
||||
}
|
||||
|
||||
// System information
|
||||
|
||||
cpu_info :: struct {
|
||||
active_time: bigtime_t,
|
||||
enabled: bool,
|
||||
current_frequency: u64,
|
||||
}
|
||||
|
||||
system_info :: struct {
|
||||
boot_time: bigtime_t, // time of boot (usecs since 1/1/1970)
|
||||
|
||||
cpu_count: u32, // number of cpus
|
||||
|
||||
max_pages: u64, // total # of accessible pages
|
||||
used_pages: u64, // # of accessible pages in use
|
||||
cached_pages: u64,
|
||||
block_cache_pages: u64,
|
||||
ignored_pages: u64, // # of ignored/inaccessible pages
|
||||
|
||||
needed_memory: u64,
|
||||
free_memory: u64,
|
||||
|
||||
max_swap_pages: u64,
|
||||
free_swap_pages: u64,
|
||||
|
||||
page_faults: u32, // # of page faults
|
||||
|
||||
max_sems: u32,
|
||||
used_sems: u32,
|
||||
|
||||
max_ports: u32,
|
||||
used_ports: u32,
|
||||
|
||||
max_threads: u32,
|
||||
used_threads: u32,
|
||||
|
||||
max_teams: u32,
|
||||
used_teams: u32,
|
||||
|
||||
kernel_name: [FILE_NAME_LENGTH]byte,
|
||||
kernel_build_date: [OS_NAME_LENGTH]byte,
|
||||
kernel_build_time: [OS_NAME_LENGTH]byte,
|
||||
|
||||
kernel_version: i64,
|
||||
abi: u32, // the system API
|
||||
}
|
||||
|
||||
topology_level_type :: enum i32 {
|
||||
UNKNOWN,
|
||||
ROOT,
|
||||
SMT,
|
||||
CORE,
|
||||
PACKAGE,
|
||||
}
|
||||
|
||||
cpu_platform :: enum i32 {
|
||||
UNKNOWN,
|
||||
x86,
|
||||
x86_64,
|
||||
PPC,
|
||||
PPC_64,
|
||||
M68K,
|
||||
ARM,
|
||||
ARM_64,
|
||||
ALPHA,
|
||||
MIPS,
|
||||
SH,
|
||||
SPARC,
|
||||
RISC_V,
|
||||
}
|
||||
|
||||
cpu_vendor :: enum i32 {
|
||||
UNKNOWN,
|
||||
AMD,
|
||||
CYRIX,
|
||||
IDT,
|
||||
INTEL,
|
||||
NATIONAL_SEMICONDUCTOR,
|
||||
RISE,
|
||||
TRANSMETA,
|
||||
VIA,
|
||||
IBM,
|
||||
MOTOROLA,
|
||||
NEC,
|
||||
HYGON,
|
||||
SUN,
|
||||
FUJITSU,
|
||||
}
|
||||
|
||||
cpu_topology_node_info :: struct {
|
||||
id: u32,
|
||||
type: topology_level_type,
|
||||
level: u32,
|
||||
|
||||
data: struct #raw_union {
|
||||
_root: struct {
|
||||
platform: cpu_platform,
|
||||
},
|
||||
_package: struct {
|
||||
vendor: cpu_vendor,
|
||||
cache_line_size: u32,
|
||||
},
|
||||
_core: struct {
|
||||
model: u32,
|
||||
default_frequency: u64,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
when ODIN_ARCH == .amd64 || ODIN_ARCH == .i386 {
|
||||
cpuid_info :: struct #raw_union {
|
||||
eax_0: struct {
|
||||
max_eax: u32,
|
||||
vendor_id: [12]byte,
|
||||
},
|
||||
|
||||
eax_1: struct {
|
||||
using _: bit_field u32 {
|
||||
stepping: u32 | 4,
|
||||
model: u32 | 4,
|
||||
family: u32 | 4,
|
||||
type: u32 | 2,
|
||||
reserved_0: u32 | 2,
|
||||
extended_model: u32 | 4,
|
||||
extended_family: u32 | 8,
|
||||
reserved_1: u32 | 4,
|
||||
},
|
||||
|
||||
using _: bit_field u32 {
|
||||
brand_index: u32 | 8,
|
||||
clflush: u32 | 8,
|
||||
logical_cpus: u32 | 8,
|
||||
apic_id: u32 | 8,
|
||||
},
|
||||
|
||||
features: u32,
|
||||
extended_features: u32,
|
||||
},
|
||||
|
||||
eax_2: struct {
|
||||
call_num: u8,
|
||||
cache_descriptors: [15]u8,
|
||||
},
|
||||
|
||||
eax_3: struct {
|
||||
reserved: [2]u32,
|
||||
serial_number_high: u32,
|
||||
serial_number_low: u32,
|
||||
},
|
||||
|
||||
as_chars: [16]byte,
|
||||
|
||||
regs: struct {
|
||||
eax: u32,
|
||||
ebx: u32,
|
||||
edx: u32,
|
||||
ecx: u32,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libroot {
|
||||
get_system_info :: proc(info: ^system_info) -> status_t ---
|
||||
_get_cpu_info_etc :: proc(firstCPU: u32, cpuCount: u32, info: ^cpu_info, size: uint) -> status_t ---
|
||||
get_cpu_topology_info :: proc(topologyInfos: [^]cpu_topology_node_info, topologyInfoCount: ^u32) -> status_t ---
|
||||
|
||||
when ODIN_ARCH == .amd64 || ODIN_ARCH == .i386 {
|
||||
get_cpuid :: proc(info: ^cpuid_info, eaxRegister: u32, cpuNum: u32) -> status_t ---
|
||||
}
|
||||
|
||||
is_computer_on :: proc() -> i32 ---
|
||||
is_computer_on_fire :: proc() -> f64 ---
|
||||
}
|
||||
|
||||
// POSIX signals
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libroot {
|
||||
/*
|
||||
Wait for queued signals.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigtimedwait.html ]]
|
||||
*/
|
||||
sigtimedwait :: proc(set: ^posix.sigset_t, info: ^posix.siginfo_t, timeout: ^posix.timespec) -> posix.result ---
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
#+build haiku
|
||||
package sys_haiku
|
||||
|
||||
status_t :: Errno
|
||||
bigtime_t :: i64
|
||||
nanotime_t :: i64
|
||||
type_code :: u32
|
||||
perform_code :: u32
|
||||
|
||||
phys_addr_t :: uintptr
|
||||
phys_size_t :: phys_addr_t
|
||||
generic_addr_t :: uintptr
|
||||
generic_size_t :: generic_addr_t
|
||||
|
||||
area_id :: i32
|
||||
port_id :: i32
|
||||
sem_id :: i32
|
||||
team_id :: i32
|
||||
thread_id :: i32
|
||||
|
||||
blkcnt_t :: i64
|
||||
blksize_t :: i32
|
||||
fsblkcnt_t :: i64
|
||||
fsfilcnt_t :: i64
|
||||
off_t :: i64
|
||||
ino_t :: i64
|
||||
cnt_t :: i32
|
||||
dev_t :: i32
|
||||
pid_t :: i32
|
||||
id_t :: i32
|
||||
|
||||
uid_t :: u32
|
||||
gid_t :: u32
|
||||
mode_t :: u32
|
||||
umode_t :: u32
|
||||
nlink_t :: i32
|
||||
|
||||
caddr_t :: [^]byte
|
||||
|
||||
addr_t :: phys_addr_t
|
||||
key_t :: i32
|
||||
|
||||
clockid_t :: i32
|
||||
|
||||
time_t :: int
|
||||
timespec :: struct {
|
||||
tv_sec: time_t,
|
||||
tv_nsec: int,
|
||||
}
|
||||
|
||||
sig_atomic_t :: i32
|
||||
sigset_t :: u64
|
||||
|
||||
image_id :: i32
|
||||
|
||||
pthread_t :: rawptr
|
||||
@@ -1,4 +1,4 @@
|
||||
#+build openbsd, freebsd, netbsd, haiku
|
||||
#+build openbsd, freebsd, netbsd
|
||||
package sysinfo
|
||||
|
||||
@(private)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#+build haiku
|
||||
package sysinfo
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
@(private)
|
||||
_ram_stats :: proc "contextless" () -> (total_ram, free_ram, total_swap, free_swap: i64, ok: bool) {
|
||||
return
|
||||
}
|
||||
|
||||
@(private)
|
||||
_os_version :: proc(allocator: runtime.Allocator, loc := #caller_location) -> (res: OS_Version, ok: bool) {
|
||||
return {}, false
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#+private
|
||||
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||
package terminal
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#+private
|
||||
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
|
||||
#+build linux, darwin, freebsd, openbsd, netbsd
|
||||
package testing
|
||||
|
||||
/*
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#+build !freebsd
|
||||
#+build !openbsd
|
||||
#+build !netbsd
|
||||
#+build !haiku
|
||||
package testing
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
|
||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||
#+private
|
||||
package testing
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#+build !wasi
|
||||
#+build !windows
|
||||
#+build !orca
|
||||
#+build !haiku
|
||||
package time
|
||||
|
||||
_IS_SUPPORTED :: false
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#+private
|
||||
#+build darwin, freebsd, openbsd, netbsd, haiku
|
||||
#+build darwin, freebsd, openbsd, netbsd
|
||||
package time
|
||||
|
||||
import "core:sys/posix"
|
||||
|
||||
Reference in New Issue
Block a user