diff --git a/build_odin.sh b/build_odin.sh index 3547689d5..09094c151 100755 --- a/build_odin.sh +++ b/build_odin.sh @@ -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)" ;; diff --git a/core/c/libc/errno.odin b/core/c/libc/errno.odin index de429a6ec..5d1ca8248 100644 --- a/core/c/libc/errno.odin +++ b/core/c/libc/errno.odin @@ -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 { diff --git a/core/c/libc/locale.odin b/core/c/libc/locale.odin index 371d755c5..d95f5c164 100644 --- a/core/c/libc/locale.odin +++ b/core/c/libc/locale.odin @@ -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 diff --git a/core/os/os_haiku.odin b/core/os/os_haiku.odin index 4ad370724..d44ca9df0 100644 --- a/core/os/os_haiku.odin +++ b/core/os/os_haiku.odin @@ -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 @@ -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 --- @@ -203,7 +204,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() } diff --git a/core/os/stat_unix.odin b/core/os/stat_unix.odin index 7f7985e83..648987a07 100644 --- a/core/os/stat_unix.odin +++ b/core/os/stat_unix.odin @@ -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, } } diff --git a/core/sync/futex_haiku.odin b/core/sync/futex_haiku.odin index 21d07b801..d1b265228 100644 --- a/core/sync/futex_haiku.odin +++ b/core/sync/futex_haiku.odin @@ -1,14 +1,12 @@ #+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 +56,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 +65,25 @@ _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 + posix.sigwait(&mask, &sig) + errno := posix.errno() + 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 + posix.sigtimedwait(&mask, &info, &ts) + 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) } } } diff --git a/core/sys/haiku/errno.odin b/core/sys/haiku/errno.odin new file mode 100644 index 000000000..2b5e3681c --- /dev/null +++ b/core/sys/haiku/errno.odin @@ -0,0 +1,217 @@ +#+build haiku +package sys_haiku + +import "core:sys/posix" + +foreign import libroot "system:c" + +Errno :: enum i32 { + // 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, + + // General Errors + NO_MEMORY = GENERAL_ERROR_BASE + 0, + IO_ERROR = GENERAL_ERROR_BASE + 1, + PERMISSION_DENIED = GENERAL_ERROR_BASE + 2, + BAD_INDEX = GENERAL_ERROR_BASE + 3, + BAD_TYPE = GENERAL_ERROR_BASE + 4, + BAD_VALUE = GENERAL_ERROR_BASE + 5, + MISMATCHED_VALUES = GENERAL_ERROR_BASE + 6, + NAME_NOT_FOUND = GENERAL_ERROR_BASE + 7, + NAME_IN_USE = GENERAL_ERROR_BASE + 8, + TIMED_OUT = GENERAL_ERROR_BASE + 9, + INTERRUPTED = GENERAL_ERROR_BASE + 10, + WOULD_BLOCK = GENERAL_ERROR_BASE + 11, + CANCELED = GENERAL_ERROR_BASE + 12, + NO_INIT = GENERAL_ERROR_BASE + 13, + NOT_INITIALIZED = GENERAL_ERROR_BASE + 13, + BUSY = GENERAL_ERROR_BASE + 14, + NOT_ALLOWED = GENERAL_ERROR_BASE + 15, + BAD_DATA = GENERAL_ERROR_BASE + 16, + DONT_DO_THAT = GENERAL_ERROR_BASE + 17, + + ERROR = -1, + OK = 0, + NO_ERROR = 0, + + // Kernel Kit Errors + BAD_SEM_ID = OS_ERROR_BASE + 0, + NO_MORE_SEMS = OS_ERROR_BASE + 1, + BAD_THREAD_ID = OS_ERROR_BASE + 0x100, + NO_MORE_THREADS = OS_ERROR_BASE + 0x101, + BAD_THREAD_STATE = OS_ERROR_BASE + 0x102, + BAD_TEAM_ID = OS_ERROR_BASE + 0x103, + NO_MORE_TEAMS = OS_ERROR_BASE + 0x104, + BAD_PORT_ID = OS_ERROR_BASE + 0x200, + NO_MORE_PORTS = OS_ERROR_BASE + 0x201, + BAD_IMAGE_ID = OS_ERROR_BASE + 0x300, + BAD_ADDRESS = OS_ERROR_BASE + 0x301, + NOT_AN_EXECUTABLE = OS_ERROR_BASE + 0x302, + MISSING_LIBRARY = OS_ERROR_BASE + 0x303, + MISSING_SYMBOL = OS_ERROR_BASE + 0x304, + UNKNOWN_EXECUTABLE = OS_ERROR_BASE + 0x305, + LEGACY_EXECUTABLE = OS_ERROR_BASE + 0x306, + + DEBUGGER_ALREADY_INSTALLED = OS_ERROR_BASE + 0x400, + + // Application Kit Errors + BAD_REPLY = APP_ERROR_BASE + 0, + DUPLICATE_REPLY = APP_ERROR_BASE + 1, + MESSAGE_TO_SELF = APP_ERROR_BASE + 2, + BAD_HANDLER = APP_ERROR_BASE + 3, + ALREADY_RUNNING = APP_ERROR_BASE + 4, + LAUNCH_FAILED = APP_ERROR_BASE + 5, + AMBIGUOUS_APP_LAUNCH = APP_ERROR_BASE + 6, + UNKNOWN_MIME_TYPE = APP_ERROR_BASE + 7, + BAD_SCRIPT_SYNTAX = APP_ERROR_BASE + 8, + LAUNCH_FAILED_NO_RESOLVE_LINK = APP_ERROR_BASE + 9, + LAUNCH_FAILED_EXECUTABLE = APP_ERROR_BASE + 10, + LAUNCH_FAILED_APP_NOT_FOUND = APP_ERROR_BASE + 11, + LAUNCH_FAILED_APP_IN_TRASH = APP_ERROR_BASE + 12, + LAUNCH_FAILED_NO_PREFERRED_APP = APP_ERROR_BASE + 13, + LAUNCH_FAILED_FILES_APP_NOT_FOUND = APP_ERROR_BASE + 14, + BAD_MIME_SNIFFER_RULE = APP_ERROR_BASE + 15, + NOT_A_MESSAGE = APP_ERROR_BASE + 16, + SHUTDOWN_CANCELLED = APP_ERROR_BASE + 17, + SHUTTING_DOWN = APP_ERROR_BASE + 18, + + // Storage Kit/File System Errors + FILE_ERROR = STORAGE_ERROR_BASE + 0, + // 1 was B_FILE_NOT_FOUND (deprecated) + FILE_EXISTS = STORAGE_ERROR_BASE + 2, + ENTRY_NOT_FOUND = STORAGE_ERROR_BASE + 3, + NAME_TOO_LONG = STORAGE_ERROR_BASE + 4, + NOT_A_DIRECTORY = STORAGE_ERROR_BASE + 5, + DIRECTORY_NOT_EMPTY = STORAGE_ERROR_BASE + 6, + DEVICE_FULL = STORAGE_ERROR_BASE + 7, + READ_ONLY_DEVICE = STORAGE_ERROR_BASE + 8, + IS_A_DIRECTORY = STORAGE_ERROR_BASE + 9, + NO_MORE_FDS = STORAGE_ERROR_BASE + 10, + CROSS_DEVICE_LINK = STORAGE_ERROR_BASE + 11, + LINK_LIMIT = STORAGE_ERROR_BASE + 12, + BUSTED_PIPE = STORAGE_ERROR_BASE + 13, + UNSUPPORTED = STORAGE_ERROR_BASE + 14, + PARTITION_TOO_SMALL = STORAGE_ERROR_BASE + 15, + PARTIAL_READ = STORAGE_ERROR_BASE + 16, + PARTIAL_WRITE = STORAGE_ERROR_BASE + 17, + + // New error codes that can be mapped to POSIX errors + TOO_MANY_ARGS = posix.E2BIG, + FILE_TOO_LARGE = posix.EFBIG, + DEVICE_NOT_FOUND = posix.ENODEV, + RESULT_NOT_REPRESENTABLE = posix.ERANGE, + BUFFER_OVERFLOW = posix.EOVERFLOW, + NOT_SUPPORTED = posix.EOPNOTSUPP, + + // Media Kit Errors + STREAM_NOT_FOUND = MEDIA_ERROR_BASE + 0, + SERVER_NOT_FOUND = MEDIA_ERROR_BASE + 1, + RESOURCE_NOT_FOUND = MEDIA_ERROR_BASE + 2, + RESOURCE_UNAVAILABLE = MEDIA_ERROR_BASE + 3, + BAD_SUBSCRIBER = MEDIA_ERROR_BASE + 4, + SUBSCRIBER_NOT_ENTERED = MEDIA_ERROR_BASE + 5, + BUFFER_NOT_AVAILABLE = MEDIA_ERROR_BASE + 6, + LAST_BUFFER_ERROR = MEDIA_ERROR_BASE + 7, + MEDIA_SYSTEM_FAILURE = MEDIA_ERROR_BASE + 100, + MEDIA_BAD_NODE = MEDIA_ERROR_BASE + 101, + MEDIA_NODE_BUSY = MEDIA_ERROR_BASE + 102, + MEDIA_BAD_FORMAT = MEDIA_ERROR_BASE + 103, + MEDIA_BAD_BUFFER = MEDIA_ERROR_BASE + 104, + MEDIA_TOO_MANY_NODES = MEDIA_ERROR_BASE + 105, + MEDIA_TOO_MANY_BUFFERS = MEDIA_ERROR_BASE + 106, + MEDIA_NODE_ALREADY_EXISTS = MEDIA_ERROR_BASE + 107, + MEDIA_BUFFER_ALREADY_EXISTS = MEDIA_ERROR_BASE + 108, + MEDIA_CANNOT_SEEK = MEDIA_ERROR_BASE + 109, + MEDIA_CANNOT_CHANGE_RUN_MODE = MEDIA_ERROR_BASE + 110, + MEDIA_APP_ALREADY_REGISTERED = MEDIA_ERROR_BASE + 111, + MEDIA_APP_NOT_REGISTERED = MEDIA_ERROR_BASE + 112, + MEDIA_CANNOT_RECLAIM_BUFFERS = MEDIA_ERROR_BASE + 113, + MEDIA_BUFFERS_NOT_RECLAIMED = MEDIA_ERROR_BASE + 114, + MEDIA_TIME_SOURCE_STOPPED = MEDIA_ERROR_BASE + 115, + MEDIA_TIME_SOURCE_BUSY = MEDIA_ERROR_BASE + 116, + MEDIA_BAD_SOURCE = MEDIA_ERROR_BASE + 117, + MEDIA_BAD_DESTINATION = MEDIA_ERROR_BASE + 118, + MEDIA_ALREADY_CONNECTED = MEDIA_ERROR_BASE + 119, + MEDIA_NOT_CONNECTED = MEDIA_ERROR_BASE + 120, + MEDIA_BAD_CLIP_FORMAT = MEDIA_ERROR_BASE + 121, + MEDIA_ADDON_FAILED = MEDIA_ERROR_BASE + 122, + MEDIA_ADDON_DISABLED = MEDIA_ERROR_BASE + 123, + MEDIA_CHANGE_IN_PROGRESS = MEDIA_ERROR_BASE + 124, + MEDIA_STALE_CHANGE_COUNT = MEDIA_ERROR_BASE + 125, + MEDIA_ADDON_RESTRICTED = MEDIA_ERROR_BASE + 126, + MEDIA_NO_HANDLER = MEDIA_ERROR_BASE + 127, + MEDIA_DUPLICATE_FORMAT = MEDIA_ERROR_BASE + 128, + MEDIA_REALTIME_DISABLED = MEDIA_ERROR_BASE + 129, + MEDIA_REALTIME_UNAVAILABLE = MEDIA_ERROR_BASE + 130, + + // Mail Kit Errors + MAIL_NO_DAEMON = MAIL_ERROR_BASE + 0, + MAIL_UNKNOWN_USER = MAIL_ERROR_BASE + 1, + MAIL_WRONG_PASSWORD = MAIL_ERROR_BASE + 2, + MAIL_UNKNOWN_HOST = MAIL_ERROR_BASE + 3, + MAIL_ACCESS_ERROR = MAIL_ERROR_BASE + 4, + MAIL_UNKNOWN_FIELD = MAIL_ERROR_BASE + 5, + MAIL_NO_RECIPIENT = MAIL_ERROR_BASE + 6, + MAIL_INVALID_MAIL = MAIL_ERROR_BASE + 7, + + // Printing Errors + NO_PRINT_SERVER = PRINT_ERROR_BASE + 0, + + // Device Kit Errors + DEV_INVALID_IOCTL = DEVICE_ERROR_BASE + 0, + DEV_NO_MEMORY = DEVICE_ERROR_BASE + 1, + DEV_BAD_DRIVE_NUM = DEVICE_ERROR_BASE + 2, + DEV_NO_MEDIA = DEVICE_ERROR_BASE + 3, + DEV_UNREADABLE = DEVICE_ERROR_BASE + 4, + DEV_FORMAT_ERROR = DEVICE_ERROR_BASE + 5, + DEV_TIMEOUT = DEVICE_ERROR_BASE + 6, + DEV_RECALIBRATE_ERROR = DEVICE_ERROR_BASE + 7, + DEV_SEEK_ERROR = DEVICE_ERROR_BASE + 8, + DEV_ID_ERROR = DEVICE_ERROR_BASE + 9, + DEV_READ_ERROR = DEVICE_ERROR_BASE + 10, + DEV_WRITE_ERROR = DEVICE_ERROR_BASE + 11, + DEV_NOT_READY = DEVICE_ERROR_BASE + 12, + DEV_MEDIA_CHANGED = DEVICE_ERROR_BASE + 13, + DEV_MEDIA_CHANGE_REQUESTED = DEVICE_ERROR_BASE + 14, + DEV_RESOURCE_CONFLICT = DEVICE_ERROR_BASE + 15, + DEV_CONFIGURATION_ERROR = DEVICE_ERROR_BASE + 16, + DEV_DISABLED_BY_USER = DEVICE_ERROR_BASE + 17, + DEV_DOOR_OPEN = DEVICE_ERROR_BASE + 18, + DEV_INVALID_PIPE = DEVICE_ERROR_BASE + 19, + DEV_CRC_ERROR = DEVICE_ERROR_BASE + 20, + DEV_STALLED = DEVICE_ERROR_BASE + 21, + DEV_BAD_PID = DEVICE_ERROR_BASE + 22, + DEV_UNEXPECTED_PID = DEVICE_ERROR_BASE + 23, + DEV_DATA_OVERRUN = DEVICE_ERROR_BASE + 24, + DEV_DATA_UNDERRUN = DEVICE_ERROR_BASE + 25, + DEV_FIFO_OVERRUN = DEVICE_ERROR_BASE + 26, + DEV_FIFO_UNDERRUN = DEVICE_ERROR_BASE + 27, + DEV_PENDING = DEVICE_ERROR_BASE + 28, + DEV_MULTIPLE_ERRORS = DEVICE_ERROR_BASE + 29, + DEV_TOO_LATE = DEVICE_ERROR_BASE + 30, + + // Translation Kit Errors + TRANSLATION_BASE_ERROR = TRANSLATION_ERROR_BASE + 0, + NO_TRANSLATOR = TRANSLATION_ERROR_BASE + 1, + ILLEGAL_DATA = TRANSLATION_ERROR_BASE + 2, +} + +@(default_calling_convention="c") +foreign libroot { + _to_positive_error :: proc(error: i32) -> i32 --- + _to_negative_error :: proc(error: i32) -> i32 --- +} diff --git a/core/sys/haiku/find_directory.odin b/core/sys/haiku/find_directory.odin index 758c4dff4..917394f48 100644 --- a/core/sys/haiku/find_directory.odin +++ b/core/sys/haiku/find_directory.odin @@ -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: uintptr) -> 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: uintptr) -> status_t --- + find_path_for_path :: proc(path: cstring, baseDirectory: path_base_directory, subPath: cstring, pathBuffer: [^]byte, bufferSize: uintptr) -> 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: uintptr) -> status_t --- + find_paths :: proc(baseDirectory: path_base_directory, subPath: cstring, _paths: ^[^][^]byte, _pathCount: ^uintptr) -> status_t --- + find_paths_etc :: proc(architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, _paths: ^[^][^]byte, _pathCount: ^uintptr) -> status_t --- } diff --git a/core/sys/haiku/os.odin b/core/sys/haiku/os.odin index 6ab3ef573..a9c5ea57d 100644 --- a/core/sys/haiku/os.odin +++ b/core/sys/haiku/os.odin @@ -1,8 +1,8 @@ #+build haiku package sys_haiku +import "base:intrinsics" import "core:c" -import "core:sys/unix" 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: uintptr, 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: uintptr, 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: uintptr) -> 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: uintptr) -> status_t --- + _get_next_area_info :: proc(team: team_id, cookie: ^c.ssize_t, areaInfo: ^area_info, size: uintptr) -> 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: uintptr) -> c.ssize_t --- + read_port_etc :: proc(port: port_id, code: ^i32, buffer: rawptr, bufferSize: uintptr, flags: port_flags, timeout: bigtime_t) -> c.ssize_t --- + write_port :: proc(port: port_id, code: i32, buffer: rawptr, bufferSize: uintptr) -> status_t --- + write_port_etc :: proc(port: port_id, code: i32, buffer: rawptr, bufferSize: uintptr, 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 --- 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: uintptr) -> status_t --- + _get_next_port_info :: proc(team: team_id, cookie: ^i32, portInfo: ^port_info, portInfoSize: uintptr) -> 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: uintptr) -> status_t --- + _get_next_sem_info :: proc(team: team_id, cookie: ^i32, info: ^sem_info, infoSize: uintptr) -> 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: uintptr) -> status_t --- + _get_next_team_info :: proc(cookie: ^i32, info: ^team_info, size: uintptr) -> status_t --- + _get_team_usage_info :: proc(id: team_id, who: team_usage_who, info: ^team_usage_info, size: uintptr) -> 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: uintptr) -> status_t --- + receive_data :: proc(sender: ^thread_id, buffer: rawptr, bufferSize: uintptr) -> 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: uintptr) -> status_t --- + _get_next_thread_info :: proc(team: team_id, cookie: ^i32, info: ^thread_info, size: uintptr) -> 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,68 @@ 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: uintptr) -> 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 --- -} - -// 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 -} - -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 --- - - send_signal :: proc(threadID: thread_id, signal: c.uint) -> c.int --- - set_signal_stack :: proc(base: rawptr, size: c.size_t) --- + when ODIN_ARCH == .amd64 || ODIN_ARCH == .i386 { + get_cpuid :: proc(info: ^cpuid_info, eaxRegister: u32, cpuNum: u32) -> status_t --- + } + + is_computer_on :: proc() -> i32 --- + is_computer_on_fire :: proc() -> f64 --- } diff --git a/core/sys/haiku/types.odin b/core/sys/haiku/types.odin index 47755b0b7..f15ffb00d 100644 --- a/core/sys/haiku/types.odin +++ b/core/sys/haiku/types.odin @@ -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 diff --git a/core/sys/posix/errno.odin b/core/sys/posix/errno.odin index 9bc77f12e..bb4e9e045 100644 --- a/core/sys/posix/errno.odin +++ b/core/sys/posix/errno.odin @@ -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) } diff --git a/core/sys/posix/fcntl.odin b/core/sys/posix/fcntl.odin index d948af600..bc0b5b5ba 100644 --- a/core/sys/posix/fcntl.odin +++ b/core/sys/posix/fcntl.odin @@ -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 diff --git a/core/sys/posix/grp.odin b/core/sys/posix/grp.odin index 956ed148b..3694308a0 100644 --- a/core/sys/posix/grp.odin +++ b/core/sys/posix/grp.odin @@ -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 diff --git a/core/sys/posix/pthread.odin b/core/sys/posix/pthread.odin index 490064da6..36a3cd7b3 100644 --- a/core/sys/posix/pthread.odin +++ b/core/sys/posix/pthread.odin @@ -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 diff --git a/core/sys/posix/sched.odin b/core/sys/posix/sched.odin index e91178b09..82b335653 100644 --- a/core/sys/posix/sched.odin +++ b/core/sys/posix/sched.odin @@ -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 + } diff --git a/core/sys/posix/signal.odin b/core/sys/posix/signal.odin index 4ba4e9943..d43270410 100644 --- a/core/sys/posix/signal.odin +++ b/core/sys/posix/signal.odin @@ -1,4 +1,4 @@ -#+build linux, darwin, netbsd, openbsd, freebsd +#+build linux, darwin, netbsd, openbsd, freebsd, haiku package posix import "base:intrinsics" @@ -185,6 +185,16 @@ foreign lib { */ sigwait :: proc(set: ^sigset_t, sig: ^Signal) -> Errno --- + when ODIN_OS != .Darwin { + /* + Wait for queued signals. + + [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigtimedwait.html ]] + */ + sigtimedwait :: proc(set: ^sigset_t, info: ^siginfo_t, timeout: ^timespec) -> result --- + } + + /* NOTE: unimplemented on darwin. void psiginfo(const siginfo_t *, const char *); @@ -1180,4 +1190,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 */ + } diff --git a/core/sys/posix/signal_libc.odin b/core/sys/posix/signal_libc.odin index aef22da29..7a054ddd7 100644 --- a/core/sys/posix/signal_libc.odin +++ b/core/sys/posix/signal_libc.odin @@ -1,4 +1,4 @@ -#+build linux, windows, darwin, netbsd, openbsd, freebsd +#+build linux, windows, darwin, netbsd, openbsd, freebsd, haiku package posix import "base:intrinsics" diff --git a/core/sys/posix/sys_stat.odin b/core/sys/posix/sys_stat.odin index 61b98ef35..265356e54 100644 --- a/core/sys/posix/sys_stat.odin +++ b/core/sys/posix/sys_stat.odin @@ -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 diff --git a/core/sys/posix/time.odin b/core/sys/posix/time.odin index f9c51c63c..88f0153f4 100644 --- a/core/sys/posix/time.odin +++ b/core/sys/posix/time.odin @@ -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