Merge pull request #4603 from avanspector/master

Haiku: fix build and add initial `core:sys/posix` support
This commit is contained in:
Laytan
2025-01-11 00:06:29 +01:00
committed by GitHub
61 changed files with 1579 additions and 415 deletions

View File

@@ -115,7 +115,7 @@ OpenBSD)
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
;;
Haiku)
CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags) -I/system/develop/headers/private/shared -I/system/develop/headers/private/kernel"
CXXFLAGS="$CXXFLAGS -D_GNU_SOURCE $($LLVM_CONFIG --cxxflags --ldflags) -I/system/develop/headers/private/shared -I/system/develop/headers/private/kernel"
LDFLAGS="$LDFLAGS -liconv"
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
;;

View File

@@ -88,14 +88,15 @@ when ODIN_OS == .Haiku {
_get_errno :: proc() -> ^int ---
}
@(private="file")
B_GENERAL_ERROR_BASE :: min(i32)
@(private="file")
B_POSIX_ERROR_BASE :: B_GENERAL_ERROR_BASE + 0x7000
_HAIKU_USE_POSITIVE_POSIX_ERRORS :: #config(HAIKU_USE_POSITIVE_POSIX_ERRORS, false)
_POSIX_ERROR_FACTOR :: -1 when _HAIKU_USE_POSITIVE_POSIX_ERRORS else 1
EDOM :: B_POSIX_ERROR_BASE + 16
EILSEQ :: B_POSIX_ERROR_BASE + 38
ERANGE :: B_POSIX_ERROR_BASE + 17
@(private="file") _GENERAL_ERROR_BASE :: min(int)
@(private="file") _POSIX_ERROR_BASE :: _GENERAL_ERROR_BASE + 0x7000
EDOM :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 16)
EILSEQ :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 38)
ERANGE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 17)
}
when ODIN_OS == .JS {

View File

@@ -110,7 +110,7 @@ when ODIN_OS == .Windows {
}
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Windows {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku || ODIN_OS == .Windows {
LC_ALL :: 0
LC_COLLATE :: 1

View File

@@ -42,6 +42,21 @@ when ODIN_OS == .Linux {
}
}
when ODIN_OS == .Haiku {
RAND_MAX :: 0x7fffffff
// GLIBC and MUSL only
@(private="file")
@(default_calling_convention="c")
foreign libc {
__ctype_get_mb_cur_max :: proc() -> ushort ---
}
MB_CUR_MAX :: #force_inline proc() -> size_t {
return size_t(__ctype_get_mb_cur_max())
}
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD {
RAND_MAX :: 0x7fffffff

View File

@@ -95,7 +95,7 @@ when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Darwin || ODIN_OS =
time_t :: distinct i64
when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD {
when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .Haiku {
clock_t :: distinct int32_t
} else {
clock_t :: distinct long

View File

@@ -1,4 +1,4 @@
#+build darwin, linux, netbsd, freebsd, openbsd
#+build darwin, linux, netbsd, freebsd, openbsd, haiku
package os
import "core:strings"

View File

@@ -1,11 +1,13 @@
package os
foreign import libc "system:c"
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
@@ -14,7 +16,7 @@ _Platform_Error :: haiku.Errno
MAX_PATH :: haiku.PATH_MAX
ENOSYS :: _Platform_Error(i32(haiku.Errno.POSIX_ERROR_BASE) + 9)
ENOSYS :: _Platform_Error(haiku.Errno.ENOSYS)
INVALID_HANDLE :: ~Handle(0)
@@ -117,14 +119,13 @@ 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 libc {
@(link_name="_errorp") __error :: proc() -> ^c.int ---
foreign lib {
@(link_name="fork") _unix_fork :: proc() -> pid_t ---
@(link_name="getthrid") _unix_getthrid :: proc() -> int ---
@(link_name="open") _unix_open :: proc(path: cstring, flags: c.int, #c_vararg mode: ..u16) -> Handle ---
@(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 ---
@@ -150,6 +151,7 @@ foreign libc {
@(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 ---
@@ -157,7 +159,7 @@ foreign libc {
@(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: rawptr) -> rawptr ---
@(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: [^]byte = nil) -> cstring ---
@(link_name="exit") _unix_exit :: proc(status: c.int) -> ! ---
@@ -203,7 +205,7 @@ fork :: proc() -> (Pid, Error) {
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 := _unix_open(cstr, c.int(flags), u16(mode))
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()
}
@@ -444,7 +446,7 @@ absolute_path_from_relative :: proc(rel: string, allocator := context.allocator)
if path_ptr == nil {
return "", get_last_error()
}
defer _unix_free(path_ptr)
defer _unix_free(rawptr(path_ptr))
path_cstr := cstring(path_ptr)
return strings.clone(string(path_cstr), allocator)
@@ -488,3 +490,17 @@ 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
}

View File

@@ -53,7 +53,7 @@ File_Info :: struct {
@(private, require_results)
_make_time_from_unix_file_time :: proc(uft: Unix_File_Time) -> time.Time {
return time.Time{
_nsec = uft.nanoseconds + uft.seconds * 1_000_000_000,
_nsec = i64(uft.nanoseconds) + i64(uft.seconds) * 1_000_000_000,
}
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, freebsd, openbsd, netbsd
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
package filepath
import "base:runtime"

View File

@@ -1,14 +1,13 @@
#+private
package sync
import "core:c"
import "core:sys/haiku"
import "core:sys/unix"
import "core:sys/posix"
import "core:time"
@(private="file")
Wait_Node :: struct {
thread: unix.pthread_t,
thread: posix.pthread_t,
futex: ^Futex,
prev, next: ^Wait_Node,
}
@@ -58,7 +57,7 @@ _futex_wait :: proc "contextless" (f: ^Futex, expect: u32) -> (ok: bool) {
head := &waitq.list
waiter := Wait_Node{
thread = unix.pthread_self(),
thread = posix.pthread_self(),
futex = f,
prev = head,
next = head.next,
@@ -67,25 +66,24 @@ _futex_wait :: proc "contextless" (f: ^Futex, expect: u32) -> (ok: bool) {
waiter.prev.next = &waiter
waiter.next.prev = &waiter
old_mask, mask: haiku.sigset_t
haiku.sigemptyset(&mask)
haiku.sigaddset(&mask, haiku.SIGCONT)
unix.pthread_sigmask(haiku.SIG_BLOCK, &mask, &old_mask)
old_mask, mask: posix.sigset_t
posix.sigemptyset(&mask)
posix.sigaddset(&mask, .SIGCONT)
posix.pthread_sigmask(.BLOCK, &mask, &old_mask)
if u32(atomic_load_explicit(f, .Acquire)) == expect {
waitq_unlock(waitq)
defer waitq_lock(waitq)
sig: c.int
haiku.sigwait(&mask, &sig)
errno := haiku.errno()
ok = errno == .OK
sig: posix.Signal
errno := posix.sigwait(&mask, &sig)
ok = errno == nil
}
waiter.prev.next = waiter.next
waiter.next.prev = waiter.prev
_ = unix.pthread_sigmask(haiku.SIG_SETMASK, &old_mask, nil)
_ = posix.pthread_sigmask(.SETMASK, &old_mask, nil)
// FIXME: Add error handling!
return
@@ -101,7 +99,7 @@ _futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expect: u32, duration
head := &waitq.list
waiter := Wait_Node{
thread = unix.pthread_self(),
thread = posix.pthread_self(),
futex = f,
prev = head,
next = head.next,
@@ -110,29 +108,29 @@ _futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expect: u32, duration
waiter.prev.next = &waiter
waiter.next.prev = &waiter
old_mask, mask: haiku.sigset_t
haiku.sigemptyset(&mask)
haiku.sigaddset(&mask, haiku.SIGCONT)
unix.pthread_sigmask(haiku.SIG_BLOCK, &mask, &old_mask)
old_mask, mask: posix.sigset_t
posix.sigemptyset(&mask)
posix.sigaddset(&mask, .SIGCONT)
posix.pthread_sigmask(.BLOCK, &mask, &old_mask)
if u32(atomic_load_explicit(f, .Acquire)) == expect {
waitq_unlock(waitq)
defer waitq_lock(waitq)
info: haiku.siginfo_t
ts := unix.timespec{
tv_sec = i64(duration / 1e9),
info: posix.siginfo_t
ts := posix.timespec{
tv_sec = posix.time_t(i64(duration / 1e9)),
tv_nsec = i64(duration % 1e9),
}
haiku.sigtimedwait(&mask, &info, &ts)
errno := haiku.errno()
ok = errno == .EAGAIN || errno == .OK
errno := posix.errno()
ok = errno == .EAGAIN || errno == nil
}
waiter.prev.next = waiter.next
waiter.next.prev = waiter.prev
unix.pthread_sigmask(haiku.SIG_SETMASK, &old_mask, nil)
posix.pthread_sigmask(.SETMASK, &old_mask, nil)
// FIXME: Add error handling!
return
@@ -146,7 +144,7 @@ _futex_signal :: proc "contextless" (f: ^Futex) {
head := &waitq.list
for waiter := head.next; waiter != head; waiter = waiter.next {
if waiter.futex == f {
unix.pthread_kill(waiter.thread, haiku.SIGCONT)
posix.pthread_kill(waiter.thread, .SIGCONT)
break
}
}
@@ -160,7 +158,7 @@ _futex_broadcast :: proc "contextless" (f: ^Futex) {
head := &waitq.list
for waiter := head.next; waiter != head; waiter = waiter.next {
if waiter.futex == f {
unix.pthread_kill(waiter.thread, haiku.SIGCONT)
posix.pthread_kill(waiter.thread, .SIGCONT)
}
}
}

View File

@@ -1,26 +1,31 @@
#+build haiku
package sys_haiku
import "core:c"
import "core:sys/posix"
Errno :: enum c.int {
// Error baselines
GENERAL_ERROR_BASE = min(c.int),
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,
foreign import libroot "system:c"
// Developer-defined errors start at (ERRORS_END+1)
ERRORS_END = GENERAL_ERROR_BASE + 0xffff,
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,
@@ -107,31 +112,95 @@ Errno :: enum c.int {
PARTIAL_READ = STORAGE_ERROR_BASE + 16,
PARTIAL_WRITE = STORAGE_ERROR_BASE + 17,
// Some POSIX errors
E2BIG = POSIX_ERROR_BASE + 1,
EFBIG = POSIX_ERROR_BASE + 4,
ENODEV = POSIX_ERROR_BASE + 7,
ERANGE = POSIX_ERROR_BASE + 17,
EOVERFLOW = POSIX_ERROR_BASE + 41,
EOPNOTSUPP = POSIX_ERROR_BASE + 43,
ENOSYS = POSIX_ERROR_BASE + 9,
EAGAIN = WOULD_BLOCK,
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_NEG = E2BIG,
FILE_TOO_LARGE_NEG = EFBIG,
DEVICE_NOT_FOUND_NEG = ENODEV,
RESULT_NOT_REPRESENTABLE_NEG = ERANGE,
BUFFER_OVERFLOW_NEG = EOVERFLOW,
NOT_SUPPORTED_NEG = EOPNOTSUPP,
TOO_MANY_ARGS_POS = -E2BIG,
FILE_TOO_LARGE_POS = -EFBIG,
DEVICE_NOT_FOUND_POS = -ENODEV,
RESULT_NOT_REPRESENTABLE_POS = -ERANGE,
BUFFER_OVERFLOW_POS = -EOVERFLOW,
NOT_SUPPORTED_POS = -EOPNOTSUPP,
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,
@@ -226,14 +295,8 @@ Errno :: enum c.int {
ILLEGAL_DATA = TRANSLATION_ERROR_BASE + 2,
}
errno :: #force_inline proc "contextless" () -> Errno {
return Errno(_errnop()^)
}
foreign import libroot "system:c"
@(default_calling_convention="c")
foreign libroot {
_to_positive_error :: proc(error: c.int) -> c.int ---
_to_negative_error :: proc(error: c.int) -> c.int ---
_errnop :: proc() -> ^c.int ---
_to_positive_error :: proc(error: i32) -> i32 ---
_to_negative_error :: proc(error: i32) -> i32 ---
}

View File

@@ -1,9 +1,11 @@
#+build haiku
package sys_haiku
import "core:c"
import "base:intrinsics"
directory_which :: enum c.int {
foreign import libroot "system:c"
directory_which :: enum i32 {
// Per volume directories
DESKTOP_DIRECTORY = 0,
TRASH_DIRECTORY,
@@ -110,17 +112,18 @@ directory_which :: enum c.int {
BEOS_SOUNDS_DIRECTORY,
}
find_path_flags :: enum c.int {
CREATE_DIRECTORY = 0x0001,
CREATE_PARENT_DIRECTORY = 0x0002,
EXISTING_ONLY = 0x0004,
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 = 0x0010,
USER_ONLY = 0x0020,
// 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 c.int {
path_base_directory :: enum i32 {
INSTALLATION_LOCATION_DIRECTORY,
ADD_ONS_DIRECTORY,
APPS_DIRECTORY,
@@ -146,7 +149,7 @@ path_base_directory :: enum c.int {
TRANSLATORS_DIRECTORY,
VAR_DIRECTORY,
// find_path() only!
// find_path() only
IMAGE_PATH = 1000,
PACKAGE_PATH,
}
@@ -154,15 +157,15 @@ path_base_directory :: enum c.int {
// 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() -> rawptr { return rawptr(current_image_symbol) }
current_image_symbol :: proc "contextless" () -> rawptr { return rawptr(current_image_symbol) }
foreign import libroot "system:c"
@(default_calling_convention="c")
foreign libroot {
find_directory :: proc(which: directory_which, volume: dev_t, createIt: bool, pathString: [^]c.char, length: i32) -> status_t ---
find_path :: proc(codePointer: rawptr, baseDirectory: path_base_directory, subPath: cstring, pathBuffer: [^]c.char, bufferSize: c.size_t) -> status_t ---
find_path_etc :: proc(codePointer: rawptr, dependency: cstring, architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, pathBuffer: [^]c.char, bufferSize: c.size_t) -> status_t ---
find_path_for_path :: proc(path: cstring, baseDirectory: path_base_directory, subPath: cstring, pathBuffer: [^]c.char, bufferSize: c.size_t) -> 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: [^]c.char, bufferSize: c.size_t) -> status_t ---
find_paths :: proc(baseDirectory: path_base_directory, subPath: cstring, _paths: ^[^][^]c.char, _pathCount: ^c.size_t) -> status_t ---
find_paths_etc :: proc(architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, _paths: ^[^][^]c.char, _pathCount: ^c.size_t) -> status_t ---
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 ---
}

View File

@@ -1,8 +1,8 @@
#+build haiku
package sys_haiku
import "core:c"
import "core:sys/unix"
import "base:intrinsics"
import "core:sys/posix"
foreign import libroot "system:c"
@@ -18,8 +18,8 @@ OS_NAME_LENGTH :: 32
area_info :: struct {
area: area_id,
name: [OS_NAME_LENGTH]c.char,
size: c.size_t,
name: [OS_NAME_LENGTH]byte,
size: uint,
lock: u32,
protection: u32,
team: team_id,
@@ -31,11 +31,11 @@ area_info :: struct {
}
area_locking :: enum u32 {
NO_LOCK = 0,
LAZY_LOCK = 1,
FULL_LOCK = 2,
CONTIGUOUS = 3,
LOMEM = 4, // CONTIGUOUS, < 16 MB physical address
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
}
@@ -52,27 +52,29 @@ address_spec :: enum u32 {
RANDOMIZED_BASE_ADDRESS = 7,
}
area_protection_flags :: enum u32 {
READ_AREA = 1 << 0,
WRITE_AREA = 1 << 1,
EXECUTE_AREA = 1 << 2,
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 = 1 << 3,
CLONEABLE_AREA = 1 << 8,
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: c.size_t, lock: area_locking, protection: area_protection_flags) -> area_id ---
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: c.size_t) -> 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: c.size_t) -> status_t ---
_get_next_area_info :: proc(team: team_id, cookie: ^c.ssize_t, areaInfo: ^area_info, size: c.size_t) -> 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
@@ -80,33 +82,35 @@ foreign libroot {
port_info :: struct {
port: port_id,
team: team_id,
name: [OS_NAME_LENGTH]c.char,
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_flags :: enum u32 {
USE_USER_MEMCPY = 0x80000000,
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 = 0x100,
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: c.size_t) -> c.ssize_t ---
read_port_etc :: proc(port: port_id, code: ^i32, buffer: rawptr, bufferSize: c.size_t, flags: port_flags, timeout: bigtime_t) -> c.ssize_t ---
write_port :: proc(port: port_id, code: i32, buffer: rawptr, bufferSize: c.size_t) -> status_t ---
write_port_etc :: proc(port: port_id, code: i32, buffer: rawptr, bufferSize: c.size_t, flags: port_flags, timeout: bigtime_t) -> status_t ---
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) -> c.ssize_t ---
port_buffer_size_etc :: proc(port: port_id, flags: port_flags, timeout: bigtime_t) -> c.ssize_t ---
port_count :: proc(port: port_id) -> c.ssize_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: c.size_t) -> status_t ---
_get_next_port_info :: proc(team: team_id, cookie: ^i32, portInfo: ^port_info, portInfoSize: c.size_t) -> 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
@@ -114,22 +118,24 @@ foreign libroot {
sem_info :: struct {
sem: sem_id,
team: team_id,
name: [OS_NAME_LENGTH]c.char,
name: [OS_NAME_LENGTH]byte,
count: i32,
latest_holder: thread_id,
}
semaphore_flags :: enum u32 {
CAN_INTERRUPT = 0x01, // acquisition of the semaphore can be interrupted (system use only)
CHECK_PERMISSION = 0x04, // ownership will be checked (system use only)
KILL_CAN_INTERRUPT = 0x20, // acquisition of the semaphore can be interrupted by SIGKILL[THR], even if not CAN_INTERRUPT (system use only)
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 = 0x02, // thread is not rescheduled
RELEASE_ALL = 0x08, // all waiting threads will be woken up, count will be zeroed
RELEASE_IF_WAITING_ONLY = 0x10, // release count only if there are any threads waiting
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 ---
@@ -141,8 +147,8 @@ foreign libroot {
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: c.size_t) -> status_t ---
_get_next_sem_info :: proc(team: team_id, cookie: ^i32, info: ^sem_info, infoSize: c.size_t) -> 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
@@ -155,7 +161,7 @@ team_info :: struct {
debugger_nub_thread: thread_id,
debugger_nub_port: port_id,
argc: i32,
args: [64]c.char,
args: [64]byte,
uid: uid_t,
gid: gid_t,
@@ -165,7 +171,7 @@ team_info :: struct {
group_id: pid_t,
session_id: pid_t,
parent: team_id,
name: [OS_NAME_LENGTH]c.char,
name: [OS_NAME_LENGTH]byte,
start_time: bigtime_t,
}
@@ -183,17 +189,18 @@ team_usage_who :: enum i32 {
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: c.size_t) -> status_t ---
_get_next_team_info :: proc(cookie: ^i32, info: ^team_info, size: c.size_t) -> status_t ---
_get_team_usage_info :: proc(id: team_id, who: team_usage_who, info: ^team_usage_info, size: c.size_t) -> 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 c.int {
thread_state :: enum i32 {
RUNNING = 1,
READY,
RECEIVING,
@@ -205,7 +212,7 @@ thread_state :: enum c.int {
thread_info :: struct {
thread: thread_id,
team: team_id,
name: [OS_NAME_LENGTH]c.char,
name: [OS_NAME_LENGTH]byte,
state: thread_state,
priority: thread_priority,
sem: sem_id,
@@ -234,6 +241,7 @@ 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 ---
@@ -247,24 +255,25 @@ foreign libroot {
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: c.size_t) -> status_t ---
receive_data :: proc(sender: ^thread_id, buffer: rawptr, bufferSize: c.size_t) -> i32 ---
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: c.int, flags: u32) -> status_t ---
snooze_until :: proc(time: bigtime_t, timeBase: c.int) -> status_t ---
_get_thread_info :: proc(id: thread_id, info: ^thread_info, size: c.size_t) -> status_t ---
_get_next_thread_info :: proc(team: team_id, cookie: ^i32, info: ^thread_info, size: c.size_t) -> status_t ---
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() -> c.ulong ---
set_real_time_clock :: proc(secsSinceJan1st1970: c.ulong) ---
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 ---
@@ -280,12 +289,14 @@ alarm_mode :: enum u32 {
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) ---
/*
@@ -296,7 +307,7 @@ foreign libroot {
to re-enable the default debugger pass a zero.
*/
disable_debugger :: proc(state: c.int) -> c.int ---
disable_debugger :: proc(state: i32) -> i32 ---
}
// System information
@@ -338,15 +349,15 @@ system_info :: struct {
max_teams: u32,
used_teams: u32,
kernel_name: [FILE_NAME_LENGTH]c.char,
kernel_build_date: [OS_NAME_LENGTH]c.char,
kernel_build_time: [OS_NAME_LENGTH]c.char,
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 c.int {
topology_level_type :: enum i32 {
UNKNOWN,
ROOT,
SMT,
@@ -354,7 +365,7 @@ topology_level_type :: enum c.int {
PACKAGE,
}
cpu_platform :: enum c.int {
cpu_platform :: enum i32 {
UNKNOWN,
x86,
x86_64,
@@ -370,7 +381,7 @@ cpu_platform :: enum c.int {
RISC_V,
}
cpu_vendor :: enum c.int {
cpu_vendor :: enum i32 {
UNKNOWN,
AMD,
CYRIX,
@@ -408,95 +419,80 @@ cpu_topology_node_info :: struct {
},
}
// FIXME: Add cpuid_info when bit fields are ready.
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: c.size_t) -> 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 ---
is_computer_on :: proc() -> i32 ---
is_computer_on_fire :: proc() -> f64 ---
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 ---
}
// Signal.h
SIG_BLOCK :: 1
SIG_UNBLOCK :: 2
SIG_SETMASK :: 3
/*
* The list of all defined signals:
*
* The numbering of signals for Haiku attempts to maintain
* some consistency with UN*X conventions so that things
* like "kill -9" do what you expect.
*/
SIGHUP :: 1 // hangup -- tty is gone!
SIGINT :: 2 // interrupt
SIGQUIT :: 3 // `quit' special character typed in tty
SIGILL :: 4 // illegal instruction
SIGCHLD :: 5 // child process exited
SIGABRT :: 6 // abort() called, dont' catch
SIGPIPE :: 7 // write to a pipe w/no readers
SIGFPE :: 8 // floating point exception
SIGKILL :: 9 // kill a team (not catchable)
SIGSTOP :: 10 // suspend a thread (not catchable)
SIGSEGV :: 11 // segmentation violation (read: invalid pointer)
SIGCONT :: 12 // continue execution if suspended
SIGTSTP :: 13 // `stop' special character typed in tty
SIGALRM :: 14 // an alarm has gone off (see alarm())
SIGTERM :: 15 // termination requested
SIGTTIN :: 16 // read of tty from bg process
SIGTTOU :: 17 // write to tty from bg process
SIGUSR1 :: 18 // app defined signal 1
SIGUSR2 :: 19 // app defined signal 2
SIGWINCH :: 20 // tty window size changed
SIGKILLTHR :: 21 // be specific: kill just the thread, not team
SIGTRAP :: 22 // Trace/breakpoint trap
SIGPOLL :: 23 // Pollable event
SIGPROF :: 24 // Profiling timer expired
SIGSYS :: 25 // Bad system call
SIGURG :: 26 // High bandwidth data is available at socket
SIGVTALRM :: 27 // Virtual timer expired
SIGXCPU :: 28 // CPU time limit exceeded
SIGXFSZ :: 29 // File size limit exceeded
SIGBUS :: 30 // access to undefined portion of a memory object
sigval :: struct #raw_union {
sival_int: c.int,
sival_ptr: rawptr,
}
siginfo_t :: struct {
si_signo: c.int, // signal number
si_code: c.int, // signal code
si_errno: c.int, // if non zero, an error number associated with this signal
si_pid: pid_t, // sending process ID
si_uid: uid_t, // real user ID of sending process
si_addr: rawptr, // address of faulting instruction
si_status: c.int, // exit value or signal
si_band: c.long, // band event for SIGPOLL
si_value: sigval, // signal value
}
// POSIX signals
@(default_calling_convention="c")
foreign libroot {
// signal set (sigset_t) manipulation
sigemptyset :: proc(set: ^sigset_t) -> c.int ---
sigfillset :: proc(set: ^sigset_t) -> c.int ---
sigaddset :: proc(set: ^sigset_t, _signal: c.int) -> c.int ---
sigdelset :: proc(set: ^sigset_t, _signal: c.int) -> c.int ---
sigismember :: proc(set: ^sigset_t, _signal: c.int) -> c.int ---
// querying and waiting for signals
sigpending :: proc(set: ^sigset_t) -> c.int ---
sigsuspend :: proc(mask: ^sigset_t) -> c.int ---
sigpause :: proc(_signal: c.int) -> c.int ---
sigwait :: proc(set: ^sigset_t, _signal: ^c.int) -> c.int ---
sigwaitinfo :: proc(set: ^sigset_t, info: ^siginfo_t) -> c.int ---
sigtimedwait :: proc(set: ^sigset_t, info: ^siginfo_t, timeout: ^unix.timespec) -> c.int ---
/*
Wait for queued signals.
send_signal :: proc(threadID: thread_id, signal: c.uint) -> c.int ---
set_signal_stack :: proc(base: rawptr, size: c.size_t) ---
[[ 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 ---
}

View File

@@ -1,9 +1,7 @@
#+build haiku
package sys_haiku
import "core:c"
status_t :: i32
status_t :: Errno
bigtime_t :: i64
nanotime_t :: i64
type_code :: u32
@@ -37,16 +35,20 @@ mode_t :: u32
umode_t :: u32
nlink_t :: i32
caddr_t :: ^c.char
caddr_t :: [^]byte
addr_t :: phys_addr_t
key_t :: i32
clockid_t :: i32
time_t :: i64 when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 else i32
time_t :: int
timespec :: struct {
tv_sec: time_t,
tv_nsec: int,
}
sig_atomic_t :: c.int
sig_atomic_t :: i32
sigset_t :: u64
image_id :: i32

View File

@@ -1,10 +1,12 @@
#+build darwin, linux, freebsd, openbsd, netbsd
#+build darwin, linux, freebsd, openbsd, netbsd, haiku
package posix
import "core:c"
when ODIN_OS == .Darwin {
foreign import lib "system:System.framework"
} else when ODIN_OS == .Haiku {
foreign import lib "system:network"
} else {
foreign import lib "system:c"
}

View File

@@ -1,4 +1,4 @@
#+build darwin, linux, freebsd, openbsd, netbsd
#+build darwin, linux, freebsd, openbsd, netbsd, haiku
package posix
import "core:c"
@@ -219,12 +219,23 @@ when ODIN_OS == .Darwin {
} else when ODIN_OS == .Linux {
dirent :: struct {
d_ino: u64, /* [PSX] file number of entry */
d_off: i64, /* directory offset of the next entry */
d_reclen: u16, /* length of this record */
d_type: D_Type, /* file type */
d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */
}
dirent :: struct {
d_ino: u64, /* [PSX] file number of entry */
d_off: i64, /* directory offset of the next entry */
d_reclen: u16, /* length of this record */
d_type: D_Type, /* file type */
d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */
}
} else when ODIN_OS == .Haiku {
dirent :: struct {
d_dev: dev_t, /* device */
d_pdev: dev_t, /* parent device (only for queries) */
d_ino: ino_t, /* inode number */
d_pino: ino_t, /* parent inode (only for queries) */
d_reclen: c.ushort, /* length of this record, not the name */
d_name: [0]c.char `fmt:"s,0"`, /* name of the entry (null byte terminated) */
}
}

View File

@@ -1,4 +1,4 @@
#+build windows, darwin, linux, freebsd, openbsd, netbsd
#+build windows, darwin, linux, freebsd, openbsd, netbsd, haiku
package posix
import "core:c"
@@ -536,5 +536,92 @@ when ODIN_OS == .Darwin {
ETXTBSY :: 139
EWOULDBLOCK :: 140
EXDEV :: 18
} else when ODIN_OS == .Haiku {
_HAIKU_USE_POSITIVE_POSIX_ERRORS :: libc._HAIKU_USE_POSITIVE_POSIX_ERRORS
_POSIX_ERROR_FACTOR :: libc._POSIX_ERROR_FACTOR
_GENERAL_ERROR_BASE :: min(c.int)
_OS_ERROR_BASE :: _GENERAL_ERROR_BASE + 0x1000
_STORAGE_ERROR_BASE :: _GENERAL_ERROR_BASE + 0x6000
_POSIX_ERROR_BASE :: _GENERAL_ERROR_BASE + 0x7000
EIO :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 1) // B_IO_ERROR
EACCES :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 2) // B_PERMISSION_DENIED
EINVAL :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 5) // B_BAD_VALUE
ETIMEDOUT :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 9) // B_TIMED_OUT
EINTR :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 10) // B_INTERRUPTED
EAGAIN :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 11) // B_WOULD_BLOCK /* SysV compatibility */
EWOULDBLOCK :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 11) // B_WOULD_BLOCK /* BSD compatibility */
EBUSY :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 14) // B_BUSY
EPERM :: _POSIX_ERROR_FACTOR * (_GENERAL_ERROR_BASE + 15) // B_NOT_ALLOWED
EFAULT :: _POSIX_ERROR_FACTOR * (_OS_ERROR_BASE + 0x301) // B_BAD_ADDRESS
ENOEXEC :: _POSIX_ERROR_FACTOR * (_OS_ERROR_BASE + 0x302) // B_NOT_AN_EXECUTABLE
EBADF :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 0) // B_FILE_ERROR
EEXIST :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 2) // B_FILE_EXISTS
ENOENT :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 3) // B_ENTRY_NOT_FOUND
ENAMETOOLONG :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 4) // B_NAME_TOO_LONG
ENOTDIR :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 5) // B_NOT_A_DIRECTORY
ENOTEMPTY :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 6) // B_DIRECTORY_NOT_EMPTY
ENOSPC :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 7) // B_DEVICE_FULL
EROFS :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 8) // B_READ_ONLY_DEVICE
EISDIR :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 9) // B_IS_A_DIRECTORY
EMFILE :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 10) // B_NO_MORE_FDS
EXDEV :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 11) // B_CROSS_DEVICE_LINK
ELOOP :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 12) // B_LINK_LIMIT
EPIPE :: _POSIX_ERROR_FACTOR * (_STORAGE_ERROR_BASE + 13) // B_BUSTED_PIPE
ENOMEM :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 0) when _HAIKU_USE_POSITIVE_POSIX_ERRORS else (_GENERAL_ERROR_BASE + 0) // B_NO_MEMORY
E2BIG :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 1)
ECHILD :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 2)
EDEADLK :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 3)
EFBIG :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 4)
EMLINK :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 5)
ENFILE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 6)
ENODEV :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 7)
ENOLCK :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 8)
ENOSYS :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 9)
ENOTTY :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 10)
ENXIO :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 11)
ESPIPE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 12)
ESRCH :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 13)
EPROTOTYPE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 18)
EPROTONOSUPPORT :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 19)
EAFNOSUPPORT :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 21)
EADDRINUSE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 22)
EADDRNOTAVAIL :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 23)
ENETDOWN :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 24)
ENETUNREACH :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 25)
ENETRESET :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 26)
ECONNABORTED :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 27)
ECONNRESET :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 28)
EISCONN :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 29)
ENOTCONN :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 30)
ECONNREFUSED :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 32)
EHOSTUNREACH :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 33)
ENOPROTOOPT :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 34)
ENOBUFS :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 35)
EINPROGRESS :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 36)
EALREADY :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 37)
ENOMSG :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 39)
ESTALE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 40)
EOVERFLOW :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 41)
EMSGSIZE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 42)
EOPNOTSUPP :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 43)
ENOTSOCK :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 44)
EBADMSG :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 46)
ECANCELED :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 47)
EDESTADDRREQ :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 48)
EDQUOT :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 49)
EIDRM :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 50)
EMULTIHOP :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 51)
ENODATA :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 52)
ENOLINK :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 53)
ENOSR :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 54)
ENOSTR :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 55)
ENOTSUP :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 56)
EPROTO :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 57)
ETIME :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 58)
ETXTBSY :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 59)
ENOTRECOVERABLE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 61)
EOWNERDEAD :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 62)
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, openbsd, freebsd, netbsd
#+build linux, darwin, openbsd, freebsd, netbsd, haiku
package posix
import "core:c"
@@ -343,6 +343,7 @@ when ODIN_OS == .Darwin {
l_type: Lock_Type, /* [PSX] type of lock */
l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
}
} else when ODIN_OS == .OpenBSD {
off_t :: distinct c.int64_t
@@ -408,6 +409,72 @@ when ODIN_OS == .Darwin {
l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
}
} else when ODIN_OS == .Haiku {
off_t :: distinct c.int64_t
pid_t :: distinct c.int32_t
/* commands that can be passed to fcntl() */
F_DUPFD :: 0x0001 /* duplicate fd */
F_GETFD :: 0x0002 /* get fd flags */
F_SETFD :: 0x0004 /* set fd flags */
F_GETFL :: 0x0008 /* get file status flags and access mode */
F_SETFL :: 0x0010 /* set file status flags */
F_GETLK :: 0x0020 /* get locking information */
F_SETLK :: 0x0080 /* set locking information */
F_SETLKW :: 0x0100 /* as above, but waits if blocked */
F_DUPFD_CLOEXEC :: 0x0200 /* duplicate fd with close on exec set */
F_GETOWN :: -1 // NOTE: Not supported.
F_SETOWN :: -1 // NOTE: Not supported.
/* advisory locking types */
F_RDLCK :: 0x0040 /* read or shared lock */
F_UNLCK :: 0x0200 /* unlock */
F_WRLCK :: 0x0400 /* write or exclusive lock */
/* file descriptor flags for fcntl() */
FD_CLOEXEC :: 1
O_CLOEXEC :: 0x00000040
O_CREAT :: 0x0200
O_DIRECTORY :: 0x00200000
O_EXCL :: 0x0100
O_NOCTTY :: 0x1000
O_NOFOLLOW :: 0x00080000
O_TRUNC :: 0x0400
_O_TTY_INIT :: 0
O_TTY_INIT :: O_Flags{} // NOTE: not defined in the headers
O_APPEND :: 0x0800
O_DSYNC :: 0x040000
O_NONBLOCK :: 0x0080
O_SYNC :: 0x010000
O_RSYNC :: 0x020000
O_EXEC :: 0x04000000 // NOTE: not defined in the headers
O_RDONLY :: 0
O_RDWR :: 0x0002
O_WRONLY :: 0x0001
_O_SEARCH :: 0
O_SEARCH :: O_Flags{} // NOTE: not defined in the headers
AT_FDCWD: FD: -100
AT_EACCESS :: 0x08
AT_SYMLINK_NOFOLLOW :: 0x01
AT_SYMLINK_FOLLOW :: 0x02
AT_REMOVEDIR :: 0x04
flock :: struct {
l_type: Lock_Type, /* [PSX] type of lock */
l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
l_start: off_t, /* [PSX] relative offset in bytes */
l_len: off_t, /* [PSX] size; if 0 then until EOF */
l_pid: pid_t, /* [PSX] process ID of the process holding the lock */
}
} else when ODIN_OS == .Linux {
off_t :: distinct c.int64_t

View File

@@ -1,4 +1,4 @@
#+build darwin, linux, openbsd, freebsd, netbsd
#+build darwin, linux, openbsd, freebsd, netbsd, haiku
package posix
import "core:c"
@@ -46,7 +46,7 @@ FNM_Flag_Bits :: enum c.int {
}
FNM_Flags :: bit_set[FNM_Flag_Bits; c.int]
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku {
FNM_NOMATCH :: 1

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -109,7 +109,7 @@ when ODIN_OS == .Darwin {
GLOB_NOMATCH :: -3
GLOB_NOSPACE :: -1
} else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD {
} else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .Haiku {
glob_t :: struct {
gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */
@@ -134,7 +134,7 @@ when ODIN_OS == .Darwin {
GLOB_ERR :: 0x0004
GLOB_MARK :: 0x0008
GLOB_NOCHECK :: 0x0010
GLOB_NOESCAPE :: 0x2000 when ODIN_OS == .FreeBSD else 0x0100
GLOB_NOESCAPE :: 0x2000 when ODIN_OS == .FreeBSD || ODIN_OS == .Haiku else 0x0100
GLOB_NOSORT :: 0x0020
GLOB_ABORTED :: -2

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -115,7 +115,7 @@ foreign lib {
getgrnam_r :: proc(name: cstring, grp: ^group, buffer: [^]byte, bufsize: c.size_t, result: ^^group) -> Errno ---
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku || ODIN_OS == .Linux {
gid_t :: distinct c.uint32_t

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -143,7 +143,7 @@ nl_item :: enum nl_item_t {
CRNCYSTR = CRNCYSTR,
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .Haiku {
// NOTE: declared with `_t` so we can enumerate the real `nl_info`.
nl_item_t :: distinct c.int
@@ -210,7 +210,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD {
YESEXPR :: 52
NOEXPR :: 53
CRNCYSTR :: 56
CRNCYSTR :: 54 when ODIN_OS == .Haiku else 56
} else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
when ODIN_OS == .Darwin {

View File

@@ -1,4 +1,4 @@
#+build windows, linux, darwin, netbsd, openbsd, freebsd
#+build windows, linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c/libc"

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -319,7 +319,7 @@ Info_Errno :: enum c.int {
OVERFLOW = EAI_OVERFLOW,
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
hostent :: struct {
h_name: cstring, /* [PSX] official name of host */
@@ -431,6 +431,23 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
NI_NUMERICSCOPE :: 0x100
NI_DGRAM :: 16
} else when ODIN_OS == .Haiku {
AI_PASSIVE :: 0x001
AI_CANONNAME :: 0x002
AI_NUMERICHOST :: 0x004
AI_NUMERICSERV :: 0x008
AI_V4MAPPED :: 0x800
AI_ALL :: 0x100
AI_ADDRCONFIG :: 0x400
NI_NOFQDN :: 0x01
NI_NUMERICHOST :: 0x02
NI_NAMEREQD :: 0x04
NI_NUMERICSERV :: 0x08
NI_DGRAM :: 0x10
NI_NUMERICSCOPE :: 0x40
}
when ODIN_OS == .OpenBSD {

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -31,20 +31,31 @@ Protocol :: enum c.int {
UDP = IPPROTO_UDP,
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
in_addr :: struct {
s_addr: in_addr_t, /* [PSX] big endian address */
}
in6_addr :: struct {
using _: struct #raw_union {
s6_addr: [16]c.uint8_t, /* [PSX] big endian address */
__u6_addr16: [8]c.uint16_t,
__u6_addr32: [4]c.uint32_t,
},
when ODIN_OS == .Haiku {
in6_addr :: struct #packed {
using _: struct #raw_union {
s6_addr: [16]c.uint8_t, /* [PSX] big endian address */
__u6_addr16: [8]c.uint16_t,
__u6_addr32: [4]c.uint32_t,
},
}
} else {
in6_addr :: struct {
using _: struct #raw_union {
s6_addr: [16]c.uint8_t, /* [PSX] big endian address */
__u6_addr16: [8]c.uint16_t,
__u6_addr32: [4]c.uint32_t,
},
}
}
when ODIN_OS == .Linux {
sockaddr_in :: struct {
@@ -77,12 +88,20 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
} else {
when ODIN_OS == .Haiku {
@(private)
_SIN_ZEROSIZE :: 24
} else {
@(private)
_SIN_ZEROSIZE :: 8
}
sockaddr_in :: struct {
sin_len: c.uint8_t,
sin_family: sa_family_t, /* [PSX] AF_INET (but a smaller size) */
sin_port: in_port_t, /* [PSX] port number */
sin_addr: in_addr, /* [PSX] IP address */
sin_zero: [8]c.char,
sin_zero: [_SIN_ZEROSIZE]c.char,
}
sockaddr_in6 :: struct {
@@ -99,13 +118,23 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
ipv6mr_interface: c.uint, /* [PSX] interface index */
}
IPV6_JOIN_GROUP :: 12
IPV6_LEAVE_GROUP :: 13
IPV6_MULTICAST_HOPS :: 10
IPV6_MULTICAST_IF :: 9
IPV6_MULTICAST_LOOP :: 11
IPV6_UNICAST_HOPS :: 4
IPV6_V6ONLY :: 27
when ODIN_OS == .Haiku {
IPV6_JOIN_GROUP :: 28
IPV6_LEAVE_GROUP :: 29
IPV6_MULTICAST_HOPS :: 25
IPV6_MULTICAST_IF :: 24
IPV6_MULTICAST_LOOP :: 26
IPV6_UNICAST_HOPS :: 27
IPV6_V6ONLY :: 30
} else {
IPV6_JOIN_GROUP :: 12
IPV6_LEAVE_GROUP :: 13
IPV6_MULTICAST_HOPS :: 10
IPV6_MULTICAST_IF :: 9
IPV6_MULTICAST_LOOP :: 11
IPV6_UNICAST_HOPS :: 4
IPV6_V6ONLY :: 27
}
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "base:intrinsics"
@@ -25,7 +25,11 @@ foreign lib {
poll :: proc(fds: [^]pollfd, nfds: nfds_t, timeout: c.int) -> c.int ---
}
nfds_t :: c.uint
when ODIN_OS == .Haiku {
nfds_t :: c.ulong
} else {
nfds_t :: c.uint
}
Poll_Event_Bits :: enum c.short {
// Data other than high-priority data may be read without blocking.
@@ -53,7 +57,7 @@ Poll_Event_Bits :: enum c.short {
}
Poll_Event :: bit_set[Poll_Event_Bits; c.short]
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku {
pollfd :: struct {
fd: FD, /* [PSX] the following descriptor being polled */
@@ -61,17 +65,36 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
revents: Poll_Event, /* [PSX] the output event flags */
}
POLLIN :: 0x0001
POLLRDNORM :: 0x0040
POLLRDBAND :: 0x0080
POLLPRI :: 0x0002
POLLOUT :: 0x0004
POLLWRNORM :: POLLOUT
POLLWRBAND :: 0x0100
when ODIN_OS == .Haiku {
POLLIN :: 0x0001 /* any readable data available */
POLLOUT :: 0x0002 /* file descriptor is writeable */
POLLRDNORM :: POLLIN
POLLWRNORM :: POLLOUT
POLLRDBAND :: 0x0008 /* priority readable data */
POLLWRBAND :: 0x0010 /* priority data can be written */
POLLPRI :: 0x0020 /* high priority readable data */
POLLERR :: 0x0004 /* errors pending */
POLLHUP :: 0x0080 /* disconnected */
POLLNVAL :: 0x1000 /* invalid file descriptor */
} else {
POLLIN :: 0x0001
POLLRDNORM :: 0x0040
POLLRDBAND :: 0x0080
POLLPRI :: 0x0002
POLLOUT :: 0x0004
POLLWRNORM :: POLLOUT
POLLWRBAND :: 0x0100
POLLERR :: 0x0008
POLLHUP :: 0x0010
POLLNVAL :: 0x0020
}
POLLERR :: 0x0008
POLLHUP :: 0x0010
POLLNVAL :: 0x0020
} else when ODIN_OS == .Linux {

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -554,6 +554,56 @@ when ODIN_OS == .Darwin {
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
}
} else when ODIN_OS == .Haiku {
PTHREAD_CANCEL_ASYNCHRONOUS :: 2
PTHREAD_CANCEL_DEFERRED :: 0
PTHREAD_CANCEL_DISABLE :: 1
PTHREAD_CANCEL_ENABLE :: 0
PTHREAD_CANCELED :: rawptr(uintptr(1))
PTHREAD_CREATE_DETACHED :: 0x1
PTHREAD_CREATE_JOINABLE :: 0
PTHREAD_EXPLICIT_SCHED :: 0
PTHREAD_INHERIT_SCHED :: 0x4
PTHREAD_PRIO_INHERIT :: 1
PTHREAD_PRIO_NONE :: 0
PTHREAD_PRIO_PROTECT :: 2
PTHREAD_PROCESS_SHARED :: 1
PTHREAD_PROCESS_PRIVATE :: 0
PTHREAD_SCOPE_PROCESS :: 0
PTHREAD_SCOPE_SYSTEM :: 0x2
pthread_t :: distinct rawptr
pthread_attr_t :: distinct rawptr
pthread_key_t :: distinct c.int
pthread_mutex_t :: struct {
flags: u32,
lock: i32,
unused: i32,
owner: i32,
owner_count: i32,
}
pthread_cond_t :: struct {
flags: u32,
unused: i32,
mutex: ^pthread_mutex_t,
waiter_count: i32,
lock: i32,
}
sched_param :: struct {
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
}
} else when ODIN_OS == .Linux {
PTHREAD_CANCEL_DEFERRED :: 0

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -176,4 +176,16 @@ when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
pw_shell: cstring, /* Shell program. */
}
} else when ODIN_OS == .Haiku {
passwd :: struct {
pw_name: cstring, /* [PSX] user name */
pw_passwd: cstring, /* encrypted password */
pw_uid: uid_t, /* [PSX] user uid */
pw_gid: gid_t, /* [PSX] user gid */
pw_dir: cstring, /* Home directory. */
pw_shell: cstring, /* Shell program. */
pw_gecos: cstring, /* Real name. */
}
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -101,4 +101,11 @@ when ODIN_OS == .Darwin {
SCHED_FIFO :: 1
SCHED_RR :: 2
} else when ODIN_OS == .Haiku {
SCHED_FIFO :: 1
SCHED_RR :: 2
// SCHED_SPORADIC :: 3 NOTE: not a thing on freebsd, netbsd and probably others, leaving it out
SCHED_OTHER :: 4
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "base:intrinsics"
@@ -1180,4 +1180,151 @@ when ODIN_OS == .Darwin {
SI_TIMER :: -2
SI_MESGQ :: -3
SI_ASYNCIO :: -4
} else when ODIN_OS == .Haiku {
// Request that signal be held
SIG_HOLD :: rawptr(uintptr(3))
uid_t :: distinct c.uint32_t
sigset_t :: distinct u64
SIGHUP :: 1 // hangup -- tty is gone!
//SIGINT :: 2 // interrupt
SIGQUIT :: 3 // `quit' special character typed in tty
//SIGILL :: 4 // illegal instruction
SIGCHLD :: 5 // child process exited
//SIGABRT :: 6 // abort() called, dont' catch
SIGPIPE :: 7 // write to a pipe w/no readers
//SIGFPE :: 8 // floating point exception
SIGKILL :: 9 // kill a team (not catchable)
SIGSTOP :: 10 // suspend a thread (not catchable)
//SIGSEGV :: 11 // segmentation violation (read: invalid pointer)
SIGCONT :: 12 // continue execution if suspended
SIGTSTP :: 13 // `stop' special character typed in tty
SIGALRM :: 14 // an alarm has gone off (see alarm())
//SIGTERM :: 15 // termination requested
SIGTTIN :: 16 // read of tty from bg process
SIGTTOU :: 17 // write to tty from bg process
SIGUSR1 :: 18 // app defined signal 1
SIGUSR2 :: 19 // app defined signal 2
SIGWINCH :: 20 // tty window size changed
SIGKILLTHR :: 21 // be specific: kill just the thread, not team
SIGTRAP :: 22 // Trace/breakpoint trap
SIGPOLL :: 23 // Pollable event
SIGPROF :: 24 // Profiling timer expired
SIGSYS :: 25 // Bad system call
SIGURG :: 26 // High bandwidth data is available at socket
SIGVTALRM :: 27 // Virtual timer expired
SIGXCPU :: 28 // CPU time limit exceeded
SIGXFSZ :: 29 // File size limit exceeded
SIGBUS :: 30 // access to undefined portion of a memory object
// NOTE: this is actually defined as `sigaction`, but due to the function with the same name
// `_t` has been added.
sigaction_t :: struct {
using _: struct #raw_union {
sa_handler: proc "c" (Signal), /* [PSX] signal-catching function or one of the SIG_IGN or SIG_DFL */
sa_sigaction: proc "c" (Signal, ^siginfo_t, rawptr), /* [PSX] signal-catching function */
},
sa_mask: sigset_t, /* [PSX] set of signals to be blocked during execution of the signal handling function */
sa_flags: SA_Flags, /* [PSX] special flags */
sa_userdata: rawptr, /* will be passed to the signal handler, BeOS extension */
}
SIG_BLOCK :: 1
SIG_UNBLOCK :: 2
SIG_SETMASK :: 3
SA_NOCLDSTOP :: 0x01
SA_NOCLDWAIT :: 0x02
SA_RESETHAND :: 0x04
SA_NODEFER :: 0x08
SA_RESTART :: 0x10
SA_ONSTACK :: 0x20
SA_SIGINFO :: 0x40
SS_ONSTACK :: 1
SS_DISABLE :: 2
MINSIGSTKSZ :: 8192
SIGSTKSZ :: 16384
stack_t :: struct {
ss_sp: rawptr, /* [PSX] stack base or pointer */
ss_size: c.size_t, /* [PSX] stack size */
ss_flags: SS_Flags, /* [PSX] flags */
}
siginfo_t :: struct {
si_signo: Signal, /* [PSX] signal number */
si_code: struct #raw_union { /* [PSX] specific more detailed codes per signal */
ill: ILL_Code,
fpe: FPE_Code,
segv: SEGV_Code,
bus: BUS_Code,
trap: TRAP_Code,
chld: CLD_Code,
poll: POLL_Code,
any: Any_Code,
},
si_errno: Errno, /* [PSX] errno value associated with this signal */
si_pid: pid_t, /* sending process ID */
si_uid: uid_t, /* real user ID of sending process */
si_addr: rawptr, /* address of faulting instruction */
si_status: c.int, /* exit value or signal */
si_band: c.long, /* band event for SIGPOLL */
si_value: sigval, /* signal value */
}
/* any signal */
SI_USER :: 0 /* signal sent by user */
SI_QUEUE :: 1 /* signal sent by sigqueue() */
SI_TIMER :: 2 /* signal sent on timer_settime() timeout */
SI_ASYNCIO :: 3 /* signal sent on asynchronous I/O completion */
SI_MESGQ :: 4 /* signal sent on arrival of message on empty message queue */
/* SIGILL */
ILL_ILLOPC :: 10 /* illegal opcode */
ILL_ILLOPN :: 11 /* illegal operand */
ILL_ILLADR :: 12 /* illegal addressing mode */
ILL_ILLTRP :: 13 /* illegal trap */
ILL_PRVOPC :: 14 /* privileged opcode */
ILL_PRVREG :: 15 /* privileged register */
ILL_COPROC :: 16 /* coprocessor error */
ILL_BADSTK :: 17 /* internal stack error */
/* SIGFPE */
FPE_INTDIV :: 20 /* integer division by zero */
FPE_INTOVF :: 21 /* integer overflow */
FPE_FLTDIV :: 22 /* floating-point division by zero */
FPE_FLTOVF :: 23 /* floating-point overflow */
FPE_FLTUND :: 24 /* floating-point underflow */
FPE_FLTRES :: 25 /* floating-point inexact result */
FPE_FLTINV :: 26 /* invalid floating-point operation */
FPE_FLTSUB :: 27 /* subscript out of range */
/* SIGSEGV */
SEGV_MAPERR :: 30 /* address not mapped to object */
SEGV_ACCERR :: 31 /* invalid permissions for mapped object */
/* SIGBUS */
BUS_ADRALN :: 40 /* invalid address alignment */
BUS_ADRERR :: 41 /* nonexistent physical address */
BUS_OBJERR :: 42 /* object-specific hardware error */
/* SIGTRAP */
TRAP_BRKPT :: 50 /* process breakpoint */
TRAP_TRACE :: 51 /* process trace trap. */
/* SIGCHLD */
CLD_EXITED :: 60 /* child exited */
CLD_KILLED :: 61 /* child terminated abnormally without core dump */
CLD_DUMPED :: 62 /* child terminated abnormally with core dump */
CLD_TRAPPED :: 63 /* traced child trapped */
CLD_STOPPED :: 64 /* child stopped */
CLD_CONTINUED :: 65 /* stopped child continued */
/* SIGPOLL */
POLL_IN :: 70 /* input available */
POLL_OUT :: 71 /* output available */
POLL_MSG :: 72 /* input message available */
POLL_ERR :: 73 /* I/O error */
POLL_PRI :: 74 /* high priority input available */
POLL_HUP :: 75 /* device disconnected */
}

View File

@@ -1,4 +1,4 @@
#+build linux, windows, darwin, netbsd, openbsd, freebsd
#+build linux, windows, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "base:intrinsics"

View File

@@ -1,4 +1,4 @@
#+build linux, windows, linux, darwin, netbsd, openbsd, freebsd
#+build linux, windows, linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "base:intrinsics"

View File

@@ -1,4 +1,4 @@
#+build linux, windows, darwin, netbsd, openbsd, freebsd
#+build linux, windows, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "base:intrinsics"

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"

View File

@@ -1,4 +1,4 @@
#+build linux, windows, darwin, netbsd, openbsd, freebsd
#+build linux, windows, darwin, netbsd, openbsd, freebsd, haiku
package posix
when ODIN_OS == .Windows {

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -111,4 +111,27 @@ when ODIN_OS == .Darwin {
IPC_SET :: 1
IPC_STAT :: 2
} else when ODIN_OS == .Haiku {
key_t :: distinct c.int32_t
ipc_perm :: struct {
key: key_t,
uid: uid_t, /* [PSX] owner's user ID */
gid: gid_t, /* [PSX] owner's group ID */
cuid: uid_t, /* [PSX] creator's user ID */
cgid: gid_t, /* [PSX] creator's group ID */
mode: mode_t, /* [PSX] read/write perms */
}
IPC_CREAT :: 0o01000
IPC_EXCL :: 0o02000
IPC_NOWAIT :: 0o04000
IPC_PRIVATE :: key_t(0)
IPC_RMID :: 0
IPC_SET :: 1
IPC_STAT :: 2
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -171,4 +171,22 @@ when ODIN_OS == .Darwin {
__unused: [2]c.ulong,
}
} else when ODIN_OS == .Haiku {
msgqnum_t :: distinct c.uint32_t
msglen_t :: distinct c.uint32_t
MSG_NOERROR :: 0o10000
msqid_ds :: struct {
msg_perm: ipc_perm, /* [PSX] operation permission structure */
msg_qnum: msgqnum_t, /* [PSX] number of messages currently on queue */
msg_qbytes: msglen_t, /* [PSX] maximum number of bytes allowed on queue */
msg_lspid: pid_t, /* [PSX] process ID of last msgsnd() */
msg_lrpid: pid_t, /* [PSX] process ID of last msgrcv() */
msg_stime: time_t, /* [PSX] time of last msgsnd() */
msg_rtime: time_t, /* [PSX] time of last msgrcv() */
msg_ctime: time_t, /* [PSX] time of last change */
}
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -96,15 +96,26 @@ when ODIN_OS == .NetBSD {
@(private) LGETRUSAGE :: "getrusage"
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
PRIO_PROCESS :: 0
PRIO_PGRP :: 1
PRIO_USER :: 2
rlim_t :: distinct c.uint64_t
when ODIN_OS == .Haiku {
rlim_t :: distinct c.ulong
} else {
rlim_t :: distinct c.uint64_t
}
RLIM_INFINITY :: ~rlim_t(0) when ODIN_OS == .Linux else (rlim_t(1) << 63) - 1
when ODIN_OS == .Haiku {
RLIM_INFINITY :: rlim_t(0xFFFFFFFF)
} else when ODIN_OS == .Linux {
RLIM_INFINITY :: ~rlim_t(0)
} else {
RLIM_INFINITY :: (rlim_t(1) << 63) - 1
}
RLIM_SAVED_MAX :: RLIM_INFINITY
RLIM_SAVED_CUR :: RLIM_INFINITY
@@ -140,19 +151,29 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
ru_nivcsw: c.long, /* involuntary " */
}
RLIMIT_CORE :: 4
RLIMIT_CPU :: 0
RLIMIT_DATA :: 2
RLIMIT_FSIZE :: 1
RLIMIT_NOFILE :: 7 when ODIN_OS == .Linux else 8
RLIMIT_STACK :: 3
when ODIN_OS == .Linux {
RLIMIT_AS :: 9
} else when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD {
RLIMIT_AS :: 5
when ODIN_OS == .Haiku {
RLIMIT_CORE :: 0
RLIMIT_CPU :: 1
RLIMIT_DATA :: 2
RLIMIT_FSIZE :: 3
RLIMIT_NOFILE :: 4
RLIMIT_STACK :: 5
RLIMIT_AS :: 6
} else {
RLIMIT_AS :: 10
RLIMIT_CORE :: 4
RLIMIT_CPU :: 0
RLIMIT_DATA :: 2
RLIMIT_FSIZE :: 1
RLIMIT_NOFILE :: 7 when ODIN_OS == .Linux else 8
RLIMIT_STACK :: 3
when ODIN_OS == .Linux {
RLIMIT_AS :: 9
} else when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD {
RLIMIT_AS :: 5
} else {
RLIMIT_AS :: 10
}
}
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "base:intrinsics"
@@ -56,9 +56,9 @@ when ODIN_OS == .NetBSD {
LSELECT :: "select"
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
suseconds_t :: distinct (c.int32_t when ODIN_OS == .Darwin || ODIN_OS == .NetBSD else c.long)
suseconds_t :: distinct (c.int32_t when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .Haiku else c.long)
timeval :: struct {
tv_sec: time_t, /* [PSX] seconds */
@@ -75,8 +75,14 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
@(private)
ALIGN :: align_of(c.long) when ODIN_OS == .FreeBSD || ODIN_OS == .Linux else align_of(c.int32_t)
fd_set :: struct #align(ALIGN) {
fds_bits: [(FD_SETSIZE / __NFDBITS) when (FD_SETSIZE % __NFDBITS) == 0 else (FD_SETSIZE / __NFDBITS) + 1]c.int32_t,
when ODIN_OS == .Haiku {
fd_set :: struct #align(ALIGN) {
fds_bits: [(FD_SETSIZE + (__NFDBITS - 1)) / __NFDBITS]c.int32_t,
}
} else {
fd_set :: struct #align(ALIGN) {
fds_bits: [(FD_SETSIZE / __NFDBITS) when (FD_SETSIZE % __NFDBITS) == 0 else (FD_SETSIZE / __NFDBITS) + 1]c.int32_t,
}
}
@(private)

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -154,4 +154,30 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
sem_flg: c.short, /* [PSX] operation flags */
}
} else when ODIN_OS == .Haiku {
SEM_UNDO :: 10 // undo the operation on exit
// Commands for `semctl'.
GETPID :: 3
GETVAL :: 4
GETALL :: 5
GETNCNT :: 6
GETZCNT :: 7
SETVAL :: 8
SETALL :: 9
semid_ds :: struct {
sem_perm: ipc_perm, // [PSX] operation permission structure
sem_nsems: c.ushort, // [PSX] number of semaphores in set
sem_otime: time_t, // [PSX] last semop()
sem_ctime: time_t, // [PSX] last time changed by semctl()
}
sembuf :: struct {
sem_num: c.ushort, /* [PSX] semaphore number */
sem_op: c.short, /* [PSX] semaphore operation */
sem_flg: c.short, /* [PSX] operation flags */
}
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -328,24 +328,32 @@ when ODIN_OS == .NetBSD {
@(private) LSOCKET :: "socket"
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
socklen_t :: distinct c.uint
when ODIN_OS == .Haiku {
@(private)
_SA_DATASIZE :: 30
} else {
@(private)
_SA_DATASIZE :: 14
}
when ODIN_OS == .Linux {
_sa_family_t :: distinct c.ushort
sockaddr :: struct {
sa_family: sa_family_t, /* [PSX] address family */
sa_data: [14]c.char, /* [PSX] socket address */
sa_family: sa_family_t, /* [PSX] address family */
sa_data: [_SA_DATASIZE]c.char, /* [PSX] socket address */
}
} else {
_sa_family_t :: distinct c.uint8_t
sockaddr :: struct {
sa_len: c.uint8_t, /* total length */
sa_family: sa_family_t, /* [PSX] address family */
sa_data: [14]c.char, /* [PSX] socket address */
sa_len: c.uint8_t, /* total length */
sa_family: sa_family_t, /* [PSX] address family */
sa_data: [_SA_DATASIZE]c.char, /* [PSX] socket address */
}
}
@@ -355,6 +363,11 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
_SS_PAD1SIZE :: 6
@(private)
_SS_PAD2SIZE :: 240
} else when ODIN_OS == .Haiku {
@(private)
_SS_PAD1SIZE :: 6
@(private)
_SS_PAD2SIZE :: 112
} else when ODIN_OS == .Linux {
@(private)
_SS_SIZE :: 128
@@ -486,6 +499,26 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
SO_RCVTIMEO :: 66
SO_SNDTIMEO :: 67
} else when ODIN_OS == .Haiku {
SOL_SOCKET :: -1
SO_ACCEPTCONN :: 0x00000001
SO_BROADCAST :: 0x00000002
SO_DEBUG :: 0x00000004
SO_DONTROUTE :: 0x00000008
SO_ERROR :: 0x40000007
SO_KEEPALIVE :: 0x00000010
SO_OOBINLINE :: 0x00000020
SO_RCVBUF :: 0x40000004
SO_RCVLOWAT :: 0x40000005
SO_REUSEADDR :: 0x00000040
SO_SNDBUF :: 0x40000001
SO_SNDLOWAT :: 0x40000002
SO_TYPE :: 0x40000008
SO_LINGER :: 0x00000200
SO_RCVTIMEO :: 0x40000006
SO_SNDTIMEO :: 0x40000003
} else {
SOL_SOCKET :: 0xffff
@@ -523,7 +556,11 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
}
// The maximum backlog queue length for listen().
SOMAXCONN :: 128
when ODIN_OS == .Haiku {
SOMAXCONN :: 32
} else {
SOMAXCONN :: 128
}
when ODIN_OS == .Linux {
MSG_CTRUNC :: 0x008
@@ -549,11 +586,18 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
MSG_NOSIGNAL :: 0x00020000
} else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
MSG_NOSIGNAL :: 0x0400
} else when ODIN_OS == .Haiku {
MSG_NOSIGNAL :: 0x800
}
}
AF_INET :: 2
AF_UNIX :: 1
when ODIN_OS == .Haiku {
AF_INET :: 1
AF_UNIX :: 9
} else {
AF_INET :: 2
AF_UNIX :: 1
}
when ODIN_OS == .Darwin {
AF_INET6 :: 30
@@ -563,6 +607,8 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
AF_INET6 :: 24
} else when ODIN_OS == .Linux {
AF_INET6 :: 10
} else when ODIN_OS == .Haiku {
AF_INET6 :: 5
}
SHUT_RD :: 0

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -428,6 +428,36 @@ when ODIN_OS == .Darwin {
UTIME_NOW :: -2
UTIME_OMIT :: -1
} else when ODIN_OS == .Haiku {
dev_t :: distinct c.int32_t
nlink_t :: distinct c.int32_t
_mode_t :: distinct c.uint32_t
blkcnt_t :: distinct c.int64_t
blksize_t :: distinct c.int32_t
ino_t :: distinct c.int64_t
stat_t :: struct {
st_dev: dev_t, /* [PSX] ID of device containing file */
st_ino: ino_t, /* [PSX] file serial number */
st_mode: mode_t, /* [PSX] mode of file */
st_nlink: nlink_t, /* [PSX] number of hard links */
st_uid: uid_t, /* [PSX] user ID of the file */
st_gid: gid_t, /* [PSX] group ID of the file */
st_size: off_t, /* [PSX] file size, in bytes */
st_rdev: dev_t, /* [PSX] device ID */
st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
st_atim: timespec, /* [PSX] time of last access */
st_mtim: timespec, /* [PSX] time of last data modification */
st_ctim: timespec, /* [PSX] time of last status change */
st_crtim: timespec, /* [PSX] time of last status change */
st_type: c.uint32_t,
st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
}
UTIME_NOW :: 1000000000
UTIME_OMIT :: 1000000001
} else when ODIN_OS == .Linux {
dev_t :: distinct u64

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -78,4 +78,15 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
ITIMER_VIRTUAL :: 1
ITIMER_PROF :: 2
} else when ODIN_OS == .Haiku {
itimerval :: struct {
it_interval: timeval, /* [PSX] timer interval */
it_value: timeval, /* [PSX] current value */
}
ITIMER_REAL :: 1
ITIMER_VIRTUAL :: 2
ITIMER_PROF :: 3
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
when ODIN_OS == .Darwin {
@@ -25,7 +25,7 @@ when ODIN_OS == .NetBSD {
@(private) LTIMES :: "times"
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
tms :: struct {
tms_utime: clock_t, /* [PSX] user CPU time */

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -31,7 +31,7 @@ foreign libc {
writev :: proc(fildes: FD, iov: [^]iovec, iovcnt: c.int) -> c.ssize_t ---
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
iovec :: struct {
iov_base: rawptr, /* [PSX] base address of I/O memory region */

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -20,4 +20,12 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
sun_path: [108]c.char, /* [PSX] socket pathname */
}
} else when ODIN_OS == .Haiku {
sockaddr_un :: struct {
sun_len: c.uint8_t,
sun_family: sa_family_t, /* [PSX] address family */
sun_path: [126]c.char, /* [PSX] socket pathname */
}
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -38,10 +38,10 @@ foreign lib {
uname :: proc(uname: ^utsname) -> c.int ---
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku {
@(private)
_SYS_NAMELEN :: 256
_SYS_NAMELEN :: 32 when ODIN_OS == .Haiku else 256
utsname :: struct {
sysname: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] name of OS */

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -442,4 +442,56 @@ when ODIN_OS == .Darwin {
_WIFCONTINUED :: #force_inline proc "contextless" (x: c.int) -> bool {
return x == 0xffff
}
} else when ODIN_OS == .Haiku {
id_t :: distinct c.int32_t
WCONTINUED :: 0x04
WNOHANG :: 0x01
WUNTRACED :: 0x02
WEXITED :: 0x08
WNOWAIT :: 0x20
WSTOPPED :: 0x10
_P_ALL :: 0
_P_PID :: 1
_P_PGID :: 2
@(private)
_WIFEXITED :: #force_inline proc "contextless" (x: c.int) -> bool {
return (x & ~(c.int)(0xff)) == 0
}
@(private)
_WEXITSTATUS :: #force_inline proc "contextless" (x: c.int) -> c.int {
return x & 0xff
}
@(private)
_WIFSIGNALED :: #force_inline proc "contextless" (x: c.int) -> bool {
return ((x >> 8) & 0xff) != 0
}
@(private)
_WTERMSIG :: #force_inline proc "contextless" (x: c.int) -> Signal {
return Signal((x >> 8) & 0xff)
}
@(private)
_WIFSTOPPED :: #force_inline proc "contextless" (x: c.int) -> bool {
return ((x >> 16) & 0xff) != 0
}
@(private)
_WSTOPSIG :: #force_inline proc "contextless" (x: c.int) -> Signal {
return Signal((x >> 16) & 0xff)
}
@(private)
_WIFCONTINUED :: #force_inline proc "contextless" (x: c.int) -> bool {
return (x & 0x20000) != 0
}
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -138,17 +138,30 @@ CLocal_Flag_Bits :: enum tcflag_t {
}
CLocal_Flags :: bit_set[CLocal_Flag_Bits; tcflag_t]
CControl_Flag_Bits :: enum tcflag_t {
// CS5 = log2(CS5), /* 5 bits (pseudo) (default) */
CS6 = log2(CS6), /* 6 bits */
CS7 = log2(CS7), /* 7 bits */
CS8 = log2(CS8), /* 8 bits */
CSTOPB = log2(CSTOPB), /* send 2 stop bits */
CREAD = log2(CREAD), /* enable receiver */
PARENB = log2(PARENB), /* parity enable */
PARODD = log2(PARODD), /* odd parity, else even */
HUPCL = log2(HUPCL), /* hang up on last close */
CLOCAL = log2(CLOCAL), /* ignore modem status lines */
when ODIN_OS == .Haiku {
CControl_Flag_Bits :: enum tcflag_t {
// CS7 = log2(CS7), /* 7 bits (default) */
CS8 = log2(CS8), /* 8 bits */
CSTOPB = log2(CSTOPB), /* send 2 stop bits */
CREAD = log2(CREAD), /* enable receiver */
PARENB = log2(PARENB), /* parity enable */
PARODD = log2(PARODD), /* odd parity, else even */
HUPCL = log2(HUPCL), /* hang up on last close */
CLOCAL = log2(CLOCAL), /* ignore modem status lines */
}
} else {
CControl_Flag_Bits :: enum tcflag_t {
// CS5 = log2(CS5), /* 5 bits (pseudo) (default) */
CS6 = log2(CS6), /* 6 bits */
CS7 = log2(CS7), /* 7 bits */
CS8 = log2(CS8), /* 8 bits */
CSTOPB = log2(CSTOPB), /* send 2 stop bits */
CREAD = log2(CREAD), /* enable receiver */
PARENB = log2(PARENB), /* parity enable */
PARODD = log2(PARODD), /* odd parity, else even */
HUPCL = log2(HUPCL), /* hang up on last close */
CLOCAL = log2(CLOCAL), /* ignore modem status lines */
}
}
CControl_Flags :: bit_set[CControl_Flag_Bits; tcflag_t]
@@ -597,4 +610,151 @@ when ODIN_OS == .Darwin {
TCOOFF :: 0
TCOON :: 1
} else when ODIN_OS == .Haiku {
cc_t :: distinct c.uchar
_speed_t :: distinct c.uint32_t
tcflag_t :: distinct c.uint16_t
// Same as speed_t, but 16-bit.
CSpeed :: enum tcflag_t {
B0 = B0,
B50 = B50,
B75 = B75,
B110 = B110,
B134 = B134,
B150 = B150,
B200 = B200,
B300 = B300,
B600 = B600,
B1200 = B1200,
B1800 = B1800,
B2400 = B2400,
B4800 = B4800,
B9600 = B9600,
B19200 = B19200,
B38400 = B38400,
}
termios :: struct {
c_iflag: CInput_Flags, /* [XBD] input flags */
c_ispeed: CSpeed, /* input speed */
c_oflag: COutput_Flags, /* [XBD] output flags */
c_ospeed: CSpeed, /* output speed */
c_cflag: CControl_Flags, /* [XBD] control flags */
c_ispeed_high: tcflag_t, /* high word of input baudrate */
c_lflag: CLocal_Flags, /* [XBD] local flag */
c_ospeed_high: tcflag_t, /* high word of output baudrate */
c_line: c.char,
_padding: c.uchar,
_padding2: c.uchar,
c_cc: [NCCS]cc_t,
}
NCCS :: 11
VINTR :: 0
VQUIT :: 1
VERASE :: 2
VKILL :: 3
VEOF :: 4
VEOL :: 5
VMIN :: 4
VTIME :: 5
VEOL2 :: 6
VSWTCH :: 7
VSTART :: 8
VSTOP :: 9
VSUSP :: 10
IGNBRK :: 0x01 /* ignore break condition */
BRKINT :: 0x02 /* break sends interrupt */
IGNPAR :: 0x04 /* ignore characters with parity errors */
PARMRK :: 0x08 /* mark parity errors */
INPCK :: 0x10 /* enable input parity checking */
ISTRIP :: 0x20 /* strip high bit from characters */
INLCR :: 0x40 /* maps newline to CR on input */
IGNCR :: 0x80 /* ignore carriage returns */
ICRNL :: 0x100 /* map CR to newline on input */
IXON :: 0x400 /* enable input SW flow control */
IXANY :: 0x800 /* any character will restart input */
IXOFF :: 0x1000 /* enable output SW flow control */
OPOST :: 0x01 /* enable postprocessing of output */
ONLCR :: 0x04 /* map NL to CR-NL on output */
OCRNL :: 0x08 /* map CR to NL on output */
ONOCR :: 0x10 /* no CR output when at column 0 */
ONLRET :: 0x20 /* newline performs CR function */
OFILL :: 0x40 /* use fill characters for delays */
OFDEL :: 0x80 /* Fills are DEL, otherwise NUL */
_NLDLY :: 0x100 /* Newline delays: */
NL0 :: 0x000
NL1 :: 0x100
_CRDLY :: 0x600 /* Carriage return delays: */
CR0 :: 0x000
CR1 :: 0x200
CR2 :: 0x400
CR3 :: 0x600
_TABDLY :: 0x1800 /* Tab delays: */
TAB0 :: 0x0000
TAB1 :: 0x0800
TAB3 :: 0x1800
_BSDLY :: 0x2000 /* Backspace delays: */
BS0 :: 0x0000
BS1 :: 0x2000
_VTDLY :: 0x4000 /* Vertical tab delays: */
VT0 :: 0x0000
VT1 :: 0x4000
_FFDLY :: 0x8000 /* Form feed delays: */
FF0 :: 0x0000
FF1 :: 0x8000
B0 :: 0x00 /* hang up */
B50 :: 0x01 /* 50 baud */
B75 :: 0x02
B110 :: 0x03
B134 :: 0x04
B150 :: 0x05
B200 :: 0x06
B300 :: 0x07
B600 :: 0x08
B1200 :: 0x09
B1800 :: 0x0A
B2400 :: 0x0B
B4800 :: 0x0C
B9600 :: 0x0D
B19200 :: 0x0E
B38400 :: 0x0F
_CSIZE :: 0x20 /* character size */
//CS5 :: 0x00 /* only 7 and 8 bits supported */
//CS6 :: 0x00 /* Note, it was not very wise to set all of these */
//CS7 :: 0x00 /* to zero, but there is not much we can do about it*/
CS8 :: 0x20
CSTOPB :: 0x40 /* send 2 stop bits, not 1 */
CREAD :: 0x80 /* enable receiver */
PARENB :: 0x100 /* parity enable */
PARODD :: 0x200 /* odd parity, else even */
HUPCL :: 0x400 /* hangs up on last close */
CLOCAL :: 0x800 /* indicates local line */
ISIG :: 0x01 /* enable signals */
ICANON :: 0x02 /* Canonical input */
ECHO :: 0x08 /* Enable echo */
ECHOE :: 0x10 /* Echo erase as bs-sp-bs */
ECHOK :: 0x20 /* Echo nl after kill */
ECHONL :: 0x40 /* Echo nl */
NOFLSH :: 0x80 /* Disable flush after int or quit */
TOSTOP :: 0x100 /* stop bg processes that write to tty */
IEXTEN :: 0x200 /* implementation defined extensions */
TCIFLUSH :: 1
TCOFLUSH :: 2
TCIOFLUSH :: 3
TCIOFF :: 0x04
TCION :: 0x08
TCOOFF :: 0x01
TCOON :: 0x02
}

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -230,6 +230,17 @@ when ODIN_OS == .Darwin {
getdate_err: Errno = .ENOSYS // NOTE: looks like it's not a thing on OpenBSD.
} else when ODIN_OS == .Haiku {
clockid_t :: distinct c.int32_t
CLOCK_MONOTONIC :: 0
CLOCK_PROCESS_CPUTIME_ID :: -2
CLOCK_REALTIME :: -1
CLOCK_THREAD_CPUTIME_ID :: -3
getdate_err: Errno = .ENOSYS // NOTE: looks like it's not a thing on Haiku.
} else when ODIN_OS == .Linux {
clockid_t :: distinct c.int

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"
@@ -1852,7 +1852,7 @@ when ODIN_OS == .Darwin {
_PC_ALLOC_SIZE_MIN :: 19
_PC_SYMLINK_MAX :: 20
_PC_2_SYMLINK :: 21
_SC_ARG_MAX :: 1
_SC_CHILD_MAX :: 2
_SC_CLK_TCK :: 3
@@ -1992,4 +1992,174 @@ when ODIN_OS == .Darwin {
// NOTE: Not implemented.
_POSIX_VDISABLE :: 0
} else when ODIN_OS == .Haiku {
_F_OK :: 0
X_OK :: 1
W_OK :: 2
R_OK :: 4
F_LOCK :: 1
F_TEST :: 3
F_TLOCK :: 2
F_ULOCK :: 0
_CS_PATH :: 1
_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 0 // Undefined.
_CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 0 // Undefined.
_CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 0 // Undefined.
_CS_POSIX_V6_ILP32_OFF32_LIBS :: 0 // Undefined.
_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 0 // Undefined.
_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 0 // Undefined.
_CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 0 // Undefined.
_CS_POSIX_V6_LP64_OFF64_CFLAGS :: 0 // Undefined.
_CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 0 // Undefined.
_CS_POSIX_V6_LP64_OFF64_LIBS :: 0 // Undefined.
_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 0 // Undefined.
_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 0 // Undefined.
_CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 0 // Undefined.
_SC_ASYNCHRONOUS_IO :: 0 // Undefined.
_SC_RAW_SOCKETS :: 0 // Undefined.
_SC_SS_REPL_MAX :: 0 // Undefined.
_SC_TRACE_EVENT_NAME_MAX :: 0 // Undefined.
_SC_TRACE_NAME_MAX :: 0 // Undefined.
_SC_TRACE_SYS_MAX :: 0 // Undefined.
_SC_TRACE_USER_EVENT_MAX :: 0 // Undefined.
_PC_CHOWN_RESTRICTED :: 1
_PC_MAX_CANON :: 2
_PC_MAX_INPUT :: 3
_PC_NAME_MAX :: 4
_PC_NO_TRUNC :: 5
_PC_PATH_MAX :: 6
_PC_PIPE_BUF :: 7
_PC_VDISABLE :: 8
_PC_LINK_MAX :: 25
_PC_SYNC_IO :: 26
_PC_ASYNC_IO :: 27
_PC_PRIO_IO :: 28
_PC_FILESIZEBITS :: 30
_PC_REC_INCR_XFER_SIZE :: 31
_PC_REC_MAX_XFER_SIZE :: 32
_PC_REC_MIN_XFER_SIZE :: 33
_PC_REC_XFER_ALIGN :: 34
_PC_ALLOC_SIZE_MIN :: 35
_PC_SYMLINK_MAX :: 36
_PC_2_SYMLINK :: 37
_SC_ARG_MAX :: 15
_SC_CHILD_MAX :: 16
_SC_CLK_TCK :: 17
_SC_JOB_CONTROL :: 18
_SC_NGROUPS_MAX :: 19
_SC_OPEN_MAX :: 20
_SC_SAVED_IDS :: 21
_SC_STREAM_MAX :: 22
_SC_TZNAME_MAX :: 23
_SC_VERSION :: 24
_SC_GETGR_R_SIZE_MAX :: 25
_SC_GETPW_R_SIZE_MAX :: 26
_SC_PAGE_SIZE :: 27
_SC_PAGESIZE :: _SC_PAGE_SIZE
_SC_SEM_NSEMS_MAX :: 28
_SC_SEM_VALUE_MAX :: 29
_SC_SEMAPHORES :: 30
_SC_THREADS :: 31
_SC_IOV_MAX :: 32
_SC_NPROCESSORS_CONF :: 34
_SC_NPROCESSORS_ONLN :: 35
_SC_ATEXIT_MAX :: 37
_SC_MAPPED_FILES :: 45
_SC_THREAD_PROCESS_SHARED :: 46
_SC_THREAD_STACK_MIN :: 47
_SC_THREAD_ATTR_STACKADDR :: 48
_SC_THREAD_ATTR_STACKSIZE :: 49
_SC_THREAD_PRIORITY_SCHEDULING :: 50
_SC_REALTIME_SIGNALS :: 51
_SC_MEMORY_PROTECTION :: 52
_SC_SIGQUEUE_MAX :: 53
_SC_RTSIG_MAX :: 54
_SC_MONOTONIC_CLOCK :: 55
_SC_DELAYTIMER_MAX :: 56
_SC_TIMER_MAX :: 57
_SC_TIMERS :: 58
_SC_CPUTIME :: 59
_SC_THREAD_CPUTIME :: 60
_SC_HOST_NAME_MAX :: 61
_SC_REGEXP :: 62
_SC_SYMLOOP_MAX :: 63
_SC_SHELL :: 64
_SC_TTY_NAME_MAX :: 65
_SC_ADVISORY_INFO :: 66
_SC_BARRIERS :: 67
_SC_CLOCK_SELECTION :: 68
_SC_FSYNC :: 69
_SC_IPV6 :: 70
_SC_MEMLOCK :: 71
_SC_MEMLOCK_RANGE :: 72
_SC_MESSAGE_PASSING :: 73
_SC_PRIORITIZED_IO :: 74
_SC_PRIORITY_SCHEDULING :: 75
_SC_READER_WRITER_LOCKS :: 76
_SC_SHARED_MEMORY_OBJECTS :: 77
_SC_SPAWN :: 78
_SC_SPIN_LOCKS :: 79
_SC_SPORADIC_SERVER :: 80
_SC_SYNCHRONIZED_IO :: 81
_SC_THREAD_PRIO_INHERIT :: 82
_SC_THREAD_PRIO_PROTECT :: 83
_SC_THREAD_SAFE_FUNCTIONS :: 86
_SC_THREAD_SPORADIC_SERVER :: 87
_SC_TIMEOUTS :: 88
_SC_TRACE :: 89
_SC_TRACE_EVENT_FILTER :: 90
_SC_TRACE_INHERIT :: 91
_SC_TRACE_LOG :: 92
_SC_TYPED_MEMORY_OBJECTS :: 93
_SC_V6_ILP32_OFF32 :: 94
_SC_V6_ILP32_OFFBIG :: 95
_SC_V6_LP64_OFF64 :: 96
_SC_V6_LPBIG_OFFBIG :: 97
_SC_2_C_BIND :: 102
_SC_2_C_DEV :: 103
_SC_2_CHAR_TERM :: 104
_SC_2_FORT_DEV :: 105
_SC_2_FORT_RUN :: 106
_SC_2_LOCALEDEF :: 107
_SC_2_PBS :: 108
_SC_2_PBS_ACCOUNTING :: 109
_SC_2_PBS_CHECKPOINT :: 110
_SC_2_PBS_LOCATE :: 111
_SC_2_PBS_MESSAGE :: 112
_SC_2_PBS_TRACK :: 113
_SC_2_SW_DEV :: 114
_SC_2_UPE :: 115
_SC_2_VERSION :: 116
_SC_XOPEN_CRYPT :: 117
_SC_XOPEN_ENH_I18N :: 118
_SC_XOPEN_REALTIME :: 119
_SC_XOPEN_REALTIME_THREADS :: 120
_SC_XOPEN_SHM :: 121
_SC_XOPEN_STREAMS :: 122
_SC_XOPEN_UNIX :: 123
_SC_XOPEN_VERSION :: 125
_SC_AIO_LISTIO_MAX :: 126
_SC_AIO_MAX :: 127
_SC_AIO_PRIO_DELTA_MAX :: 128
_SC_BC_BASE_MAX :: 129
_SC_BC_DIM_MAX :: 130
_SC_BC_SCALE_MAX :: 131
_SC_BC_STRING_MAX :: 132
_SC_COLL_WEIGHTS_MAX :: 133
_SC_EXPR_NEST_MAX :: 134
_SC_LINE_MAX :: 135
_SC_LOGIN_NAME_MAX :: 136
_SC_MQ_OPEN_MAX :: 137
_SC_MQ_PRIO_MAX :: 138
_SC_THREAD_DESTRUCTOR_ITERATIONS :: 139
_SC_THREAD_KEYS_MAX :: 140
_SC_THREAD_THREADS_MAX :: 141
_SC_RE_DUP_MAX :: 142
}

View File

@@ -1,4 +1,4 @@
#+build linux, windows, darwin, netbsd, openbsd, freebsd
#+build linux, windows, darwin, netbsd, openbsd, freebsd, haiku
package posix
import "core:c"

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
package posix
when ODIN_OS == .Darwin {
@@ -25,7 +25,7 @@ when ODIN_OS == .NetBSD {
@(private) LUTIME :: "utime"
}
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
utimbuf :: struct {
actime: time_t, /* [PSX] access time (seconds since epoch) */

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
#+build linux, darwin, netbsd, openbsd, freebsd, haiku
#+private
package testing

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, freebsd, openbsd, netbsd
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
package tests_core_posix
import "core:log"
@@ -65,8 +65,17 @@ test_dirent :: proc(t: ^testing.T) {
for entry in entries {
defer posix.free(entry)
if entry.d_type != .REG {
continue
when ODIN_OS == .Haiku {
stat: posix.stat_t
posix.stat(cstring(raw_data(entry.d_name[:])), &stat)
if !posix.S_ISREG(stat.st_mode) {
continue
}
} else {
if entry.d_type != .REG {
continue
}
}
name := string(cstring(raw_data(entry.d_name[:])))
@@ -86,8 +95,17 @@ test_dirent :: proc(t: ^testing.T) {
break
}
if entry.d_type != .REG {
continue
when ODIN_OS == .Haiku {
stat: posix.stat_t
posix.stat(cstring(raw_data(entry.d_name[:])), &stat)
if !posix.S_ISREG(stat.st_mode) {
continue
}
} else {
if entry.d_type != .REG {
continue
}
}
name := string(cstring(raw_data(entry.d_name[:])))
@@ -140,15 +158,15 @@ test_langinfo :: proc(t: ^testing.T) {
@(test)
test_libgen :: proc(t: ^testing.T) {
tests := [][3]cstring{
{ "usr", ".", "usr" },
{ "usr/", ".", "usr" },
{ "", ".", "." },
{ "/", "/", "/" },
{ "///", "/", "/" },
{ "/usr/", "/", "usr" },
{ "/usr/lib", "/usr", "lib" },
{ "//usr//lib//", "//usr", "lib" },
{ "/home//dwc//test", "/home//dwc", "test" },
{ "usr", ".", "usr" },
{ "usr/", ".", "usr" },
{ "", ".", "." },
{ "/", "/", "/" },
{ "///", "/", "/" },
{ "/usr/", "/", "usr" },
{ "/usr/lib", "/usr", "lib" },
{ "//usr//lib//", "//usr" + ("/" when ODIN_OS == .Haiku else ""), "lib" },
{ "/home//dwc//test", "/home//dwc" + ("/" when ODIN_OS == .Haiku else ""), "test" },
}
for test in tests {

View File

@@ -1,4 +1,4 @@
#+build linux, darwin, freebsd, openbsd, netbsd
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
package tests_core_posix
import "core:log"

View File

@@ -10,7 +10,11 @@
#include <netdb.h>
#include <poll.h>
#include <pwd.h>
#ifndef __HAIKU__
#include <sys/shm.h>
#endif
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/un.h>
@@ -25,7 +29,11 @@
#include <sys/statvfs.h>
#include <sys/time.h>
#include <utime.h>
#ifndef __HAIKU__
#include <wordexp.h>
#endif
#include <sys/socket.h>
int main(int argc, char *argv[])
@@ -67,7 +75,10 @@ int main(int argc, char *argv[])
printf("passwd %zu %zu\n", sizeof(struct passwd), _Alignof(struct passwd));
#ifndef __HAIKU__
printf("shmid_ds %zu %zu\n", sizeof(struct shmid_ds), _Alignof(struct shmid_ds));
#endif
printf("ipc_perm %zu %zu\n", sizeof(struct ipc_perm), _Alignof(struct ipc_perm));
printf("msqid_ds %zu %zu\n", sizeof(struct msqid_ds), _Alignof(struct msqid_ds));
@@ -95,7 +106,9 @@ int main(int argc, char *argv[])
printf("utimbuf %zu %zu\n", sizeof(struct utimbuf), _Alignof(struct utimbuf));
#ifndef __HAIKU__
printf("wordexp_t %zu %zu\n", sizeof(wordexp_t), _Alignof(wordexp_t));
#endif
printf("time_t %zu %zu\n", sizeof(time_t), _Alignof(time_t));
printf("timespec %zu %zu\n", sizeof(struct timespec), _Alignof(struct timespec));

View File

@@ -42,7 +42,10 @@ main :: proc() {
fmt.println("pollfd", size_of(posix.pollfd), align_of(posix.pollfd))
fmt.println("passwd", size_of(posix.passwd), align_of(posix.passwd))
fmt.println("shmid_ds", size_of(posix.shmid_ds), align_of(posix.shmid_ds))
when ODIN_OS != .Haiku {
fmt.println("shmid_ds", size_of(posix.shmid_ds), align_of(posix.shmid_ds))
}
fmt.println("ipc_perm", size_of(posix.ipc_perm), align_of(posix.ipc_perm))
fmt.println("msqid_ds", size_of(posix.msqid_ds), align_of(posix.msqid_ds))
@@ -70,8 +73,10 @@ main :: proc() {
fmt.println("utimbuf", size_of(posix.utimbuf), align_of(posix.utimbuf))
fmt.println("wordexp_t", size_of(posix.wordexp_t), align_of(posix.wordexp_t))
when ODIN_OS != .Haiku {
fmt.println("wordexp_t", size_of(posix.wordexp_t), align_of(posix.wordexp_t))
}
fmt.println("time_t", size_of(posix.time_t), align_of(posix.time_t))
fmt.println("timespec", size_of(posix.timespec), align_of(posix.timespec))
fmt.println("clock_t", size_of(posix.clock_t), align_of(posix.clock_t))