aboutsummaryrefslogtreecommitdiff
path: root/core/sys
diff options
context:
space:
mode:
authorColin Davidson <colrdavidson@gmail.com>2024-11-20 15:51:08 -0800
committerColin Davidson <colrdavidson@gmail.com>2024-11-20 15:51:08 -0800
commitd60fb5a44e4d2e371562fd38947f8125b06bceb9 (patch)
tree4e924ee102c2af7b30d29017ab716ed00c51ab26 /core/sys
parentf3ab14b8ccb45d0fef8a96937635bdf0943ce7d6 (diff)
parent3229f4668dfaa5f43a374bc549f42661b002699d (diff)
update to master
Diffstat (limited to 'core/sys')
-rw-r--r--core/sys/darwin/Foundation/NSApplication.odin10
-rw-r--r--core/sys/darwin/mach_darwin.odin514
-rw-r--r--core/sys/info/cpu_intel.odin47
-rw-r--r--core/sys/info/platform_darwin.odin16
-rw-r--r--core/sys/linux/bits.odin127
-rw-r--r--core/sys/linux/constants.odin25
-rw-r--r--core/sys/linux/sys.odin25
-rw-r--r--core/sys/linux/types.odin23
-rw-r--r--core/sys/posix/arpa_inet.odin1
-rw-r--r--core/sys/posix/dirent.odin87
-rw-r--r--core/sys/posix/dlfcn.odin12
-rw-r--r--core/sys/posix/errno.odin183
-rw-r--r--core/sys/posix/fcntl.odin152
-rw-r--r--core/sys/posix/fnmatch.odin11
-rw-r--r--core/sys/posix/glob.odin36
-rw-r--r--core/sys/posix/grp.odin5
-rw-r--r--core/sys/posix/iconv.odin1
-rw-r--r--core/sys/posix/langinfo.odin89
-rw-r--r--core/sys/posix/libgen.odin8
-rw-r--r--core/sys/posix/limits.odin98
-rw-r--r--core/sys/posix/locale.odin94
-rw-r--r--core/sys/posix/monetary.odin1
-rw-r--r--core/sys/posix/net_if.odin5
-rw-r--r--core/sys/posix/netdb.odin39
-rw-r--r--core/sys/posix/netinet_in.odin93
-rw-r--r--core/sys/posix/netinet_tcp.odin5
-rw-r--r--core/sys/posix/poll.odin24
-rw-r--r--core/sys/posix/posix.odin7
-rw-r--r--core/sys/posix/pthread.odin111
-rw-r--r--core/sys/posix/pwd.odin15
-rw-r--r--core/sys/posix/sched.odin5
-rw-r--r--core/sys/posix/setjmp.odin6
-rw-r--r--core/sys/posix/setjmp_libc.odin11
-rw-r--r--core/sys/posix/signal.odin298
-rw-r--r--core/sys/posix/signal_libc.odin145
-rw-r--r--core/sys/posix/stdio.odin173
-rw-r--r--core/sys/posix/stdio_libc.odin207
-rw-r--r--core/sys/posix/stdlib.odin79
-rw-r--r--core/sys/posix/stdlib_libc.odin101
-rw-r--r--core/sys/posix/string.odin15
-rw-r--r--core/sys/posix/string_libc.odin30
-rw-r--r--core/sys/posix/sys_ipc.odin29
-rw-r--r--core/sys/posix/sys_mman.odin30
-rw-r--r--core/sys/posix/sys_msg.odin53
-rw-r--r--core/sys/posix/sys_resource.odin18
-rw-r--r--core/sys/posix/sys_select.odin7
-rw-r--r--core/sys/posix/sys_sem.odin53
-rw-r--r--core/sys/posix/sys_shm.odin47
-rw-r--r--core/sys/posix/sys_socket.odin227
-rw-r--r--core/sys/posix/sys_stat.odin187
-rw-r--r--core/sys/posix/sys_statvfs.odin26
-rw-r--r--core/sys/posix/sys_time.odin5
-rw-r--r--core/sys/posix/sys_times.odin5
-rw-r--r--core/sys/posix/sys_uio.odin5
-rw-r--r--core/sys/posix/sys_un.odin10
-rw-r--r--core/sys/posix/sys_utsname.odin16
-rw-r--r--core/sys/posix/sys_wait.odin75
-rw-r--r--core/sys/posix/termios.odin17
-rw-r--r--core/sys/posix/time.odin15
-rw-r--r--core/sys/posix/ulimit.odin5
-rw-r--r--core/sys/posix/unistd.odin412
-rw-r--r--core/sys/posix/unistd_libc.odin153
-rw-r--r--core/sys/posix/utime.odin5
-rw-r--r--core/sys/posix/wordexp.odin24
-rw-r--r--core/sys/unix/pthread_darwin.odin96
-rw-r--r--core/sys/unix/pthread_freebsd.odin122
-rw-r--r--core/sys/unix/pthread_haiku.odin71
-rw-r--r--core/sys/unix/pthread_linux.odin124
-rw-r--r--core/sys/unix/pthread_netbsd.odin102
-rw-r--r--core/sys/unix/pthread_openbsd.odin74
-rw-r--r--core/sys/unix/pthread_unix.odin127
-rw-r--r--core/sys/unix/unix.odin8
-rw-r--r--core/sys/wasm/js/dom.odin2
-rw-r--r--core/sys/wasm/js/events.odin4
-rw-r--r--core/sys/wasm/js/odin.js49
-rw-r--r--core/sys/windows/icu.odin14
-rw-r--r--core/sys/windows/kernel32.odin8
-rw-r--r--core/sys/windows/types.odin17
-rw-r--r--core/sys/windows/user32.odin61
-rw-r--r--core/sys/windows/ux_theme.odin2
-rw-r--r--core/sys/windows/winerror.odin14
81 files changed, 3375 insertions, 1878 deletions
diff --git a/core/sys/darwin/Foundation/NSApplication.odin b/core/sys/darwin/Foundation/NSApplication.odin
index 7191f6d07..254da75ad 100644
--- a/core/sys/darwin/Foundation/NSApplication.odin
+++ b/core/sys/darwin/Foundation/NSApplication.odin
@@ -108,6 +108,16 @@ Application_setMainMenu :: proc "c" (self: ^Application, menu: ^Menu) {
msgSend(nil, self, "setMainMenu:", menu)
}
+@(objc_type=Application, objc_name="mainWindow")
+Application_mainWindow :: proc "c" (self: ^Application) -> ^Window {
+ return msgSend(^Window, self, "mainWindow")
+}
+
+@(objc_type=Application, objc_name="keyWindow")
+Application_keyWindow :: proc "c" (self: ^Application) -> ^Window {
+ return msgSend(^Window, self, "keyWindow")
+}
+
@(objc_type=Application, objc_name="windows")
Application_windows :: proc "c" (self: ^Application) -> ^Array {
return msgSend(^Array, self, "windows")
diff --git a/core/sys/darwin/mach_darwin.odin b/core/sys/darwin/mach_darwin.odin
index 1e728fe78..01affa6e8 100644
--- a/core/sys/darwin/mach_darwin.odin
+++ b/core/sys/darwin/mach_darwin.odin
@@ -3,17 +3,18 @@ package darwin
foreign import mach "system:System.framework"
import "core:c"
+import "base:intrinsics"
// NOTE(tetra): Unclear whether these should be aligned 16 or not.
// However all other sync primitives are aligned for robustness.
// I cannot currently align these though.
// See core/sys/unix/pthread_linux.odin/pthread_t.
-mach_port_t :: distinct i32
+mach_port_t :: distinct c.uint
task_t :: mach_port_t
semaphore_t :: distinct u64
-kern_return_t :: distinct u64
+kern_return_t :: distinct c.int
thread_act_t :: distinct u64
thread_state_t :: distinct ^u32
thread_list_t :: [^]thread_act_t
@@ -37,11 +38,6 @@ MACH_MSGH_BITS_COMPLEX :: 0x80000000
MACH_PORT_RIGHT_SEND :: 0
MACH_PORT_RIGHT_RECEIVE :: 1
-VM_PROT_NONE :: 0
-VM_PROT_READ :: 1
-VM_PROT_WRITE :: 2
-VM_PROT_EXECUTE :: 4
-
VM_INHERIT_SHARE :: 0
VM_INHERIT_COPY :: 1
VM_INHERIT_NONE :: 2
@@ -58,6 +54,27 @@ ARM_THREAD_STATE64 :: 6
mach_msg_option_t :: distinct i32
name_t :: distinct cstring
+vm_map_t :: mach_port_t
+mem_entry_name_port_t :: mach_port_t
+ipc_space_t :: mach_port_t
+thread_t :: mach_port_t
+
+vm_size_t :: distinct c.uintptr_t
+
+vm_address_t :: vm_offset_t
+vm_offset_t :: distinct c.uintptr_t
+
+// NOTE(beau): typedefed to int in the original headers
+boolean_t :: b32
+
+vm_prot_t :: distinct c.int
+
+vm_inherit_t :: distinct c.uint
+
+mach_port_name_t :: distinct c.uint
+
+sync_policy_t :: distinct c.int
+
mach_msg_port_descriptor_t :: struct {
name: mach_port_t,
_: u32,
@@ -257,20 +274,489 @@ foreign mach {
task_info :: proc(task: task_t, flavor: i32, info: task_info_t, count: ^u32) -> kern_return_t ---
task_terminate :: proc(task: task_t) -> kern_return_t ---
+ semaphore_create :: proc(task: task_t, semaphore: ^semaphore_t, policy: Sync_Policy, value: c.int) -> Kern_Return ---
+ semaphore_destroy :: proc(task: task_t, semaphore: semaphore_t) -> Kern_Return ---
+
+ semaphore_signal :: proc(semaphore: semaphore_t) -> Kern_Return ---
+ semaphore_signal_all :: proc(semaphore: semaphore_t) -> Kern_Return ---
+ semaphore_signal_thread :: proc(semaphore: semaphore_t, thread: thread_t) -> Kern_Return ---
+
+ semaphore_wait :: proc(semaphore: semaphore_t) -> Kern_Return ---
+
thread_get_state :: proc(thread: thread_act_t, flavor: i32, thread_state: thread_state_t, old_state_count: ^u32) -> kern_return_t ---
thread_info :: proc(thread: thread_act_t, flavor: u32, thread_info: ^thread_identifier_info, info_count: ^u32) -> kern_return_t ---
bootstrap_register2 :: proc(bp: mach_port_t, service_name: name_t, sp: mach_port_t, flags: u64) -> kern_return_t ---
bootstrap_look_up :: proc(bp: mach_port_t, service_name: name_t, sp: ^mach_port_t) -> kern_return_t ---
- semaphore_create :: proc(task: task_t, semaphore: ^semaphore_t, policy, value: c.int) -> kern_return_t ---
- semaphore_destroy :: proc(task: task_t, semaphore: semaphore_t) -> kern_return_t ---
+ vm_map :: proc(
+ target_task: vm_map_t,
+ address: ^vm_address_t,
+ size: vm_size_t,
+ mask: vm_address_t,
+ flags: VM_Flags,
+ object: mem_entry_name_port_t,
+ offset: vm_offset_t,
+ copy: boolean_t,
+ cur_protection,
+ max_protection: VM_Prot_Flags,
+ inheritance: VM_Inherit,
+ ) -> Kern_Return ---
+
+ mach_make_memory_entry :: proc(
+ target_task: vm_map_t,
+ size: ^vm_size_t,
+ offset: vm_offset_t,
+ permission: VM_Prot_Flags,
+ object_handle: ^mem_entry_name_port_t,
+ parent_entry: mem_entry_name_port_t,
+ ) -> Kern_Return ---
+}
+
+
+
+Kern_Return :: enum kern_return_t {
+ Success,
+
+ /* Specified address is not currently valid.
+ */
+ Invalid_Address,
+
+ /* Specified memory is valid, but does not permit the
+ * required forms of access.
+ */
+ Protection_Failure,
+
+ /* The address range specified is already in use, or
+ * no address range of the size specified could be
+ * found.
+ */
+ No_Space,
+
+ /* The function requested was not applicable to this
+ * type of argument, or an argument is invalid
+ */
+ Invalid_Argument,
+
+ /* The function could not be performed. A catch-all.
+ */
+ Failure,
+
+ /* A system resource could not be allocated to fulfill
+ * this request. This failure may not be permanent.
+ */
+ Resource_Shortage,
+
+ /* The task in question does not hold receive rights
+ * for the port argument.
+ */
+ Not_Receiver,
+
+ /* Bogus access restriction.
+ */
+ No_Access,
+
+ /* During a page fault, the target address refers to a
+ * memory object that has been destroyed. This
+ * failure is permanent.
+ */
+ Memory_Failure,
+
+ /* During a page fault, the memory object indicated
+ * that the data could not be returned. This failure
+ * may be temporary; future attempts to access this
+ * same data may succeed, as defined by the memory
+ * object.
+ */
+ Memory_Error,
+
+ /* The receive right is already a member of the portset.
+ */
+ Already_In_Set,
+
+ /* The receive right is not a member of a port set.
+ */
+ Not_In_Set,
+
+ /* The name already denotes a right in the task.
+ */
+ Name_Exists,
+
+ /* The operation was aborted. Ipc code will
+ * catch this and reflect it as a message error.
+ */
+ Aborted,
+
+ /* The name doesn't denote a right in the task.
+ */
+ Invalid_Name,
+
+ /* Target task isn't an active task.
+ */
+ Invalid_Task,
+
+ /* The name denotes a right, but not an appropriate right.
+ */
+ Invalid_Right,
+
+ /* A blatant range error.
+ */
+ Invalid_Value,
+
+ /* Operation would overflow limit on user-references.
+ */
+ URefs_Overflow,
+
+ /* The supplied (port) capability is improper.
+ */
+ Invalid_Capability,
+
+ /* The task already has send or receive rights
+ * for the port under another name.
+ */
+ Right_Exists,
+
+ /* Target host isn't actually a host.
+ */
+ Invalid_Host,
+
+ /* An attempt was made to supply "precious" data
+ * for memory that is already present in a
+ * memory object.
+ */
+ Memory_Present,
+
+ /* A page was requested of a memory manager via
+ * memory_object_data_request for an object using
+ * a MEMORY_OBJECT_COPY_CALL strategy, with the
+ * VM_PROT_WANTS_COPY flag being used to specify
+ * that the page desired is for a copy of the
+ * object, and the memory manager has detected
+ * the page was pushed into a copy of the object
+ * while the kernel was walking the shadow chain
+ * from the copy to the object. This error code
+ * is delivered via memory_object_data_error
+ * and is handled by the kernel (it forces the
+ * kernel to restart the fault). It will not be
+ * seen by users.
+ */
+ Memory_Data_Moved,
+
+ /* A strategic copy was attempted of an object
+ * upon which a quicker copy is now possible.
+ * The caller should retry the copy using
+ * vm_object_copy_quickly. This error code
+ * is seen only by the kernel.
+ */
+ Memory_Restart_Copy,
+
+ /* An argument applied to assert processor set privilege
+ * was not a processor set control port.
+ */
+ Invalid_Processor_Set,
+
+ /* The specified scheduling attributes exceed the thread's
+ * limits.
+ */
+ Policy_Limit,
+
+ /* The specified scheduling policy is not currently
+ * enabled for the processor set.
+ */
+ Invalid_Policy,
+
+ /* The external memory manager failed to initialize the
+ * memory object.
+ */
+ Invalid_Object,
+
+ /* A thread is attempting to wait for an event for which
+ * there is already a waiting thread.
+ */
+ Already_Waiting,
+
+ /* An attempt was made to destroy the default processor
+ * set.
+ */
+ Default_Set,
+
+ /* An attempt was made to fetch an exception port that is
+ * protected, or to abort a thread while processing a
+ * protected exception.
+ */
+ Exception_Protected,
+
+ /* A ledger was required but not supplied.
+ */
+ Invalid_Ledger,
+
+ /* The port was not a memory cache control port.
+ */
+ Invalid_Memory_Control,
+
+ /* An argument supplied to assert security privilege
+ * was not a host security port.
+ */
+ Invalid_Security,
+
+ /* thread_depress_abort was called on a thread which
+ * was not currently depressed.
+ */
+ Not_Depressed,
+
+ /* Object has been terminated and is no longer available
+ */
+ Terminated,
+
+ /* Lock set has been destroyed and is no longer available.
+ */
+ Lock_Set_Destroyed,
+
+ /* The thread holding the lock terminated before releasing
+ * the lock
+ */
+ Lock_Unstable,
+
+ /* The lock is already owned by another thread
+ */
+ Lock_Owned,
+
+ /* The lock is already owned by the calling thread
+ */
+ Lock_Owned_Self,
+
+ /* Semaphore has been destroyed and is no longer available.
+ */
+ Semaphore_Destroyed,
+
+ /* Return from RPC indicating the target server was
+ * terminated before it successfully replied
+ */
+ Rpc_Server_Terminated,
+
+ /* Terminate an orphaned activation.
+ */
+ RPC_Terminate_Orphan,
+
+ /* Allow an orphaned activation to continue executing.
+ */
+ RPC_Continue_Orphan,
+
+ /* Empty thread activation (No thread linked to it)
+ */
+ Not_Supported,
+
+ /* Remote node down or inaccessible.
+ */
+ Node_Down,
+
+ /* A signalled thread was not actually waiting. */
+ Not_Waiting,
+
+ /* Some thread-oriented operation (semaphore_wait) timed out
+ */
+ Operation_Timed_Out,
+
+ /* During a page fault, indicates that the page was rejected
+ * as a result of a signature check.
+ */
+ Codesign_Error,
+
+ /* The requested property cannot be changed at this time.
+ */
+ Policy_Static,
+
+ /* The provided buffer is of insufficient size for the requested data.
+ */
+ Insufficient_Buffer_Size,
+
+ /* Denied by security policy
+ */
+ Denied,
+
+ /* The KC on which the function is operating is missing
+ */
+ Missing_KC,
+
+ /* The KC on which the function is operating is invalid
+ */
+ Invalid_KC,
+
+ /* A search or query operation did not return a result
+ */
+ Not_Found,
+
+ /* Maximum return value allowable
+ */
+ Return_Max = 0x100,
+}
+
+/*
+ * VM allocation flags:
+ *
+ * VM_FLAGS_FIXED
+ * (really the absence of VM_FLAGS_ANYWHERE)
+ * Allocate new VM region at the specified virtual address, if possible.
+ *
+ * VM_FLAGS_ANYWHERE
+ * Allocate new VM region anywhere it would fit in the address space.
+ *
+ * VM_FLAGS_PURGABLE
+ * Create a purgable VM object for that new VM region.
+ *
+ * VM_FLAGS_4GB_CHUNK
+ * The new VM region will be chunked up into 4GB sized pieces.
+ *
+ * VM_FLAGS_NO_PMAP_CHECK
+ * (for DEBUG kernel config only, ignored for other configs)
+ * Do not check that there is no stale pmap mapping for the new VM region.
+ * This is useful for kernel memory allocations at bootstrap when building
+ * the initial kernel address space while some memory is already in use.
+ *
+ * VM_FLAGS_OVERWRITE
+ * The new VM region can replace existing VM regions if necessary
+ * (to be used in combination with VM_FLAGS_FIXED).
+ *
+ * VM_FLAGS_NO_CACHE
+ * Pages brought in to this VM region are placed on the speculative
+ * queue instead of the active queue. In other words, they are not
+ * cached so that they will be stolen first if memory runs low.
+ */
+
+@(private="file")
+LOG2 :: intrinsics.constant_log2
+
+VM_Flag :: enum c.int {
+ Anywhere,
+ Purgable,
+ _4GB_Chunk,
+ Random_Addr,
+ No_Cache,
+ Resilient_Codesign,
+ Resilient_Media,
+ Permanent,
+
+ // NOTE(beau): log 2 of the bit we want in the bit set so we get that bit in
+ // the bit set
+
+ TPRO = LOG2(0x1000),
+ Overwrite = LOG2(0x4000),/* delete any existing mappings first */
+
+ Superpage_Size_Any = LOG2(0x10000),
+ Superpage_Size_2MB = LOG2(0x20000),
+ __Superpage3 = LOG2(0x40000),
+
+ Return_Data_Addr = LOG2(0x100000),
+ Return_4K_Data_Addr = LOG2(0x800000),
+
+ Alias_Mask1 = 24,
+ Alias_Mask2,
+ Alias_Mask3,
+ Alias_Mask4,
+ Alias_Mask5,
+ Alias_Mask6,
+ Alias_Mask7,
+ Alias_Mask8,
+
+ HW = TPRO,
+}
+
+VM_Flags :: distinct bit_set[VM_Flag; c.int]
+VM_FLAGS_FIXED :: VM_Flags{}
+
+/*
+ * VM_FLAGS_SUPERPAGE_MASK
+ * 3 bits that specify whether large pages should be used instead of
+ * base pages (!=0), as well as the requested page size.
+ */
+VM_FLAGS_SUPERPAGE_MASK :: VM_Flags {
+ .Superpage_Size_Any,
+ .Superpage_Size_2MB,
+ .__Superpage3,
+}
+
+// 0xFF000000
+VM_FLAGS_ALIAS_MASK :: VM_Flags {
+ .Alias_Mask1,
+ .Alias_Mask2,
+ .Alias_Mask3,
+ .Alias_Mask4,
+ .Alias_Mask5,
+ .Alias_Mask6,
+ .Alias_Mask7,
+ .Alias_Mask8,
+}
+
+VM_GET_FLAGS_ALIAS :: proc(flags: VM_Flags) -> c.int {
+ return transmute(c.int)(flags & VM_FLAGS_ALIAS_MASK) >> 24
+}
+// NOTE(beau): no need for VM_SET_FLAGS_ALIAS, just mask in things from
+// VM_Flag.Alias_Mask*
+
+/* These are the flags that we accept from user-space */
+VM_FLAGS_USER_ALLOCATE :: VM_Flags {
+ .Anywhere,
+ .Purgable,
+ ._4GB_Chunk,
+ .Random_Addr,
+ .No_Cache,
+ .Permanent,
+ .Overwrite,
+} | VM_FLAGS_FIXED | VM_FLAGS_SUPERPAGE_MASK | VM_FLAGS_ALIAS_MASK
+
+VM_FLAGS_USER_MAP :: VM_Flags {
+ .Return_4K_Data_Addr,
+ .Return_Data_Addr,
+} | VM_FLAGS_USER_ALLOCATE
+
+VM_FLAGS_USER_REMAP :: VM_Flags {
+ .Anywhere,
+ .Random_Addr,
+ .Overwrite,
+ .Return_Data_Addr,
+ .Resilient_Codesign,
+ .Resilient_Media,
+} | VM_FLAGS_FIXED
+
+VM_FLAGS_SUPERPAGE_NONE :: VM_Flags{} /* no superpages, if all bits are 0 */
+
+/*
+ * Protection values, defined as bits within the vm_prot_t type
+ */
+
+VM_Prot :: enum vm_prot_t {
+ Read,
+ Write,
+ Execute,
+}
+
+VM_Prot_Flags :: distinct bit_set[VM_Prot; vm_prot_t]
+
+VM_PROT_NONE :: VM_Prot_Flags{}
+VM_PROT_DEFAULT :: VM_Prot_Flags{.Read, .Write}
+VM_PROT_ALL :: VM_Prot_Flags{.Read, .Write, .Execute}
+
+/*
+ * Enumeration of valid values for vm_inherit_t.
+ */
+
+VM_Inherit :: enum vm_inherit_t {
+ Share,
+ Copy,
+ None,
+ Donate_Copy,
+
+ Default = Copy,
+ Last_Valid = None,
+}
+
+Sync_Policy :: enum sync_policy_t {
+ Fifo,
+ Fixed_Priority,
+ Reversed,
+ Order_Mask,
- semaphore_signal :: proc(semaphore: semaphore_t) -> kern_return_t ---
- semaphore_signal_all :: proc(semaphore: semaphore_t) -> kern_return_t ---
- semaphore_signal_thread :: proc(semaphore: semaphore_t, thread: thread_act_t) -> kern_return_t ---
-
- semaphore_wait :: proc(semaphore: semaphore_t) -> kern_return_t ---
+ Lifo = Fifo | Reversed,
}
mach_vm_trunc_page :: proc(v: u64) -> u64 {
diff --git a/core/sys/info/cpu_intel.odin b/core/sys/info/cpu_intel.odin
index d6fa98507..95b53dda0 100644
--- a/core/sys/info/cpu_intel.odin
+++ b/core/sys/info/cpu_intel.odin
@@ -28,6 +28,23 @@ CPU_Feature :: enum u64 {
ssse3, // Supplemental streaming SIMD extension 3
sse41, // Streaming SIMD extension 4 and 4.1
sse42, // Streaming SIMD extension 4 and 4.2
+
+ avx512bf16, // Vector Neural Network Instructions supporting bfloat16
+ avx512bitalg, // Bit Algorithms
+ avx512bw, // Byte and Word instructions
+ avx512cd, // Conflict Detection instructions
+ avx512dq, // Doubleword and Quadword instructions
+ avx512er, // Exponential and Reciprocal instructions
+ avx512f, // Foundation
+ avx512fp16, // Vector 16-bit float instructions
+ avx512ifma, // Integer Fused Multiply Add
+ avx512pf, // Prefetch instructions
+ avx512vbmi, // Vector Byte Manipulation Instructions
+ avx512vbmi2, // Vector Byte Manipulation Instructions 2
+ avx512vl, // Vector Length extensions
+ avx512vnni, // Vector Neural Network Instructions
+ avx512vp2intersect, // Vector Pair Intersection to a Pair of Mask Registers
+ avx512vpopcntdq, // Vector Population Count for Doubleword and Quadword
}
CPU_Features :: distinct bit_set[CPU_Feature; u64]
@@ -82,9 +99,11 @@ init_cpu_features :: proc "c" () {
//
// See: crbug.com/375968
os_supports_avx := false
+ os_supports_avx512 := false
if .os_xsave in set && is_set(26, ecx1) {
eax, _ := xgetbv(0)
os_supports_avx = is_set(1, eax) && is_set(2, eax)
+ os_supports_avx512 = is_set(5, eax) && is_set(6, eax) && is_set(7, eax)
}
if os_supports_avx {
try_set(&set, .avx, 28, ecx1)
@@ -94,11 +113,37 @@ init_cpu_features :: proc "c" () {
return
}
- _, ebx7, _, _ := cpuid(7, 0)
+ _, ebx7, ecx7, edx7 := cpuid(7, 0)
try_set(&set, .bmi1, 3, ebx7)
if os_supports_avx {
try_set(&set, .avx2, 5, ebx7)
}
+ if os_supports_avx512 {
+ try_set(&set, .avx512f, 16, ebx7)
+ try_set(&set, .avx512dq, 17, ebx7)
+ try_set(&set, .avx512ifma, 21, ebx7)
+ try_set(&set, .avx512pf, 26, ebx7)
+ try_set(&set, .avx512er, 27, ebx7)
+ try_set(&set, .avx512cd, 28, ebx7)
+ try_set(&set, .avx512bw, 30, ebx7)
+
+ // XMM/YMM are also required for 128/256-bit instructions
+ if os_supports_avx {
+ try_set(&set, .avx512vl, 31, ebx7)
+ }
+
+ try_set(&set, .avx512vbmi, 1, ecx7)
+ try_set(&set, .avx512vbmi2, 6, ecx7)
+ try_set(&set, .avx512vnni, 11, ecx7)
+ try_set(&set, .avx512bitalg, 12, ecx7)
+ try_set(&set, .avx512vpopcntdq, 14, ecx7)
+
+ try_set(&set, .avx512vp2intersect, 8, edx7)
+ try_set(&set, .avx512fp16, 23, edx7)
+
+ eax7_1, _, _, _ := cpuid(7, 1)
+ try_set(&set, .avx512bf16, 5, eax7_1)
+ }
try_set(&set, .bmi2, 8, ebx7)
try_set(&set, .erms, 9, ebx7)
try_set(&set, .rdseed, 18, ebx7)
diff --git a/core/sys/info/platform_darwin.odin b/core/sys/info/platform_darwin.odin
index 493f038f0..97a2199ab 100644
--- a/core/sys/info/platform_darwin.odin
+++ b/core/sys/info/platform_darwin.odin
@@ -494,6 +494,10 @@ macos_release_map: map[string]Darwin_To_Release = {
"21G816" = {{21, 6, 0}, "macOS", {"Monterey", {12, 7, 0}}},
"21G920" = {{21, 6, 0}, "macOS", {"Monterey", {12, 7, 1}}},
"21G1974" = {{21, 6, 0}, "macOS", {"Monterey", {12, 7, 2}}},
+ "21H1015" = {{21, 6, 0}, "macOS", {"Monterey", {12, 7, 3}}},
+ "21H1123" = {{21, 6, 0}, "macOS", {"Monterey", {12, 7, 4}}},
+ "21H1222" = {{21, 6, 0}, "macOS", {"Monterey", {12, 7, 5}}},
+ "21H1320" = {{21, 6, 0}, "macOS", {"Monterey", {12, 7, 6}}},
// MacOS Ventura
"22A380" = {{22, 1, 0}, "macOS", {"Ventura", {13, 0, 0}}},
@@ -513,6 +517,15 @@ macos_release_map: map[string]Darwin_To_Release = {
"22G120" = {{22, 6, 0}, "macOS", {"Ventura", {13, 6, 0}}},
"22G313" = {{22, 6, 0}, "macOS", {"Ventura", {13, 6, 1}}},
"22G320" = {{22, 6, 0}, "macOS", {"Ventura", {13, 6, 2}}},
+ "22G436" = {{22, 6, 0}, "macOS", {"Ventura", {13, 6, 3}}},
+ "22G513" = {{22, 6, 0}, "macOS", {"Ventura", {13, 6, 4}}},
+ "22G621" = {{22, 6, 0}, "macOS", {"Ventura", {13, 6, 5}}},
+ "22G630" = {{22, 6, 0}, "macOS", {"Ventura", {13, 6, 6}}},
+ "22G720" = {{22, 6, 0}, "macOS", {"Ventura", {13, 6, 7}}},
+ "22G820" = {{22, 6, 0}, "macOS", {"Ventura", {13, 6, 8}}},
+ "22G830" = {{22, 6, 0}, "macOS", {"Ventura", {13, 6, 9}}},
+ "22H123" = {{22, 6, 0}, "macOS", {"Ventura", {13, 7, 0}}},
+ "22H221" = {{22, 6, 0}, "macOS", {"Ventura", {13, 7, 1}}},
// MacOS Sonoma
"23A344" = {{23, 0, 0}, "macOS", {"Sonoma", {14, 0, 0}}},
@@ -531,9 +544,12 @@ macos_release_map: map[string]Darwin_To_Release = {
"23G80" = {{23, 6, 0}, "macOS", {"Sonoma", {14, 6, 0}}},
"23G93" = {{23, 6, 0}, "macOS", {"Sonoma", {14, 6, 1}}},
"23H124" = {{23, 6, 0}, "macOS", {"Sonoma", {14, 7, 0}}},
+ "23H222" = {{23, 6, 0}, "macOS", {"Sonoma", {14, 7, 1}}},
// MacOS Sequoia
"24A335" = {{24, 0, 0}, "macOS", {"Sequoia", {15, 0, 0}}},
+ "24A348" = {{24, 0, 0}, "macOS", {"Sequoia", {15, 0, 1}}},
+ "24B83" = {{24, 1, 0}, "macOS", {"Sequoia", {15, 1, 0}}},
}
@(private)
diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin
index 8a4a6dd7a..9ce2e206e 100644
--- a/core/sys/linux/bits.odin
+++ b/core/sys/linux/bits.odin
@@ -152,66 +152,43 @@ Errno :: enum i32 {
RDONLY flag is not present, because it has the value of 0, i.e. it is the
default, unless WRONLY or RDWR is specified.
*/
-when ODIN_ARCH != .arm64 && ODIN_ARCH != .arm32 {
- Open_Flags_Bits :: enum {
- WRONLY = 0,
- RDWR = 1,
- CREAT = 6,
- EXCL = 7,
- NOCTTY = 8,
- TRUNC = 9,
- APPEND = 10,
- NONBLOCK = 11,
- DSYNC = 12,
- ASYNC = 13,
- DIRECT = 14,
- LARGEFILE = 15,
- DIRECTORY = 16,
- NOFOLLOW = 17,
- NOATIME = 18,
- CLOEXEC = 19,
- PATH = 21,
- }
- // https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19
- #assert(1 << uint(Open_Flags_Bits.WRONLY) == 0o0000000_1)
- #assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2)
- #assert(1 << uint(Open_Flags_Bits.CREAT) == 0o00000_100)
- #assert(1 << uint(Open_Flags_Bits.EXCL) == 0o00000_200)
- #assert(1 << uint(Open_Flags_Bits.NOCTTY) == 0o00000_400)
- #assert(1 << uint(Open_Flags_Bits.TRUNC) == 0o0000_1000)
- #assert(1 << uint(Open_Flags_Bits.APPEND) == 0o0000_2000)
- #assert(1 << uint(Open_Flags_Bits.NONBLOCK) == 0o0000_4000)
- #assert(1 << uint(Open_Flags_Bits.DSYNC) == 0o000_10000)
- #assert(1 << uint(Open_Flags_Bits.ASYNC) == 0o000_20000)
- #assert(1 << uint(Open_Flags_Bits.DIRECT) == 0o000_40000)
- #assert(1 << uint(Open_Flags_Bits.LARGEFILE) == 0o00_100000)
- #assert(1 << uint(Open_Flags_Bits.DIRECTORY) == 0o00_200000)
- #assert(1 << uint(Open_Flags_Bits.NOFOLLOW) == 0o00_400000)
- #assert(1 << uint(Open_Flags_Bits.NOATIME) == 0o0_1000000)
- #assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000)
- #assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000)
-
-} else {
- Open_Flags_Bits :: enum {
- WRONLY = 0,
- RDWR = 1,
- CREAT = 6,
- EXCL = 7,
- NOCTTY = 8,
- TRUNC = 9,
- APPEND = 10,
- NONBLOCK = 11,
- DSYNC = 12,
- ASYNC = 13,
- DIRECTORY = 14,
- NOFOLLOW = 15,
- DIRECT = 16,
- LARGEFILE = 17,
- NOATIME = 18,
- CLOEXEC = 19,
- PATH = 21,
- }
-}
+Open_Flags_Bits :: enum {
+ WRONLY = 0,
+ RDWR = 1,
+ CREAT = 6,
+ EXCL = 7,
+ NOCTTY = 8,
+ TRUNC = 9,
+ APPEND = 10,
+ NONBLOCK = 11,
+ DSYNC = 12,
+ ASYNC = 13,
+ DIRECT = 14,
+ LARGEFILE = 15,
+ DIRECTORY = 16,
+ NOFOLLOW = 17,
+ NOATIME = 18,
+ CLOEXEC = 19,
+ PATH = 21,
+}
+// https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19
+#assert(1 << uint(Open_Flags_Bits.WRONLY) == 0o0000000_1)
+#assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2)
+#assert(1 << uint(Open_Flags_Bits.CREAT) == 0o00000_100)
+#assert(1 << uint(Open_Flags_Bits.EXCL) == 0o00000_200)
+#assert(1 << uint(Open_Flags_Bits.NOCTTY) == 0o00000_400)
+#assert(1 << uint(Open_Flags_Bits.TRUNC) == 0o0000_1000)
+#assert(1 << uint(Open_Flags_Bits.APPEND) == 0o0000_2000)
+#assert(1 << uint(Open_Flags_Bits.NONBLOCK) == 0o0000_4000)
+#assert(1 << uint(Open_Flags_Bits.DSYNC) == 0o000_10000)
+#assert(1 << uint(Open_Flags_Bits.ASYNC) == 0o000_20000)
+#assert(1 << uint(Open_Flags_Bits.DIRECT) == 0o000_40000)
+#assert(1 << uint(Open_Flags_Bits.LARGEFILE) == 0o00_100000)
+#assert(1 << uint(Open_Flags_Bits.DIRECTORY) == 0o00_200000)
+#assert(1 << uint(Open_Flags_Bits.NOFOLLOW) == 0o00_400000)
+#assert(1 << uint(Open_Flags_Bits.NOATIME) == 0o0_1000000)
+#assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000)
+#assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000)
/*
Bits for FD_Flags bitset
@@ -542,6 +519,36 @@ Fd_Poll_Events_Bits :: enum {
RDHUP = 13,
}
+Inotify_Init_Bits :: enum {
+ NONBLOCK = 11,
+ CLOEXEC = 19,
+}
+
+Inotify_Event_Bits :: enum u32 {
+ ACCESS = 0,
+ MODIFY = 1,
+ ATTRIB = 2,
+ CLOSE_WRITE = 3,
+ CLOSE_NOWRITE = 4,
+ OPEN = 5,
+ MOVED_FROM = 6,
+ MOVED_TO = 7,
+ CREATE = 8,
+ DELETE = 9,
+ DELETE_SELF = 10,
+ MOVE_SELF = 11,
+ UNMOUNT = 13,
+ Q_OVERFLOW = 14,
+ IGNORED = 15,
+ ONLYDIR = 24,
+ DONT_FOLLOW = 25,
+ EXCL_UNLINK = 26,
+ MASK_CREATE = 28,
+ MASK_ADD = 29,
+ ISDIR = 30,
+ ONESHOT = 31,
+}
+
/*
Bits for Mem_Protection bitfield
*/
diff --git a/core/sys/linux/constants.odin b/core/sys/linux/constants.odin
index 129444d0f..b3bbcafb3 100644
--- a/core/sys/linux/constants.odin
+++ b/core/sys/linux/constants.odin
@@ -135,6 +135,31 @@ STATX_BASIC_STATS :: Statx_Mask {
.BLOCKS,
}
+IN_ALL_EVENTS :: Inotify_Event_Mask {
+ .ACCESS,
+ .MODIFY,
+ .ATTRIB,
+ .CLOSE_WRITE,
+ .CLOSE_NOWRITE,
+ .OPEN,
+ .MOVED_FROM,
+ .MOVED_TO,
+ .CREATE,
+ .DELETE,
+ .DELETE_SELF,
+ .MOVE_SELF,
+}
+
+IN_CLOSE :: Inotify_Event_Mask {
+ .CLOSE_WRITE,
+ .CLOSE_NOWRITE,
+}
+
+IN_MOVE :: Inotify_Event_Mask {
+ .MOVED_FROM,
+ .MOVED_TO,
+}
+
/*
Tell `shmget` to create a new key
*/
diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin
index c5894d78b..690902f07 100644
--- a/core/sys/linux/sys.odin
+++ b/core/sys/linux/sys.odin
@@ -2536,11 +2536,30 @@ waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, opt
// TODO(flysand): ioprio_get
-// TODO(flysand): inotify_init
+inotify_init :: proc "contextless" () -> (Fd, Errno) {
+ when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
+ ret := syscall(SYS_inotify_init1, 0)
+ return errno_unwrap(ret, Fd)
+ } else {
+ ret := syscall(SYS_inotify_init)
+ return errno_unwrap(ret, Fd)
+ }
+}
-// TODO(flysand): inotify_add_watch
+inotify_init1 :: proc "contextless" (flags: Inotify_Init_Flags) -> (Fd, Errno) {
+ ret := syscall(SYS_inotify_init1, transmute(i32)flags)
+ return errno_unwrap(ret, Fd)
+}
+
+inotify_add_watch :: proc "contextless" (fd: Fd, pathname: cstring, mask: Inotify_Event_Mask) -> (Wd, Errno) {
+ ret := syscall(SYS_inotify_add_watch, fd, transmute(uintptr) pathname, transmute(u32) mask)
+ return errno_unwrap(ret, Wd)
+}
-// TODO(flysand): inotify_rm_watch
+inotify_rm_watch :: proc "contextless" (fd: Fd, wd: Wd) -> (Errno) {
+ ret := syscall(SYS_inotify_rm_watch, fd, wd)
+ return Errno(-ret)
+}
// TODO(flysand): migrate_pages
diff --git a/core/sys/linux/types.odin b/core/sys/linux/types.odin
index 0e5b8218b..42d5cc988 100644
--- a/core/sys/linux/types.odin
+++ b/core/sys/linux/types.odin
@@ -31,6 +31,11 @@ Id :: distinct uint
Fd :: distinct i32
/*
+ Represents a watch descriptor.
+*/
+Wd :: distinct i32
+
+/*
Type for PID file descriptors.
*/
Pid_FD :: distinct i32
@@ -343,6 +348,18 @@ Poll_Fd :: struct {
revents: Fd_Poll_Events,
}
+Inotify_Init_Flags :: bit_set[Inotify_Init_Bits; i32]
+
+Inotify_Event :: struct {
+ wd: Wd,
+ mask: Inotify_Event_Mask,
+ cookie: u32,
+ len: u32,
+ name: [0]u8,
+}
+
+Inotify_Event_Mask :: bit_set[Inotify_Event_Bits; u32]
+
/*
Specifies protection for memory pages.
*/
@@ -1136,6 +1153,12 @@ when ODIN_ARCH == .arm32 {
eflags: uint,
rsp: uint,
ss: uint,
+ fs_base: uint,
+ gs_base: uint,
+ ds: uint,
+ es: uint,
+ fs: uint,
+ gs: uint,
}
// All floating point state
_Arch_User_FP_Regs :: struct {
diff --git a/core/sys/posix/arpa_inet.odin b/core/sys/posix/arpa_inet.odin
index 7e950c4be..d3592dd80 100644
--- a/core/sys/posix/arpa_inet.odin
+++ b/core/sys/posix/arpa_inet.odin
@@ -1,3 +1,4 @@
+#+build darwin, linux, freebsd, openbsd, netbsd
package posix
import "core:c"
diff --git a/core/sys/posix/dirent.odin b/core/sys/posix/dirent.odin
index bbb5416c5..bf32be8cf 100644
--- a/core/sys/posix/dirent.odin
+++ b/core/sys/posix/dirent.odin
@@ -1,3 +1,4 @@
+#+build darwin, linux, freebsd, openbsd, netbsd
package posix
import "core:c"
@@ -29,12 +30,12 @@ foreign lib {
panic(string(posix.strerror(posix.errno())))
}
defer posix.free(list)
-
+
entries := list[:ret]
- for entry in entries {
- log.info(entry)
- posix.free(entry)
- }
+ for entry in entries {
+ log.info(entry)
+ posix.free(entry)
+ }
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/scandir.html ]]
*/
@@ -54,15 +55,6 @@ foreign lib {
closedir :: proc(dirp: DIR) -> result ---
/*
- Return a file descriptor referring to the same directory as the dirp argument.
-
- // TODO: this is a macro on NetBSD?
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/dirfd.html ]]
- */
- dirfd :: proc(dirp: DIR) -> FD ---
-
- /*
Equivalent to the opendir() function except that the directory is specified by a file descriptor
rather than by a name.
The file offset associated with the file descriptor at the time of the call determines
@@ -89,16 +81,16 @@ foreign lib {
Returns nil when the end is reached or an error occurred (which sets errno).
Example:
- posix.set_errno(.NONE)
- entry := posix.readdir(dirp)
- if entry == nil {
- if errno := posix.errno(); errno != .NONE {
- panic(string(posix.strerror(errno)))
- } else {
- fmt.println("end of directory stream")
- }
- } else {
- fmt.println(entry)
+ posix.set_errno(.NONE)
+ entry := posix.readdir(dirp)
+ if entry == nil {
+ if errno := posix.errno(); errno != .NONE {
+ panic(string(posix.strerror(errno)))
+ } else {
+ fmt.println("end of directory stream")
+ }
+ } else {
+ fmt.println(entry)
}
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html ]]
@@ -160,11 +152,36 @@ when ODIN_OS == .NetBSD {
@(private) LSCANDIR :: "__scandir30"
@(private) LOPENDIR :: "__opendir30"
@(private) LREADDIR :: "__readdir30"
+
+ /*
+ Return a file descriptor referring to the same directory as the dirp argument.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/dirfd.html ]]
+ */
+ dirfd :: proc "c" (dirp: DIR) -> FD {
+ _dirdesc :: struct {
+ dd_fd: FD,
+
+ // more stuff...
+ }
+
+ return (^_dirdesc)(dirp).dd_fd
+ }
+
} else {
@(private) LALPHASORT :: "alphasort" + INODE_SUFFIX
@(private) LSCANDIR :: "scandir" + INODE_SUFFIX
@(private) LOPENDIR :: "opendir" + INODE_SUFFIX
@(private) LREADDIR :: "readdir" + INODE_SUFFIX
+
+ foreign lib {
+ /*
+ Return a file descriptor referring to the same directory as the dirp argument.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/dirfd.html ]]
+ */
+ dirfd :: proc(dirp: DIR) -> FD ---
+ }
}
when ODIN_OS == .Darwin {
@@ -193,13 +210,21 @@ when ODIN_OS == .Darwin {
} else when ODIN_OS == .NetBSD {
dirent :: struct {
- d_ino: ino_t, /* [PSX] file number of entry */
- d_reclen: c.uint16_t, /* length of this record */
- d_namelen: c.uint16_t, /* length of string in d_name */
- d_type: D_Type, /* file type */
- d_name: [512]c.char `fmt:"s,0"`, /* [PSX] entry name */
+ d_ino: ino_t, /* [PSX] file number of entry */
+ d_reclen: c.uint16_t, /* length of this record */
+ d_namelen: c.uint16_t, /* length of string in d_name */
+ d_type: D_Type, /* file type */
+ d_name: [512]c.char `fmt:"s,0"`, /* [PSX] entry name */
}
-} else {
- #panic("posix is unimplemented for the current target")
+} 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 */
+ }
+
}
diff --git a/core/sys/posix/dlfcn.odin b/core/sys/posix/dlfcn.odin
index 0ddc41337..e84b29d79 100644
--- a/core/sys/posix/dlfcn.odin
+++ b/core/sys/posix/dlfcn.odin
@@ -1,3 +1,4 @@
+#+build darwin, linux, freebsd, openbsd, netbsd
package posix
import "core:c"
@@ -111,7 +112,14 @@ when ODIN_OS == .Darwin {
RTLD_LOCAL :: RTLD_Flags{RTLD_Flag_Bits(log2(_RTLD_LOCAL))}
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ RTLD_LAZY :: 0x001
+ RTLD_NOW :: 0x002
+ RTLD_GLOBAL :: 0x100
+
+ _RTLD_LOCAL :: 0
+ RTLD_LOCAL :: RTLD_Flags{}
+
}
diff --git a/core/sys/posix/errno.odin b/core/sys/posix/errno.odin
index 4ef10aadf..9bc77f12e 100644
--- a/core/sys/posix/errno.odin
+++ b/core/sys/posix/errno.odin
@@ -1,3 +1,4 @@
+#+build windows, darwin, linux, freebsd, openbsd, netbsd
package posix
import "core:c"
@@ -141,7 +142,7 @@ when ODIN_OS == .Darwin {
EMLINK :: 31
EPIPE :: 32
EAGAIN :: 35
- EWOULDBLOCK :: 35
+ EWOULDBLOCK :: EAGAIN
EINPROGRESS :: 36
EALREADY :: 37
ENOTSOCK :: 38
@@ -151,7 +152,7 @@ when ODIN_OS == .Darwin {
ENOPROTOOPT :: 42
EPROTONOSUPPORT :: 43
ENOTSUP :: 45
- EOPNOTSUPP :: 45
+ EOPNOTSUPP :: ENOTSUP
EAFNOSUPPORT :: 47
EADDRINUSE :: 48
EADDRNOTAVAIL :: 49
@@ -220,7 +221,7 @@ when ODIN_OS == .Darwin {
EMLINK :: 31
EPIPE :: 32
EAGAIN :: 35
- EWOULDBLOCK :: 35
+ EWOULDBLOCK :: EAGAIN
EINPROGRESS :: 36
EALREADY :: 37
ENOTSOCK :: 38
@@ -230,7 +231,7 @@ when ODIN_OS == .Darwin {
ENOPROTOOPT :: 42
EPROTONOSUPPORT :: 43
ENOTSUP :: 45
- EOPNOTSUPP :: 45
+ EOPNOTSUPP :: ENOTSUP
EAFNOSUPPORT :: 47
EADDRINUSE :: 48
EADDRNOTAVAIL :: 49
@@ -301,7 +302,7 @@ when ODIN_OS == .Darwin {
EMLINK :: 31
EPIPE :: 32
EAGAIN :: 35
- EWOULDBLOCK :: 35
+ EWOULDBLOCK :: EAGAIN
EINPROGRESS :: 36
EALREADY :: 37
ENOTSOCK :: 38
@@ -311,7 +312,7 @@ when ODIN_OS == .Darwin {
ENOPROTOOPT :: 42
EPROTONOSUPPORT :: 43
ENOTSUP :: 45
- EOPNOTSUPP :: 45
+ EOPNOTSUPP :: ENOTSUP
EAFNOSUPPORT :: 47
EADDRINUSE :: 48
EADDRNOTAVAIL :: 49
@@ -367,7 +368,173 @@ when ODIN_OS == .Darwin {
ETIME :: -1
}
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+ EPERM :: 1
+ ENOENT :: 2
+ ESRCH :: 3
+ EINTR :: 4
+ EIO :: 5
+ ENXIO :: 6
+ E2BIG :: 7
+ ENOEXEC :: 8
+ EBADF :: 9
+ ECHILD :: 10
+ EAGAIN :: 11
+ EWOULDBLOCK :: EAGAIN
+ ENOMEM :: 12
+ EACCES :: 13
+ EFAULT :: 14
+ EBUSY :: 16
+ EEXIST :: 17
+ EXDEV :: 18
+ ENODEV :: 19
+ ENOTDIR :: 20
+ EISDIR :: 21
+ EINVAL :: 22
+ ENFILE :: 23
+ EMFILE :: 24
+ ENOTTY :: 25
+ ETXTBSY :: 26
+ EFBIG :: 27
+ ENOSPC :: 28
+ ESPIPE :: 29
+ EROFS :: 30
+ EMLINK :: 31
+ EPIPE :: 32
+
+ EDEADLK :: 35
+ ENAMETOOLONG :: 36
+ ENOLCK :: 37
+ ENOSYS :: 38
+ ENOTEMPTY :: 39
+ ELOOP :: 40
+ ENOMSG :: 42
+ EIDRM :: 43
+
+ ENOSTR :: 60
+ ENODATA :: 61
+ ETIME :: 62
+ ENOSR :: 63
+
+ ENOLINK :: 67
+
+ EPROTO :: 71
+ EMULTIHOP :: 72
+ EBADMSG :: 74
+ EOVERFLOW :: 75
+
+ ENOTSOCK :: 88
+ EDESTADDRREQ :: 89
+ EMSGSIZE :: 90
+ EPROTOTYPE :: 91
+ ENOPROTOOPT :: 92
+ EPROTONOSUPPORT :: 93
+
+ EOPNOTSUPP :: 95
+ ENOTSUP :: EOPNOTSUPP
+ EAFNOSUPPORT :: 97
+ EADDRINUSE :: 98
+ EADDRNOTAVAIL :: 99
+ ENETDOWN :: 100
+ ENETUNREACH :: 101
+ ENETRESET :: 102
+ ECONNABORTED :: 103
+ ECONNRESET :: 104
+ ENOBUFS :: 105
+ EISCONN :: 106
+ ENOTCONN :: 107
+
+ ETIMEDOUT :: 110
+ ECONNREFUSED :: 111
+
+ EHOSTUNREACH :: 113
+ EALREADY :: 114
+ EINPROGRESS :: 115
+ ESTALE :: 116
+
+ EDQUOT :: 122
+ ECANCELED :: 125
+
+ EOWNERDEAD :: 130
+ ENOTRECOVERABLE :: 131
+} else when ODIN_OS == .Windows {
+ E2BIG :: 7
+ EACCES :: 13
+ EADDRINUSE :: 100
+ EADDRNOTAVAIL :: 101
+ EAFNOSUPPORT :: 102
+ EAGAIN :: 11
+ EALREADY :: 103
+ EBADF :: 9
+ EBADMSG :: 104
+ EBUSY :: 16
+ ECANCELED :: 105
+ ECHILD :: 10
+ ECONNABORTED :: 106
+ ECONNREFUSED :: 107
+ ECONNRESET :: 108
+ EDEADLK :: 36
+ EDESTADDRREQ :: 109
+ EDQUOT :: -1 // NOTE: not defined
+ EEXIST :: 17
+ EFAULT :: 14
+ EFBIG :: 27
+ EHOSTUNREACH :: 110
+ EIDRM :: 111
+ EINPROGRESS :: 112
+ EINTR :: 4
+ EINVAL :: 22
+ EIO :: 5
+ EISCONN :: 113
+ EISDIR :: 21
+ ELOOP :: 114
+ EMFILE :: 24
+ EMLINK :: 31
+ EMSGSIZE :: 115
+ EMULTIHOP :: -1 // NOTE: not defined
+ ENAMETOOLONG :: 38
+ ENETDOWN :: 116
+ ENETRESET :: 117
+ ENETUNREACH :: 118
+ ENFILE :: 23
+ ENOBUFS :: 119
+ ENODATA :: 120
+ ENODEV :: 19
+ ENOENT :: 2
+ ENOEXEC :: 8
+ ENOLCK :: 39
+ ENOLINK :: 121
+ ENOMEM :: 12
+ ENOMSG :: 122
+ ENOPROTOOPT :: 123
+ ENOSPC :: 28
+ ENOSR :: 124
+ ENOSTR :: 125
+ ENOSYS :: 40
+ ENOTCONN :: 126
+ ENOTDIR :: 20
+ ENOTEMPTY :: 41
+ ENOTRECOVERABLE :: 127
+ ENOTSOCK :: 128
+ ENOTSUP :: 129
+ ENOTTY :: 25
+ ENXIO :: 6
+ EOPNOTSUPP :: 130
+ EOVERFLOW :: 132
+ EOWNERDEAD :: 133
+ EPERM :: 1
+ EPIPE :: 32
+ EPROTO :: 134
+ EPROTONOSUPPORT :: 135
+ EPROTOTYPE :: 136
+ EROFS :: 30
+ ESPIPE :: 29
+ ESRCH :: 3
+ ESTALE :: -1 // NOTE: not defined
+ ETIME :: 137
+ ETIMEDOUT :: 138
+ ETXTBSY :: 139
+ EWOULDBLOCK :: 140
+ EXDEV :: 18
}
diff --git a/core/sys/posix/fcntl.odin b/core/sys/posix/fcntl.odin
index ca030a9a5..d948af600 100644
--- a/core/sys/posix/fcntl.odin
+++ b/core/sys/posix/fcntl.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, openbsd, freebsd, netbsd
package posix
import "core:c"
@@ -92,9 +93,6 @@ Lock_Type :: enum c.short {
WRLCK = F_WRLCK,
}
-// Assertions made to unify this bit set.
-#assert(O_RDONLY == 0)
-
O_Flag_Bits :: enum c.int {
// Sets FD_CLOEXEC on the file descriptor.
CLOEXEC = log2(O_CLOEXEC),
@@ -107,11 +105,11 @@ O_Flag_Bits :: enum c.int {
// If terminal device, do not make it the controlling terminal for the process.
NOCTTY = log2(O_NOCTTY),
// Don't follow symbolic links, fail with errno ELOOP.
- NOFOLLOW = log2(O_NOFOLOW),
+ NOFOLLOW = log2(O_NOFOLLOW),
// If exists and regular, truncate the length to 0.
TRUNC = log2(O_TRUNC),
- // NOTE: use with `posix.O_TTY_INIT + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in
+ // NOTE: use with `posix.O_TTY_INIT + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in
// this bit set enum because it is 0 on some platforms and a value on others.
// TTY_INIT = O_TTY_INIT,
@@ -123,7 +121,8 @@ O_Flag_Bits :: enum c.int {
NONBLOCK = log2(O_NONBLOCK),
// Write I/O shall complete as defined by synchronized I/O file integrity completion.
SYNC = log2(O_SYNC),
- // NOTE: use with `posix.O_RSYNC + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in
+
+ // NOTE: use with `posix.O_RSYNC + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in
// this bit set enum because it is 0 on some platforms and a value on others.
// RSYNC = O_RSYNC,
@@ -135,11 +134,10 @@ O_Flag_Bits :: enum c.int {
WRONLY = log2(O_WRONLY),
// Reading only.
// RDONLY = 0, // Default
-
}
+
O_Flags :: bit_set[O_Flag_Bits; c.int]
-// A mask of all the access mode bits.
O_ACCMODE :: O_Flags{ .EXEC, .RDWR, .WRONLY }
AT_Flag_Bits :: enum c.int {
@@ -152,8 +150,8 @@ AT_Flags :: bit_set[AT_Flag_Bits; c.int]
when ODIN_OS == .Darwin {
- off_t :: distinct c.int64_t
- pid_t :: distinct c.int32_t
+ off_t :: distinct c.int64_t
+ pid_t :: distinct c.int32_t
F_DUPFD :: 0
F_DUPFD_CLOEXEC :: 67
@@ -178,7 +176,7 @@ when ODIN_OS == .Darwin {
O_DIRECTORY :: 0x00100000
O_EXCL :: 0x00000800
O_NOCTTY :: 0x00020000
- O_NOFOLOW :: 0x00000100
+ O_NOFOLLOW :: 0x00000100
O_TRUNC :: 0x00000400
_O_TTY_INIT :: 0
@@ -189,16 +187,16 @@ when ODIN_OS == .Darwin {
O_NONBLOCK :: 0x00000004
O_SYNC :: 0x0080
- _O_RSYNC :: 0
- O_RSYNC :: O_Flags{}
+ _O_RSYNC :: 0
+ O_RSYNC :: O_Flags{}
- O_EXEC :: 0x40000000
- O_RDONLY :: 0
- O_RDWR :: 0x0002
- O_WRONLY :: 0x0001
+ O_EXEC :: 0x40000000
+ O_RDONLY :: 0
+ O_RDWR :: 0x0002
+ O_WRONLY :: 0x0001
_O_SEARCH :: O_EXEC | O_DIRECTORY
- O_SEARCH :: O_Flags{ .EXEC, .DIRECTORY }
+ O_SEARCH :: O_Flags{.EXEC, .DIRECTORY}
AT_FDCWD: FD: -2
@@ -217,8 +215,8 @@ when ODIN_OS == .Darwin {
} else when ODIN_OS == .FreeBSD {
- off_t :: distinct c.int64_t
- pid_t :: distinct c.int32_t
+ off_t :: distinct c.int64_t
+ pid_t :: distinct c.int32_t
F_DUPFD :: 0
F_DUPFD_CLOEXEC :: 17
@@ -243,7 +241,7 @@ when ODIN_OS == .Darwin {
O_DIRECTORY :: 0x00020000
O_EXCL :: 0x0800
O_NOCTTY :: 0x8000
- O_NOFOLOW :: 0x0100
+ O_NOFOLLOW :: 0x0100
O_TRUNC :: 0x0400
_O_TTY_INIT :: 0x00080000
@@ -256,10 +254,10 @@ when ODIN_OS == .Darwin {
_O_RSYNC :: 0
O_RSYNC :: O_Flags{} // NOTE: not defined in headers
- O_EXEC :: 0x00040000
- O_RDONLY :: 0
- O_RDWR :: 0x0002
- O_WRONLY :: 0x0001
+ O_EXEC :: 0x00040000
+ O_RDONLY :: 0
+ O_RDWR :: 0x0002
+ O_WRONLY :: 0x0001
_O_SEARCH :: O_EXEC
O_SEARCH :: O_Flags{ .EXEC }
@@ -282,8 +280,8 @@ when ODIN_OS == .Darwin {
} else when ODIN_OS == .NetBSD {
- off_t :: distinct c.int64_t
- pid_t :: distinct c.int32_t
+ off_t :: distinct c.int64_t
+ pid_t :: distinct c.int32_t
F_DUPFD :: 0
F_DUPFD_CLOEXEC :: 12
@@ -308,7 +306,7 @@ when ODIN_OS == .Darwin {
O_DIRECTORY :: 0x0020000
O_EXCL :: 0x0800
O_NOCTTY :: 0x8000
- O_NOFOLOW :: 0x0100
+ O_NOFOLLOW :: 0x0100
O_TRUNC :: 0x0400
_O_TTY_INIT :: 0
@@ -319,14 +317,14 @@ when ODIN_OS == .Darwin {
O_NONBLOCK :: 0x0004
O_SYNC :: 0x0080
- _O_RSYNC :: 0x0002
- O_RSYNC :: O_Flags{O_Flag_Bits(log2(_O_RSYNC))}
+ _O_RSYNC :: 0x0002
+ O_RSYNC :: O_Flags{O_Flag_Bits(log2(_O_RSYNC))}
- O_EXEC :: 0x04000000
- O_RDONLY :: 0
- O_RDWR :: 0x0002
- O_WRONLY :: 0x0001
+ O_EXEC :: 0x04000000
+ O_RDONLY :: 0
+ O_RDWR :: 0x0002
+ O_WRONLY :: 0x0001
_O_SEARCH :: 0x00800000
O_SEARCH :: O_Flags{O_Flag_Bits(log2(_O_SEARCH))}
@@ -347,8 +345,8 @@ when ODIN_OS == .Darwin {
}
} else when ODIN_OS == .OpenBSD {
- off_t :: distinct c.int64_t
- pid_t :: distinct c.int32_t
+ off_t :: distinct c.int64_t
+ pid_t :: distinct c.int32_t
F_DUPFD :: 0
F_DUPFD_CLOEXEC :: 10
@@ -373,7 +371,7 @@ when ODIN_OS == .Darwin {
O_DIRECTORY :: 0x20000
O_EXCL :: 0x0800
O_NOCTTY :: 0x8000
- O_NOFOLOW :: 0x0100
+ O_NOFOLLOW :: 0x0100
O_TRUNC :: 0x0400
_O_TTY_INIT :: 0
@@ -384,13 +382,13 @@ when ODIN_OS == .Darwin {
O_NONBLOCK :: 0x0004
O_SYNC :: 0x0080
- _O_RSYNC :: O_SYNC
- O_RSYNC :: O_Flags{ .SYNC }
+ _O_RSYNC :: O_SYNC
+ O_RSYNC :: O_Flags{.SYNC}
- O_EXEC :: 0x04000000 // NOTE: not defined in the headers
- O_RDONLY :: 0
- O_RDWR :: 0x0002
- O_WRONLY :: 0x0001
+ 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
@@ -410,6 +408,70 @@ when ODIN_OS == .Darwin {
l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
}
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ off_t :: distinct c.int64_t
+ pid_t :: distinct c.int
+
+ F_DUPFD :: 0
+ F_GETFD :: 1
+ F_SETFD :: 2
+ F_GETFL :: 3
+ F_SETFL :: 4
+ F_GETLK :: 5
+ F_SETLK :: 6
+ F_SETLKW :: 7
+ F_SETOWN :: 8
+ F_GETOWN :: 9
+ F_RDLCK :: 0
+ F_UNLCK :: 2
+ F_WRLCK :: 1
+
+ F_DUPFD_CLOEXEC :: 1030
+
+ FD_CLOEXEC :: 1
+
+ O_CREAT :: 0o0_000_100
+ O_EXCL :: 0o0_000_200
+ O_NOCTTY :: 0o0_000_400
+ O_TRUNC :: 0o0_001_000
+ O_DIRECTORY :: 0o0_200_000
+ O_NOFOLLOW :: 0o0_400_000
+ O_CLOEXEC :: 0o2_000_000
+
+ _O_TTY_INIT :: 0
+ O_TTY_INIT :: O_Flags{}
+
+ O_APPEND :: 0o0_002_000
+ O_NONBLOCK :: 0o0_004_000
+ O_DSYNC :: 0o0_010_000
+ O_SYNC :: 0o4_010_000
+
+ _O_RSYNC :: 0
+ O_RSYNC :: O_Flags{}
+
+ O_EXEC :: 0x04000000 // NOTE: not defined in the headers
+
+ O_RDONLY :: 0
+ O_WRONLY :: 0o1
+ O_RDWR :: 0o2
+
+ _O_SEARCH :: 0
+ O_SEARCH :: O_Flags{}
+
+ AT_FDCWD: FD: -100
+
+ AT_EACCESS :: 0x200
+ AT_SYMLINK_NOFOLLOW :: 0x100
+ AT_SYMLINK_FOLLOW :: 0x400
+ AT_REMOVEDIR :: 0x200
+
+ 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. */
+ }
+
}
diff --git a/core/sys/posix/fnmatch.odin b/core/sys/posix/fnmatch.odin
index 9e54972e7..2d582705c 100644
--- a/core/sys/posix/fnmatch.odin
+++ b/core/sys/posix/fnmatch.odin
@@ -1,3 +1,4 @@
+#+build darwin, linux, openbsd, freebsd, netbsd
package posix
import "core:c"
@@ -53,6 +54,12 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
FNM_PERIOD :: 0x04
FNM_NOESCAPE :: 0x01
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ FNM_NOMATCH :: 1
+
+ FNM_PATHNAME :: 0x01
+ FNM_NOESCAPE :: 0x02
+ FNM_PERIOD :: 0x04
+
}
diff --git a/core/sys/posix/glob.odin b/core/sys/posix/glob.odin
index 4f41d83db..7c8009a59 100644
--- a/core/sys/posix/glob.odin
+++ b/core/sys/posix/glob.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -112,7 +113,7 @@ when ODIN_OS == .Darwin {
glob_t :: struct {
gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */
- gl_matchc: c.size_t, /* count of paths matching pattern */
+ gl_matchc: c.size_t, /* count of paths matching pattern */
gl_offs: c.size_t, /* [PSX] slots to reserve at the beginning of gl_pathv */
gl_flags: Glob_Flags, /* copy of flags parameter to glob */
gl_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */
@@ -144,7 +145,7 @@ when ODIN_OS == .Darwin {
glob_t :: struct {
gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */
- gl_matchc: c.size_t, /* count of paths matching pattern */
+ gl_matchc: c.size_t, /* count of paths matching pattern */
gl_offs: c.size_t, /* [PSX] slots to reserve at the beginning of gl_pathv */
gl_flags: Glob_Flags, /* copy of flags parameter to glob */
gl_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */
@@ -174,6 +175,33 @@ when ODIN_OS == .Darwin {
GLOB_NOMATCH :: -3
GLOB_NOSPACE :: -1
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ glob_t :: struct {
+ gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */
+ gl_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */
+ gl_offs: c.size_t, /* [PSX] slots to reserve at the beginning of gl_pathv */
+ gl_flags: Glob_Flags, /* copy of flags parameter to glob */
+
+ // Non-standard alternate file system access functions:
+
+ gl_closedir: proc "c" (dirp: DIR),
+ gl_readdir: proc "c" (dirp: DIR) -> ^dirent,
+ gl_opendir: proc "c" (path: cstring) -> DIR,
+ gl_lstat: proc "c" (path: cstring, buf: ^stat_t) -> result,
+ gl_stat: proc "c" (path: cstring, buf: ^stat_t) -> result,
+ }
+
+ GLOB_ERR :: 1 << 0
+ GLOB_MARK :: 1 << 1
+ GLOB_NOSORT :: 1 << 2
+ GLOB_DOOFFS :: 1 << 3
+ GLOB_NOCHECK :: 1 << 4
+ GLOB_APPEND :: 1 << 5
+ GLOB_NOESCAPE :: 1 << 6
+
+ GLOB_NOSPACE :: 1
+ GLOB_ABORTED :: 2
+ GLOB_NOMATCH :: 3
+
}
diff --git a/core/sys/posix/grp.odin b/core/sys/posix/grp.odin
index c8a39de6a..956ed148b 100644
--- a/core/sys/posix/grp.odin
+++ b/core/sys/posix/grp.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -114,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 {
+when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
gid_t :: distinct c.uint32_t
@@ -125,6 +126,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
gr_mem: [^]cstring, /* [PSX] group members */
}
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/iconv.odin b/core/sys/posix/iconv.odin
index 59248890f..f7447be9e 100644
--- a/core/sys/posix/iconv.odin
+++ b/core/sys/posix/iconv.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
diff --git a/core/sys/posix/langinfo.odin b/core/sys/posix/langinfo.odin
index 24ecc917a..3c001aee0 100644
--- a/core/sys/posix/langinfo.odin
+++ b/core/sys/posix/langinfo.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -238,7 +239,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD {
ABDAY_4 :: 16
ABDAY_5 :: 17
ABDAY_6 :: 18
- ABDAY_7 :: 19
+ ABDAY_7 :: 19
MON_1 :: 20
MON_2 :: 21
@@ -278,7 +279,91 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD {
YESEXPR :: 47
NOEXPR :: 49
- CRNCYSTR :: 50
+ CRNCYSTR :: 50
+
+} else when ODIN_OS == .Linux {
+
+ // NOTE: declared with `_t` so we can enumerate the real `nl_info`.
+ nl_item_t :: distinct c.int
+
+ // NOTE: All these values are set in an enum on the Linux implementation.
+ // Some depend on locale.h contants (bits/locale.h to be precise).
+
+ // NOTE: ABDAY_1 is set to LC_TIME << 16 (LC_TIME is 2) on the enum group of
+ // the Linux implementation.
+ ABDAY_1 :: 0x20_000
+ ABDAY_2 :: 0x20_001
+ ABDAY_3 :: 0x20_002
+ ABDAY_4 :: 0x20_003
+ ABDAY_5 :: 0x20_004
+ ABDAY_6 :: 0x20_005
+ ABDAY_7 :: 0x20_006
+
+ DAY_1 :: 0x20_007
+ DAY_2 :: 0x20_008
+ DAY_3 :: 0x20_009
+ DAY_4 :: 0x20_00A
+ DAY_5 :: 0x20_00B
+ DAY_6 :: 0x20_00C
+ DAY_7 :: 0x20_00D
+
+ ABMON_1 :: 0x20_00E
+ ABMON_2 :: 0x20_010
+ ABMON_3 :: 0x20_011
+ ABMON_4 :: 0x20_012
+ ABMON_5 :: 0x20_013
+ ABMON_6 :: 0x20_014
+ ABMON_7 :: 0x20_015
+ ABMON_8 :: 0x20_016
+ ABMON_9 :: 0x20_017
+ ABMON_10 :: 0x20_018
+ ABMON_11 :: 0x20_019
+ ABMON_12 :: 0x20_01A
+
+ MON_1 :: 0x20_01B
+ MON_2 :: 0x20_01C
+ MON_3 :: 0x20_01D
+ MON_4 :: 0x20_01E
+ MON_5 :: 0x20_020
+ MON_6 :: 0x20_021
+ MON_7 :: 0x20_022
+ MON_8 :: 0x20_023
+ MON_9 :: 0x20_024
+ MON_10 :: 0x20_025
+ MON_11 :: 0x20_026
+ MON_12 :: 0x20_027
+
+ AM_STR :: 0x20_028
+ PM_STR :: 0x20_029
+
+ D_T_FMT :: 0x20_02A
+ D_FMT :: 0x20_02B
+ T_FMT :: 0x20_02C
+ T_FMT_AMPM :: 0x20_02D
+
+ ERA :: 0x20_02E
+ ERA_D_FMT :: 0x20_030
+ ALT_DIGITS :: 0x20_031
+ ERA_D_T_FMT :: 0x20_032
+ ERA_T_FMT :: 0x20_033
+
+ // NOTE: CODESET is the 16th member of the enum group starting with value
+ // LC_CTYPE << 16, LC_CTYPE is 0.
+ CODESET :: 0x0F
+
+ // NOTE: CRNCYSTR is the 16th member of the enum group starting with value
+ // LC_MONETARY << 16, LC_MONETARY is 4.
+ CRNCYSTR :: 0x40_00F
+
+ // NOTE: RADIXCHAR is the 1st member of the enum group starting with value
+ // LC_NUMERIC << 16, LC_NUMERIC is 1.
+ RADIXCHAR :: 0x10_000
+ THOUSEP :: 0x10_001
+
+ // NOTE: YESEXPR is the 1st member of the enum group starting with value
+ // LC_MESSAGES << 16, LC_MESSAGES is 5.
+ YESEXPR :: 0x50_000
+ NOEXPR :: 0x50_001
} else {
#panic("posix is unimplemented for the current target")
diff --git a/core/sys/posix/libgen.odin b/core/sys/posix/libgen.odin
index 99506797e..69176a557 100644
--- a/core/sys/posix/libgen.odin
+++ b/core/sys/posix/libgen.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
when ODIN_OS == .Darwin {
@@ -56,6 +57,7 @@ foreign lib {
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/basename.html ]]
*/
+ @(link_name=LBASENAME)
basename :: proc(path: cstring) -> cstring ---
/*
@@ -72,3 +74,9 @@ foreign lib {
*/
dirname :: proc(path: cstring) -> cstring ---
}
+
+when ODIN_OS == .Linux {
+ @(private) LBASENAME :: "__xpg_basename"
+} else {
+ @(private) LBASENAME :: "basename"
+}
diff --git a/core/sys/posix/limits.odin b/core/sys/posix/limits.odin
index 7bb561215..6680986ad 100644
--- a/core/sys/posix/limits.odin
+++ b/core/sys/posix/limits.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
// limits.h - implementation-defined constants
@@ -454,6 +455,99 @@ when ODIN_OS == .Darwin {
NL_TEXTMAX :: 255
NZERO :: 20
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ // A definition of one of the symbolic constants in the following list shall be omitted from
+ // <limits.h> on specific implementations where the corresponding value is equal to or greater
+ // than the stated minimum, but is unspecified.
+ //
+ // This indetermination might depend on the amount of available memory space on a specific
+ // instance of a specific implementation. The actual value supported by a specific instance shall
+ // be provided by the sysconf() function.
+
+ // AIO_LISTIO_MAX :: sysconf(._AIO_LISTIO_MAX)
+ // AIO_MAX :: sysconf(._AIO_MAX)
+ // AIO_PRIO_DELTA_MAX :: sysconf(._AIO_PRIO_DELTA_MAX)
+ ARG_MAX :: 131_072
+ // ATEXIT_MAX :: sysconf(._ATEXIT_MAX)
+ // CHILD_MAX :: sysconf(._POSIX_ARG_MAX)
+ // DELAYTIMER_MAX :: sysconf(._DELAYTIMER_MAX)
+ // HOST_NAME_MAX :: sysconf(._HOST_NAME_MAX)
+ // IOV_MAX :: sysconf(._XOPEN_IOV_MAX)
+ // LOGIN_NAME_MAX :: sysconf(._LOGIN_NAME_MAX)
+ // MQ_OPEN_MAX :: sysconf(._MQ_OPEN_MAX)
+ // MQ_PRIO_MAX :: sysconf(._MQ_PRIO_MAX)
+ // PAGESIZE :: PAGE_SIZE
+ // PAGE_SIZE :: sysconf(._PAGE_SIZE)
+ PTHREAD_DESTRUCTOR_ITERATIONS :: 4
+ // PTHREAD_KEYS_MAX :: sysconf(._PTHREAD_KEYS_MAX)
+ // PTHREAD_STACK_MIN :: sysconf(._PTHREAD_STACK_MIN)
+ // RTSIG_MAX :: sysconf(._RTSIG_MAX)
+ // SEM_NSEMS_MAX :: sysconf(._SEM_NSEMS_MAX)
+ // SEM_VALUE_MAX :: sysconf(._SEM_VALUE_MAX)
+ // SIGQUEUE_MAX :: sysconf(._SIGQUEUE_MAX)
+ // SS_REPL_MAX :: sysconf(._SS_REPL_MAX)
+ // STREAM_MAX :: sysconf(._STREAM_MAX)
+ // SYMLOOP_MAX :: sysconf(._SYSLOOP_MAX)
+ // TIMER_MAX :: sysconf(._TIMER_MAX)
+ // TRACE_EVENT_NAME_MAX :: sysconf(._TRACE_EVENT_NAME_MAX)
+ // TRACE_NAME_MAX :: sysconf(._TRACE_NAME_MAX)
+ // TRACE_SYS_MAX :: sysconf(._TRACE_SYS_MAX)
+ // TRACE_USER_EVENT_MAX :: sysconf(._TRACE_USER_EVENT_MAX)
+ // TTY_NAME_MAX :: sysconf(._TTY_NAME_MAX)
+ // TZNAME_MAX :: sysconf(._TZNAME_MAX)
+
+ // The values in the following list may be constants within an implementation or may vary from
+ // one pathname to another.
+ // For example, file systems or directories may have different characteristics.
+ //
+ // A definition of one of the symbolic constants in the following list shall be omitted from the
+ // <limits.h> header on specific implementations where the corresponding value is equal to or
+ // greater than the stated minimum, but where the value can vary depending on the file to which
+ // it is applied.
+ // The actual value supported for a specific pathname shall be provided by the pathconf() function.
+
+ // FILESIZEBITS :: pathconf(".", ._FILESIZEBITS)
+ LINK_MAX :: 127
+ MAX_CANON :: 255
+ MAX_INPUT :: 255
+ NAME_MAX :: 255
+ PATH_MAX :: 4096
+ PIPE_BUF :: 4096
+ // POSIX_ALLOC_SIZE_MIN :: sysconf(._POSIX_ALLOC_SIZE_MIN)
+ // POSIX_REC_INCR_XFER_SIZE :: sysconf(._POSIX_REC_INCR_XFER_SIZE)
+ // POSIX_REC_MAX_XFER_SIZE :: sysconf(._POSIX_REC_MAX_XFER_SIZE)
+ // POSIX_REC_MIN_XFER_SIZE :: sysconf(._POSIX_REC_MIN_XFER_SIZE)
+ // POSIX_REC_XFER_ALIGN :: sysconf(._POSIX_REC_XFER_ALIGN)
+ // SYMLINK_MAX :: pathconf(".", ._SYMLINK_MAX)
+
+
+ // The magnitude limitations in the following list shall be fixed by specific implementations.
+ // An application should assume that the value of the symbolic constant defined by <limits.h>
+ // in a specific implementation is the minimum that pertains whenever the application is run
+ // under that implementation.
+ // A specific instance of a specific implementation may increase the value relative to that
+ // supplied by <limits.h> for that implementation.
+ // The actual value supported by a specific instance shall be provided by the sysconf() function.
+
+ BC_BASE_MAX :: 99
+ BC_DIM_MAX :: 2048
+ BC_SCALE_MAX :: 99
+ BC_STRING_MAX :: 1000
+ CHARCLASS_NAME_MAX :: 14
+ COLL_WEIGHTS_MAX :: 2
+ EXPR_NEST_MAX :: 32
+ // LINE_MAX :: sysconf(._LINE_MAX)
+ // NGROUPS_MAX :: sysconf(._NGROUPS_MAX)
+ RE_DUP_MAX :: 255
+
+ // Other limits.
+
+ NL_ARGMAX :: 9
+ NL_LANGMAX :: 32 // 14 on glibc, 32 on musl
+ NL_MSGMAX :: 32_767
+ NL_SETMAX :: 255
+ NL_TEXTMAX :: 2048 // 255 on glibc, 2048 on musl
+ NZERO :: 20
+
}
diff --git a/core/sys/posix/locale.odin b/core/sys/posix/locale.odin
index 1f2a336b5..5b8d7c216 100644
--- a/core/sys/posix/locale.odin
+++ b/core/sys/posix/locale.odin
@@ -1,93 +1,11 @@
+#+build windows, linux, darwin, netbsd, openbsd, freebsd
package posix
-import "core:c"
+import "core:c/libc"
-when ODIN_OS == .Darwin {
- foreign import lib "system:System.framework"
-} else {
- foreign import lib "system:c"
-}
+localeconv :: libc.localeconv
+setlocale :: libc.setlocale
-// locale.h - category macros
+lconv :: libc.lconv
-foreign lib {
- /*
- Sets the components of an object with the type lconv with the values appropriate for the
- formatting of numeric quantities (monetary and otherwise) according to the rules of the current
- locale.
-
- Returns: a pointer to the lconv structure, might be invalidated by subsequent calls to localeconv() and setlocale()
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/localeconv.html ]]
- */
- localeconv :: proc() -> ^lconv ---
-
- /*
- Selects the appropriate piece of the global locale, as specified by the category and locale arguments,
- and can be used to change or query the entire global locale or portions thereof.
-
- Returns: the current locale if `locale` is `nil`, the set locale otherwise
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/setlocale.html ]]
- */
- @(link_name=LSETLOCALE)
- setlocale :: proc(category: Locale_Category, locale: cstring) -> cstring ---
-}
-
-Locale_Category :: enum c.int {
- ALL = LC_ALL,
- COLLATE = LC_COLLATE,
- CTYPE = LC_CTYPE,
- MESSAGES = LC_MESSAGES,
- MONETARY = LC_MONETARY,
- NUMERIC = LC_NUMERIC,
- TIME = LC_TIME,
-}
-
-when ODIN_OS == .NetBSD {
- @(private) LSETLOCALE :: "__setlocale50"
-} else {
- @(private) LSETLOCALE :: "setlocale"
-}
-
-when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
-
- // NOTE: All of these fields are standard ([PSX]).
- lconv :: struct {
- decimal_point: cstring,
- thousand_sep: cstring,
- grouping: cstring,
- int_curr_symbol: cstring,
- currency_symbol: cstring,
- mon_decimal_points: cstring,
- mon_thousands_sep: cstring,
- mon_grouping: cstring,
- positive_sign: cstring,
- negative_sign: cstring,
- int_frac_digits: c.char,
- frac_digits: c.char,
- p_cs_precedes: c.char,
- p_sep_by_space: c.char,
- n_cs_precedes: c.char,
- n_sep_by_space: c.char,
- p_sign_posn: c.char,
- n_sign_posn: c.char,
- int_p_cs_precedes: c.char,
- int_n_cs_precedes: c.char,
- int_p_sep_by_space: c.char,
- int_n_sep_by_space: c.char,
- int_p_sign_posn: c.char,
- int_n_sign_posn: c.char,
- }
-
- LC_ALL :: 0
- LC_COLLATE :: 1
- LC_CTYPE :: 2
- LC_MESSAGES :: 6
- LC_MONETARY :: 3
- LC_NUMERIC :: 4
- LC_TIME :: 5
-
-} else {
- #panic("posix is unimplemented for the current target")
-}
+Locale_Category :: libc.Locale_Category
diff --git a/core/sys/posix/monetary.odin b/core/sys/posix/monetary.odin
index b4f0c31ee..ee342e211 100644
--- a/core/sys/posix/monetary.odin
+++ b/core/sys/posix/monetary.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
diff --git a/core/sys/posix/net_if.odin b/core/sys/posix/net_if.odin
index aaeb5088a..774d11b72 100644
--- a/core/sys/posix/net_if.odin
+++ b/core/sys/posix/net_if.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -44,7 +45,7 @@ foreign lib {
if_freenameindex :: proc(ptr: ^if_nameindex_t) ---
}
-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 == .Linux {
// NOTE: `_t` suffix added due to name conflict.
@@ -55,6 +56,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
IF_NAMESIZE :: 16
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/netdb.odin b/core/sys/posix/netdb.odin
index 7570f9a22..79e13a140 100644
--- a/core/sys/posix/netdb.odin
+++ b/core/sys/posix/netdb.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -318,7 +319,7 @@ Info_Errno :: enum c.int {
OVERFLOW = EAI_OVERFLOW,
}
-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 == .OpenBSD || ODIN_OS == .Linux {
hostent :: struct {
h_name: cstring, /* [PSX] official name of host */
@@ -412,9 +413,28 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
NI_NUMERICSERV :: 2
NI_NUMERICSCOPE :: 32
NI_DGRAM :: 16
+
+ } else when ODIN_OS == .Linux {
+
+ AI_PASSIVE :: 0x001
+ AI_CANONNAME :: 0x002
+ AI_NUMERICHOST :: 0x004
+ AI_NUMERICSERV :: 0x400
+ AI_V4MAPPED :: 0x008
+ AI_ALL :: 0x010
+ AI_ADDRCONFIG :: 0x020
+
+ NI_NOFQDN :: 4
+ NI_NUMERICHOST :: 1
+ NI_NAMEREQD :: 8
+ NI_NUMERICSERV :: 2
+ NI_NUMERICSCOPE :: 0x100
+ NI_DGRAM :: 16
+
}
when ODIN_OS == .OpenBSD {
+
EAI_AGAIN :: -3
EAI_BADFLAGS :: -1
EAI_FAIL :: -4
@@ -425,7 +445,22 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
EAI_SOCKTYPE :: -7
EAI_SYSTEM :: -11
EAI_OVERFLOW :: -14
+
+ } else when ODIN_OS == .Linux {
+
+ EAI_AGAIN :: -3
+ EAI_BADFLAGS :: -1
+ EAI_FAIL :: -4
+ EAI_FAMILY :: -6
+ EAI_MEMORY :: -10
+ EAI_NONAME :: -2
+ EAI_SERVICE :: -8
+ EAI_SOCKTYPE :: -7
+ EAI_SYSTEM :: -11
+ EAI_OVERFLOW :: -12
+
} else {
+
EAI_AGAIN :: 2
EAI_BADFLAGS :: 3
EAI_FAIL :: 4
@@ -438,6 +473,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
EAI_OVERFLOW :: 14
}
-}else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/netinet_in.odin b/core/sys/posix/netinet_in.odin
index 3926c5288..a2cf904ce 100644
--- a/core/sys/posix/netinet_in.odin
+++ b/core/sys/posix/netinet_in.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -30,7 +31,7 @@ Protocol :: enum c.int {
UDP = IPPROTO_UDP,
}
-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 == .Linux {
in_addr :: struct {
s_addr: in_addr_t, /* [PSX] big endian address */
@@ -44,26 +45,68 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
},
}
- 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,
- }
-
- sockaddr_in6 :: struct {
- sin6_len: c.uint8_t,
- sin6_family: sa_family_t, /* [PSX] AF_INET6 (but a smaller size) */
- sin6_port: in_port_t, /* [PSX] port number */
- sin6_flowinfo: c.uint32_t, /* [PSX] IPv6 traffic class and flow information */
- sin6_addr: in6_addr, /* [PSX] IPv6 address */
- sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */
- }
+ when ODIN_OS == .Linux {
+
+ sockaddr_in :: struct {
+ 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,
+ }
+
+ sockaddr_in6 :: struct {
+ sin6_family: sa_family_t, /* [PSX] AF_INET6 (but a smaller size) */
+ sin6_port: in_port_t, /* [PSX] port number */
+ sin6_flowinfo: u32be, /* [PSX] IPv6 traffic class and flow information */
+ sin6_addr: in6_addr, /* [PSX] IPv6 address */
+ sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */
+ }
+
+ ipv6_mreq :: struct {
+ ipv6mr_multiaddr: in6_addr, /* [PSX] IPv6 multicast address */
+ ipv6mr_interface: c.uint, /* [PSX] interface index */
+ }
+
+ IPV6_MULTICAST_IF :: 17
+ IPV6_UNICAST_HOPS :: 16
+ IPV6_MULTICAST_HOPS :: 18
+ IPV6_MULTICAST_LOOP :: 19
+ IPV6_JOIN_GROUP :: 20
+ IPV6_LEAVE_GROUP :: 21
+ IPV6_V6ONLY :: 26
+
+ } else {
+
+ 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,
+ }
+
+ sockaddr_in6 :: struct {
+ sin6_len: c.uint8_t,
+ sin6_family: sa_family_t, /* [PSX] AF_INET6 (but a smaller size) */
+ sin6_port: in_port_t, /* [PSX] port number */
+ sin6_flowinfo: c.uint32_t, /* [PSX] IPv6 traffic class and flow information */
+ sin6_addr: in6_addr, /* [PSX] IPv6 address */
+ sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */
+ }
+
+ ipv6_mreq :: struct {
+ ipv6mr_multiaddr: in6_addr, /* [PSX] IPv6 multicast address */
+ 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
- ipv6_mreq :: struct {
- ipv6mr_multiaddr: in6_addr, /* [PSX] IPv6 multicast address */
- ipv6mr_interface: c.uint, /* [PSX] interface index */
}
IPPROTO_IP :: 0
@@ -76,14 +119,6 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
INADDR_ANY :: 0x00000000
INADDR_BROADCAST :: 0xFFFFFFFF
- 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
-
IN6_IS_ADDR_UNSPECIFIED :: #force_inline proc "contextless" (a: in6_addr) -> b32 {
return a.s6_addr == 0
}
@@ -194,6 +229,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
)
}
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/netinet_tcp.odin b/core/sys/posix/netinet_tcp.odin
index ecd084b38..b1da12f5e 100644
--- a/core/sys/posix/netinet_tcp.odin
+++ b/core/sys/posix/netinet_tcp.odin
@@ -1,11 +1,10 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
// netinet/tcp.h - definitions for the Internet Transmission Control Protocol (TCP)
-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 == .Linux {
TCP_NODELAY :: 0x01
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/poll.odin b/core/sys/posix/poll.odin
index 3e825e009..9c3b8b081 100644
--- a/core/sys/posix/poll.odin
+++ b/core/sys/posix/poll.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "base:intrinsics"
@@ -72,7 +73,24 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
POLLHUP :: 0x0010
POLLNVAL :: 0x0020
-} else {
- #panic("posix is unimplemented for the current target")
-}
+} else when ODIN_OS == .Linux {
+
+ pollfd :: struct {
+ fd: FD, /* [PSX] the following descriptor being polled */
+ events: Poll_Event, /* [PSX] the input event flags */
+ revents: Poll_Event, /* [PSX] the output event flags */
+ }
+ POLLIN :: 0x0001
+ POLLRDNORM :: 0x0040
+ POLLRDBAND :: 0x0080
+ POLLPRI :: 0x0002
+ POLLOUT :: 0x0004
+ POLLWRNORM :: 0x0100
+ POLLWRBAND :: 0x0200
+
+ POLLERR :: 0x0008
+ POLLHUP :: 0x0010
+ POLLNVAL :: 0x0020
+
+}
diff --git a/core/sys/posix/posix.odin b/core/sys/posix/posix.odin
index 5cb4122a6..d56217407 100644
--- a/core/sys/posix/posix.odin
+++ b/core/sys/posix/posix.odin
@@ -1,5 +1,7 @@
/*
-Bindings for most POSIX APIs.
+Raw bindings for most POSIX APIs.
+
+Targets glibc and musl compatibility.
APIs that have been left out are due to not being useful,
being fully replaced (and better) by other Odin packages,
@@ -9,6 +11,9 @@ The struct fields that are cross-platform are documented with `[PSX]`.
Accessing these fields on one target should be the same on others.
Other fields are implementation specific.
+The parts of POSIX that Windows implements are also supported here, but
+other symbols are undefined on Windows targets.
+
Most macros have been reimplemented in Odin with inlined functions.
Unimplemented headers:
diff --git a/core/sys/posix/pthread.odin b/core/sys/posix/pthread.odin
index e264f6f6c..490064da6 100644
--- a/core/sys/posix/pthread.odin
+++ b/core/sys/posix/pthread.odin
@@ -1,10 +1,11 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
when ODIN_OS == .Darwin {
foreign import lib "system:System.framework"
-} else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD {
+} else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .Linux {
foreign import lib "system:pthread"
} else {
foreign import lib "system:c"
@@ -354,12 +355,16 @@ Thread_Scope :: enum c.int {
}
Cancel_State :: enum c.int {
+ // Cancel takes place at next cancellation point.
ENABLE = PTHREAD_CANCEL_ENABLE,
+ // Cancel postponed.
DISABLE = PTHREAD_CANCEL_DISABLE,
}
Cancel_Type :: enum c.int {
+ // Cancel waits until cancellation point.
DEFERRED = PTHREAD_CANCEL_DEFERRED,
+ // Cancel occurs immediately.
ASYNCHRONOUS = PTHREAD_CANCEL_ASYNCHRONOUS,
}
@@ -371,6 +376,12 @@ when ODIN_OS == .Darwin {
PTHREAD_CANCEL_DISABLE :: 0x00
PTHREAD_CANCEL_ENABLE :: 0x01
+ // PTHREAD_CANCEL_ASYNCHRONOUS :: 1
+ // PTHREAD_CANCEL_DEFERRED :: 0
+ //
+ // PTHREAD_CANCEL_DISABLE :: 1
+ // PTHREAD_CANCEL_ENABLE :: 0
+
PTHREAD_CANCELED :: rawptr(uintptr(1))
PTHREAD_CREATE_DETACHED :: 2
@@ -398,6 +409,16 @@ when ODIN_OS == .Darwin {
pthread_key_t :: distinct c.ulong
+ pthread_mutex_t :: struct {
+ __sig: c.long,
+ __opaque: [56]c.char,
+ }
+
+ pthread_cond_t :: struct {
+ __sig: c.long,
+ __opaque: [40]c.char,
+ }
+
sched_param :: struct {
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
_: [4]c.char,
@@ -423,18 +444,28 @@ when ODIN_OS == .Darwin {
PTHREAD_PRIO_NONE :: 0
PTHREAD_PRIO_PROTECT :: 2
- PTHREAD_PROCESS_SHARED :: 0
- PTHREAD_PROCESS_PRIVATE :: 1
+ PTHREAD_PROCESS_SHARED :: 1
+ PTHREAD_PROCESS_PRIVATE :: 0
PTHREAD_SCOPE_PROCESS :: 0
PTHREAD_SCOPE_SYSTEM :: 2
pthread_t :: distinct u64
- pthread_attr_t :: distinct rawptr
+ pthread_attr_t :: struct #align(8) {
+ _: [8]byte,
+ }
pthread_key_t :: distinct c.int
+ pthread_mutex_t :: struct #align(8) {
+ _: [8]byte,
+ }
+
+ pthread_cond_t :: struct #align(8) {
+ _: [8]byte,
+ }
+
sched_param :: struct {
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
}
@@ -475,6 +506,14 @@ when ODIN_OS == .Darwin {
pthread_key_t :: distinct c.int
+ pthread_cond_t :: struct #align(8) {
+ _: [40]byte,
+ }
+
+ pthread_mutex_t :: struct #align(8) {
+ _: [48]byte,
+ }
+
sched_param :: struct {
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
}
@@ -505,14 +544,68 @@ when ODIN_OS == .Darwin {
PTHREAD_SCOPE_PROCESS :: 0
PTHREAD_SCOPE_SYSTEM :: 0x2
- pthread_t :: distinct rawptr
- pthread_attr_t :: distinct rawptr
- pthread_key_t :: distinct c.int
+ pthread_t :: distinct rawptr
+ pthread_attr_t :: distinct rawptr
+ pthread_key_t :: distinct c.int
+ pthread_mutex_t :: distinct rawptr
+ pthread_cond_t :: distinct rawptr
sched_param :: struct {
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
}
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ PTHREAD_CANCEL_DEFERRED :: 0
+ PTHREAD_CANCEL_ASYNCHRONOUS :: 1
+
+ PTHREAD_CANCEL_ENABLE :: 0
+ PTHREAD_CANCEL_DISABLE :: 1
+
+ PTHREAD_CANCELED :: rawptr(~uintptr(0))
+
+ PTHREAD_CREATE_JOINABLE :: 0
+ PTHREAD_CREATE_DETACHED :: 1
+
+ PTHREAD_INHERIT_SCHED :: 0
+ PTHREAD_EXPLICIT_SCHED :: 1
+
+ PTHREAD_PRIO_NONE :: 0
+ PTHREAD_PRIO_INHERIT :: 1
+ PTHREAD_PRIO_PROTECT :: 2
+
+ PTHREAD_PROCESS_PRIVATE :: 0
+ PTHREAD_PROCESS_SHARED :: 1
+
+ PTHREAD_SCOPE_SYSTEM :: 0
+ PTHREAD_SCOPE_PROCESS :: 1
+
+ pthread_t :: distinct c.ulong
+
+ pthread_attr_t :: struct #raw_union {
+ __size: [56]c.char, // NOTE: may be smaller depending on libc or arch, but never larger.
+ __align: c.long,
+ }
+
+ pthread_key_t :: distinct c.uint
+
+ pthread_cond_t :: struct {
+ __size: [40]c.char, // NOTE: may be smaller depending on libc or arch, but never larger.
+ __align: c.long,
+ }
+
+ pthread_mutex_t :: struct {
+ __size: [32]c.char, // NOTE: may be smaller depending on libc or arch, but never larger.
+ __align: c.long,
+ }
+
+ sched_param :: struct {
+ sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
+
+ // NOTE: may be smaller depending on libc or arch, but never larger.
+ __reserved1: c.int,
+ __reserved2: [4]c.long,
+ __reserved3: c.int,
+ }
+
}
diff --git a/core/sys/posix/pwd.odin b/core/sys/posix/pwd.odin
index 546d58309..33cbcd7c5 100644
--- a/core/sys/posix/pwd.odin
+++ b/core/sys/posix/pwd.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -163,6 +164,16 @@ when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
pw_fields: c.int,
}
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ 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_gecos: cstring, /* Real name. */
+ pw_dir: cstring, /* Home directory. */
+ pw_shell: cstring, /* Shell program. */
+ }
+
}
diff --git a/core/sys/posix/sched.odin b/core/sys/posix/sched.odin
index 6623ba6e6..e91178b09 100644
--- a/core/sys/posix/sched.odin
+++ b/core/sys/posix/sched.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -94,12 +95,10 @@ when ODIN_OS == .Darwin {
SCHED_RR :: 3
SCHED_OTHER :: 2
-} else when ODIN_OS == .NetBSD {
+} else when ODIN_OS == .NetBSD || ODIN_OS == .Linux {
SCHED_OTHER :: 0
SCHED_FIFO :: 1
SCHED_RR :: 2
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/setjmp.odin b/core/sys/posix/setjmp.odin
index cb1dad184..926dbd3ad 100644
--- a/core/sys/posix/setjmp.odin
+++ b/core/sys/posix/setjmp.odin
@@ -1,7 +1,7 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
-import "core:c/libc"
when ODIN_OS == .Darwin {
foreign import lib "system:System.framework"
@@ -43,12 +43,8 @@ foreign lib {
sigsetjmp :: proc(env: ^sigjmp_buf, savemask: b32) -> c.int ---
}
-jmp_buf :: libc.jmp_buf
sigjmp_buf :: distinct jmp_buf
-longjmp :: libc.longjmp
-setjmp :: libc.setjmp
-
when ODIN_OS == .NetBSD {
@(private) LSIGSETJMP :: "__sigsetjmp14"
@(private) LSIGLONGJMP :: "__siglongjmp14"
diff --git a/core/sys/posix/setjmp_libc.odin b/core/sys/posix/setjmp_libc.odin
new file mode 100644
index 000000000..a69dff09f
--- /dev/null
+++ b/core/sys/posix/setjmp_libc.odin
@@ -0,0 +1,11 @@
+#+build windows, linux, darwin, netbsd, openbsd, freebsd
+package posix
+
+import "core:c/libc"
+
+// setjmp.h - stack environment declarations
+
+jmp_buf :: libc.jmp_buf
+
+longjmp :: libc.longjmp
+setjmp :: libc.setjmp
diff --git a/core/sys/posix/signal.odin b/core/sys/posix/signal.odin
index c35494185..4ba4e9943 100644
--- a/core/sys/posix/signal.odin
+++ b/core/sys/posix/signal.odin
@@ -1,9 +1,9 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "base:intrinsics"
import "core:c"
-import "core:c/libc"
when ODIN_OS == .Darwin {
foreign import lib "system:System.framework"
@@ -14,31 +14,6 @@ when ODIN_OS == .Darwin {
// signal.h - signals
foreign lib {
- // LIBC:
-
- /*
- Set a signal handler.
-
- func can either be:
- - `auto_cast posix.SIG_DFL` setting the default handler for that specific signal
- - `auto_cast posix.SIG_IGN` causing the specific signal to be ignored
- - a custom signal handler
-
- Returns: SIG_ERR (setting errno), the last value of func on success
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html ]]
- */
- signal :: proc(sig: Signal, func: proc "c" (Signal)) -> proc "c" (Signal) ---
-
- /*
- Raises a signal, calling its handler and then returning.
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/raise.html ]]
- */
- raise :: proc(sig: Signal) -> result ---
-
- // POSIX:
-
/*
Raise a signal to the process/group specified by pid.
@@ -227,72 +202,6 @@ sigval :: struct #raw_union {
sigval_ptr: rawptr, /* [PSX] pointer signal value */
}
-Signal :: enum c.int {
- NONE,
-
- // LIBC:
-
- // Process abort signal.
- SIGABRT = SIGABRT,
- // Erronous arithemtic operation.
- SIGFPE = SIGFPE,
- // Illegal instruction.
- SIGILL = SIGILL,
- // Terminal interrupt signal.
- SIGINT = SIGINT,
- // Invalid memory reference.
- SIGSEGV = SIGSEGV,
- // Termination signal.
- SIGTERM = SIGTERM,
-
- // POSIX:
-
- // Process abort signal.
- SIGALRM = SIGALRM,
- // Access to an undefined portion of a memory object.
- SIGBUS = SIGBUS,
- // Child process terminated, stopped, or continued.
- SIGCHLD = SIGCHLD,
- // Continue execution, if stopped.
- SIGCONT = SIGCONT,
- // Hangup.
- SIGHUP = SIGHUP,
- // Kill (cannot be caught or ignored).
- SIGKILL = SIGKILL,
- // Write on a pipe with no one to read it.
- SIGPIPE = SIGPIPE,
- // Terminal quit signal.
- SIGQUIT = SIGQUIT,
- // Stop executing (cannot be caught or ignored).
- SIGSTOP = SIGSTOP,
- // Terminal stop process.
- SIGTSTP = SIGTSTP,
- // Background process attempting read.
- SIGTTIN = SIGTTIN,
- // Background process attempting write.
- SIGTTOU = SIGTTOU,
- // User-defined signal 1.
- SIGUSR1 = SIGUSR1,
- // User-defined signal 2.
- SIGUSR2 = SIGUSR2,
- // Pollable event.
- SIGPOLL = SIGPOLL,
- // Profiling timer expired.
- SIGPROF = SIGPROF,
- // Bad system call.
- SIGSYS = SIGSYS,
- // Trace/breakpoint trap.
- SIGTRAP = SIGTRAP,
- // High bandwidth data is available at a socket.
- SIGURG = SIGURG,
- // Virtual timer expired.
- SIGVTALRM = SIGVTALRM,
- // CPU time limit exceeded.
- SIGXCPU = SIGXCPU,
- // File size limit exceeded.
- SIGXFSZ = SIGXFSZ,
-}
-
ILL_Code :: enum c.int {
// Illegal opcode.
ILLOPC = ILL_ILLOPC,
@@ -434,20 +343,6 @@ Sig :: enum c.int {
SETMASK = SIG_SETMASK,
}
-// Request for default signal handling.
-SIG_DFL :: libc.SIG_DFL
-// Return value from signal() in case of error.
-SIG_ERR :: libc.SIG_ERR
-// Request that signal be ignored.
-SIG_IGN :: libc.SIG_IGN
-
-SIGABRT :: libc.SIGABRT
-SIGFPE :: libc.SIGFPE
-SIGILL :: libc.SIGILL
-SIGINT :: libc.SIGINT
-SIGSEGV :: libc.SIGSEGV
-SIGTERM :: libc.SIGTERM
-
when ODIN_OS == .NetBSD {
@(private) LSIGPROCMASK :: "__sigprocmask14"
@(private) LSIGACTION :: "__sigaction_siginfo"
@@ -480,11 +375,6 @@ when ODIN_OS == .Darwin {
uid_t :: distinct c.uint32_t
sigset_t :: distinct c.uint32_t
- // MOTE: unimplemented on darwin.
- //
- // SIGRTMIN ::
- // SIGRTMAX ::
-
SIGHUP :: 1
SIGQUIT :: 3
SIGTRAP :: 5
@@ -625,11 +515,6 @@ when ODIN_OS == .Darwin {
__bits: [4]c.uint32_t,
}
- // MOTE: unimplemented on darwin.
- //
- // SIGRTMIN :: 65
- // SIGRTMAX :: 126
-
SIGHUP :: 1
SIGQUIT :: 3
SIGTRAP :: 5
@@ -794,11 +679,6 @@ when ODIN_OS == .Darwin {
__bits: [4]c.uint32_t,
}
- // MOTE: unimplemented on darwin.
- //
- // SIGRTMIN :: 33
- // SIGRTMAX :: 63
-
SIGHUP :: 1
SIGQUIT :: 3
SIGTRAP :: 5
@@ -1126,6 +1006,178 @@ when ODIN_OS == .Darwin {
SI_ASYNCIO :: -4 // NOTE: not implemented
SI_MESGQ :: -5 // NOTE: not implemented
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ // Request that signal be held
+ SIG_HOLD :: rawptr(uintptr(2))
+
+ uid_t :: distinct c.uint32_t
+ sigset_t :: struct {
+ __val: [1024/(8 * size_of(c.ulong))]c.ulong,
+ }
+
+ SIGHUP :: 1
+ SIGQUIT :: 3
+ SIGTRAP :: 5
+ SIGBUS :: 7
+ SIGKILL :: 9
+ SIGUSR1 :: 10
+ SIGUSR2 :: 12
+ SIGPIPE :: 13
+ SIGALRM :: 14
+ SIGCHLD :: 17
+ SIGCONT :: 18
+ SIGSTOP :: 19
+ SIGTSTP :: 20
+ SIGTTIN :: 21
+ SIGTTOU :: 22
+ SIGURG :: 23
+ SIGXCPU :: 24
+ SIGXFSZ :: 25
+ SIGVTALRM :: 26
+ SIGPROF :: 27
+ SIGPOLL :: 29
+ SIGSYS :: 31
+
+ // 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_restorer: proc "c" (),
+ }
+
+ SIG_BLOCK :: 0
+ SIG_UNBLOCK :: 1
+ SIG_SETMASK :: 2
+
+ SA_NOCLDSTOP :: 1
+ SA_NOCLDWAIT :: 2
+ SA_SIGINFO :: 4
+ SA_ONSTACK :: 0x08000000
+ SA_RESTART :: 0x10000000
+ SA_NODEFER :: 0x40000000
+ SA_RESETHAND :: 0x80000000
+
+ SS_ONSTACK :: 1
+ SS_DISABLE :: 2
+
+ when ODIN_ARCH == .arm64 {
+ MINSIGSTKSZ :: 6144
+ SIGSTKSZ :: 12288
+ } else {
+ MINSIGSTKSZ :: 2048
+ SIGSTKSZ :: 8192
+ }
+
+ stack_t :: struct {
+ ss_sp: rawptr, /* [PSX] stack base or pointer */
+ ss_flags: SS_Flags, /* [PSX] flags */
+ ss_size: c.size_t, /* [PSX] stack size */
+ }
+
+ @(private)
+ __SI_MAX_SIZE :: 128
+
+ when size_of(int) == 8 {
+ @(private)
+ _pad0 :: struct {
+ _pad0: c.int,
+ }
+ @(private)
+ __SI_PAD_SIZE :: (__SI_MAX_SIZE / size_of(c.int)) - 4
+
+ } else {
+ @(private)
+ _pad0 :: struct {}
+ @(private)
+ __SI_PAD_SIZE :: (__SI_MAX_SIZE / size_of(c.int)) - 3
+ }
+
+ siginfo_t :: struct #align(8) {
+ si_signo: Signal, /* [PSX] signal number */
+ si_errno: Errno, /* [PSX] errno value associated with this signal */
+ 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,
+ },
+ __pad0: _pad0,
+ using _sifields: struct #raw_union {
+ _pad: [__SI_PAD_SIZE]c.int,
+
+ using _: struct {
+ si_pid: pid_t, /* [PSX] sending process ID */
+ si_uid: uid_t, /* [PSX] real user ID of sending process */
+ using _: struct #raw_union {
+ si_status: c.int, /* [PSX] exit value or signal */
+ si_value: sigval, /* [PSX] signal value */
+ },
+ },
+ using _: struct {
+ si_addr: rawptr, /* [PSX] address of faulting instruction */
+ },
+ using _: struct {
+ si_band: c.long, /* [PSX] band event for SIGPOLL */
+ },
+ },
+ }
+
+ ILL_ILLOPC :: 1
+ ILL_ILLOPN :: 2
+ ILL_ILLADR :: 3
+ ILL_ILLTRP :: 4
+ ILL_PRVOPC :: 5
+ ILL_PRVREG :: 6
+ ILL_COPROC :: 7
+ ILL_BADSTK :: 8
+
+ FPE_INTDIV :: 1
+ FPE_INTOVF :: 2
+ FPE_FLTDIV :: 3
+ FPE_FLTOVF :: 4
+ FPE_FLTUND :: 5
+ FPE_FLTRES :: 6
+ FPE_FLTINV :: 7
+ FPE_FLTSUB :: 8
+
+ SEGV_MAPERR :: 1
+ SEGV_ACCERR :: 2
+
+ BUS_ADRALN :: 1
+ BUS_ADRERR :: 2
+ BUS_OBJERR :: 3
+
+ TRAP_BRKPT :: 1
+ TRAP_TRACE :: 2
+
+ CLD_EXITED :: 1
+ CLD_KILLED :: 2
+ CLD_DUMPED :: 3
+ CLD_TRAPPED :: 4
+ CLD_STOPPED :: 5
+ CLD_CONTINUED :: 6
+
+ POLL_IN :: 1
+ POLL_OUT :: 2
+ POLL_MSG :: 3
+ POLL_ERR :: 4
+ POLL_PRI :: 5
+ POLL_HUP :: 6
+
+ SI_USER :: 0
+ SI_QUEUE :: -1
+ SI_TIMER :: -2
+ SI_MESGQ :: -3
+ SI_ASYNCIO :: -4
}
diff --git a/core/sys/posix/signal_libc.odin b/core/sys/posix/signal_libc.odin
new file mode 100644
index 000000000..aef22da29
--- /dev/null
+++ b/core/sys/posix/signal_libc.odin
@@ -0,0 +1,145 @@
+#+build linux, windows, darwin, netbsd, openbsd, freebsd
+package posix
+
+import "base:intrinsics"
+
+import "core:c"
+import "core:c/libc"
+
+when ODIN_OS == .Windows {
+ foreign import lib "system:libucrt.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "system:System.framework"
+} else {
+ foreign import lib "system:c"
+}
+
+// signal.h - signals
+
+foreign lib {
+ /*
+ Set a signal handler.
+
+ func can either be:
+ - `auto_cast posix.SIG_DFL` setting the default handler for that specific signal
+ - `auto_cast posix.SIG_IGN` causing the specific signal to be ignored
+ - a custom signal handler
+
+ Returns: SIG_ERR (setting errno), the last value of func on success
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html ]]
+ */
+ signal :: proc(sig: Signal, func: proc "c" (Signal)) -> proc "c" (Signal) ---
+
+ /*
+ Raises a signal, calling its handler and then returning.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/raise.html ]]
+ */
+ raise :: proc(sig: Signal) -> result ---
+}
+
+Signal :: enum c.int {
+ NONE,
+
+ // LIBC:
+
+ // Process abort signal.
+ SIGABRT = SIGABRT,
+ // Erronous arithemtic operation.
+ SIGFPE = SIGFPE,
+ // Illegal instruction.
+ SIGILL = SIGILL,
+ // Terminal interrupt signal.
+ SIGINT = SIGINT,
+ // Invalid memory reference.
+ SIGSEGV = SIGSEGV,
+ // Termination signal.
+ SIGTERM = SIGTERM,
+
+ // POSIX:
+
+ // Process abort signal.
+ SIGALRM = SIGALRM,
+ // Access to an undefined portion of a memory object.
+ SIGBUS = SIGBUS,
+ // Child process terminated, stopped, or continued.
+ SIGCHLD = SIGCHLD,
+ // Continue execution, if stopped.
+ SIGCONT = SIGCONT,
+ // Hangup.
+ SIGHUP = SIGHUP,
+ // Kill (cannot be caught or ignored).
+ SIGKILL = SIGKILL,
+ // Write on a pipe with no one to read it.
+ SIGPIPE = SIGPIPE,
+ // Terminal quit signal.
+ SIGQUIT = SIGQUIT,
+ // Stop executing (cannot be caught or ignored).
+ SIGSTOP = SIGSTOP,
+ // Terminal stop process.
+ SIGTSTP = SIGTSTP,
+ // Background process attempting read.
+ SIGTTIN = SIGTTIN,
+ // Background process attempting write.
+ SIGTTOU = SIGTTOU,
+ // User-defined signal 1.
+ SIGUSR1 = SIGUSR1,
+ // User-defined signal 2.
+ SIGUSR2 = SIGUSR2,
+ // Pollable event.
+ SIGPOLL = SIGPOLL,
+ // Profiling timer expired.
+ SIGPROF = SIGPROF,
+ // Bad system call.
+ SIGSYS = SIGSYS,
+ // Trace/breakpoint trap.
+ SIGTRAP = SIGTRAP,
+ // High bandwidth data is available at a socket.
+ SIGURG = SIGURG,
+ // Virtual timer expired.
+ SIGVTALRM = SIGVTALRM,
+ // CPU time limit exceeded.
+ SIGXCPU = SIGXCPU,
+ // File size limit exceeded.
+ SIGXFSZ = SIGXFSZ,
+}
+
+// Request for default signal handling.
+SIG_DFL :: libc.SIG_DFL
+// Return value from signal() in case of error.
+SIG_ERR :: libc.SIG_ERR
+// Request that signal be ignored.
+SIG_IGN :: libc.SIG_IGN
+
+SIGABRT :: libc.SIGABRT
+SIGFPE :: libc.SIGFPE
+SIGILL :: libc.SIGILL
+SIGINT :: libc.SIGINT
+SIGSEGV :: libc.SIGSEGV
+SIGTERM :: libc.SIGTERM
+
+when ODIN_OS == .Windows {
+ SIGALRM :: -1
+ SIGBUS :: -1
+ SIGCHLD :: -1
+ SIGCONT :: -1
+ SIGHUP :: -1
+ SIGKILL :: -1
+ SIGPIPE :: -1
+ SIGQUIT :: -1
+ SIGSTOP :: -1
+ SIGTSTP :: -1
+ SIGTTIN :: -1
+ SIGTTOU :: -1
+ SIGUSR1 :: -1
+ SIGUSR2 :: -1
+ SIGPOLL :: -1
+ SIGPROF :: -1
+ SIGSYS :: -1
+ SIGTRAP :: -1
+ SIGURG :: -1
+ SIGVTALRM :: -1
+ SIGXCPU :: -1
+ SIGXFSZ :: -1
+}
diff --git a/core/sys/posix/stdio.odin b/core/sys/posix/stdio.odin
index de716f8d7..24464dfd8 100644
--- a/core/sys/posix/stdio.odin
+++ b/core/sys/posix/stdio.odin
@@ -1,7 +1,7 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
-import "core:c/libc"
when ODIN_OS == .Darwin {
foreign import lib "system:System.framework"
@@ -33,16 +33,6 @@ foreign lib {
dprintf :: proc(fildse: FD, format: cstring, #c_vararg args: ..any) -> c.int ---
/*
- Equivalent to fprintf but output is written to s, it is the user's responsibility to
- ensure there is enough space.
-
- Return: number of bytes written, negative (setting errno) on failure
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/dprintf.html ]]
- */
- sprintf :: proc(s: [^]byte, format: cstring, #c_vararg args: ..any) -> c.int ---
-
- /*
Associate a stream with a file descriptor.
Returns: nil (setting errno) on failure, the stream on success
@@ -116,34 +106,6 @@ foreign lib {
open_memstream :: proc(bufp: ^[^]byte, sizep: ^c.size_t) -> ^FILE ---
/*
- Equivalent to getc but unaffected by locks.
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
- */
- getc_unlocked :: proc(stream: ^FILE) -> c.int ---
-
- /*
- Equivalent to getchar but unaffected by locks.
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
- */
- getchar_unlocked :: proc() -> c.int ---
-
- /*
- Equivalent to putc but unaffected by locks.
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
- */
- putc_unlocked :: proc(ch: c.int, stream: ^FILE) -> c.int ---
-
- /*
- Equivalent to putchar but unaffected by locks.
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
- */
- putchar_unlocked :: proc(ch: c.int) -> c.int ---
-
- /*
Read a delimited record from the stream.
Returns: the number of bytes written or -1 on failure/EOF
@@ -182,60 +144,6 @@ foreign lib {
getline :: proc(lineptr: ^cstring, n: ^c.size_t, stream: ^FILE) -> c.ssize_t ---
/*
- Get a string from the stdin stream.
-
- It is up to the user to make sure s is big enough.
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/gets.html ]]
- */
- gets :: proc(s: [^]byte) -> cstring ---
-
- /*
- Create a name for a temporary file.
-
- Returns: an allocated cstring that needs to be freed, nil on failure
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/tempnam.html ]]
- */
- tempnam :: proc(dir: cstring, pfx: cstring) -> cstring ---
-
- /*
- Executes the command specified, creating a pipe and returning a pointer to a stream that can
- read or write from/to the pipe.
-
- Returns: nil (setting errno) on failure or a pointer to the stream
-
- Example:
- fp := posix.popen("ls *", "r")
- if fp == nil {
- /* Handle error */
- }
-
- path: [1024]byte
- for posix.fgets(raw_data(path[:]), len(path), fp) != nil {
- posix.printf("%s", &path)
- }
-
- status := posix.pclose(fp)
- if status == -1 {
- /* Error reported by pclose() */
- } else {
- /* Use functions described under wait() to inspect `status` in order
- to determine success/failure of the command executed by popen() */
- }
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html ]]
- */
- popen :: proc(command: cstring, mode: cstring) -> ^FILE ---
-
- /*
- Closes a pipe stream to or from a process.
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pclose.html ]]
- */
- pclose :: proc(stream: ^FILE) -> c.int ---
-
- /*
Equivalent to rename but relative directories are resolved from their respective fds.
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/renameat.html ]]
@@ -243,76 +151,6 @@ foreign lib {
renameat :: proc(oldfd: FD, old: cstring, newfd: FD, new: cstring) -> result ---
}
-clearerr :: libc.clearerr
-fclose :: libc.fclose
-feof :: libc.feof
-ferror :: libc.ferror
-fflush :: libc.fflush
-fgetc :: libc.fgetc
-fgetpos :: libc.fgetpos
-fgets :: libc.fgets
-fopen :: libc.fopen
-fprintf :: libc.fprintf
-fputc :: libc.fputc
-fread :: libc.fread
-freopen :: libc.freopen
-fscanf :: libc.fscanf
-fseek :: libc.fseek
-fsetpos :: libc.fsetpos
-ftell :: libc.ftell
-fwrite :: libc.fwrite
-getc :: libc.getc
-getchar :: libc.getchar
-perror :: libc.perror
-printf :: libc.printf
-putc :: libc.puts
-putchar :: libc.putchar
-puts :: libc.puts
-remove :: libc.remove
-rename :: libc.rename
-rewind :: libc.rewind
-scanf :: libc.scanf
-setbuf :: libc.setbuf
-setvbuf :: libc.setvbuf
-snprintf :: libc.snprintf
-sscanf :: libc.sscanf
-tmpfile :: libc.tmpfile
-tmpnam :: libc.tmpnam
-vfprintf :: libc.vfprintf
-vfscanf :: libc.vfscanf
-vprintf :: libc.vprintf
-vscanf :: libc.vscanf
-vsnprintf :: libc.vsnprintf
-vsprintf :: libc.vsprintf
-vsscanf :: libc.vsscanf
-ungetc :: libc.ungetc
-
-to_stream :: libc.to_stream
-
-Whence :: libc.Whence
-FILE :: libc.FILE
-fpos_t :: libc.fpos_t
-
-BUFSIZ :: libc.BUFSIZ
-
-_IOFBF :: libc._IOFBF
-_IOLBF :: libc._IOLBF
-_IONBF :: libc._IONBF
-
-SEEK_CUR :: libc.SEEK_CUR
-SEEK_END :: libc.SEEK_END
-SEEK_SET :: libc.SEEK_SET
-
-FILENAME_MAX :: libc.FILENAME_MAX
-FOPEN_MAX :: libc.FOPEN_MAX
-TMP_MAX :: libc.TMP_MAX
-
-EOF :: libc.EOF
-
-stderr := libc.stderr
-stdin := libc.stdin
-stdout := libc.stdout
-
when ODIN_OS == .Darwin {
L_ctermid :: 1024
@@ -327,6 +165,11 @@ when ODIN_OS == .Darwin {
P_tmpdir :: "/tmp/"
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ L_ctermid :: 20 // 20 on musl, 9 on glibc
+ L_tmpnam :: 20
+
+ P_tmpdir :: "/tmp/"
+
}
diff --git a/core/sys/posix/stdio_libc.odin b/core/sys/posix/stdio_libc.odin
new file mode 100644
index 000000000..fbd949b2c
--- /dev/null
+++ b/core/sys/posix/stdio_libc.odin
@@ -0,0 +1,207 @@
+#+build linux, windows, linux, darwin, netbsd, openbsd, freebsd
+package posix
+
+import "core:c"
+import "core:c/libc"
+
+when ODIN_OS == .Windows {
+ foreign import lib {
+ "system:libucrt.lib",
+ "system:legacy_stdio_definitions.lib",
+ }
+} else when ODIN_OS == .Darwin {
+ foreign import lib "system:System.framework"
+} else {
+ foreign import lib "system:c"
+}
+
+// stdio.h - standard buffered input/output
+
+when ODIN_OS == .Windows {
+ @(private) LGETC_UNLOCKED :: "_getc_nolock"
+ @(private) LGETCHAR_UNLOCKED :: "_getchar_nolock"
+ @(private) LPUTC_UNLOCKED :: "_putc_nolock"
+ @(private) LPUTCHAR_UNLOCKED :: "_putchar_nolock"
+ @(private) LTEMPNAM :: "_tempnam"
+ @(private) LPOPEN :: "_popen"
+ @(private) LPCLOSE :: "_pclose"
+} else {
+ @(private) LGETC_UNLOCKED :: "getc_unlocked"
+ @(private) LGETCHAR_UNLOCKED :: "getchar_unlocked"
+ @(private) LPUTC_UNLOCKED :: "putc_unlocked"
+ @(private) LPUTCHAR_UNLOCKED :: "putchar_unlocked"
+ @(private) LTEMPNAM :: "tempnam"
+ @(private) LPOPEN :: "popen"
+ @(private) LPCLOSE :: "pclose"
+}
+
+foreign lib {
+ /*
+ Equivalent to fprintf but output is written to s, it is the user's responsibility to
+ ensure there is enough space.
+
+ Return: number of bytes written, negative (setting errno) on failure
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/dprintf.html ]]
+ */
+ sprintf :: proc(s: [^]byte, format: cstring, #c_vararg args: ..any) -> c.int ---
+
+ /*
+ Equivalent to getc but unaffected by locks.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
+ */
+ @(link_name=LGETC_UNLOCKED)
+ getc_unlocked :: proc(stream: ^FILE) -> c.int ---
+
+ /*
+ Equivalent to getchar but unaffected by locks.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
+ */
+ @(link_name=LGETCHAR_UNLOCKED)
+ getchar_unlocked :: proc() -> c.int ---
+
+ /*
+ Equivalent to putc but unaffected by locks.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
+ */
+ @(link_name=LPUTC_UNLOCKED)
+ putc_unlocked :: proc(ch: c.int, stream: ^FILE) -> c.int ---
+
+ /*
+ Equivalent to putchar but unaffected by locks.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
+ */
+ @(link_name=LPUTCHAR_UNLOCKED)
+ putchar_unlocked :: proc(ch: c.int) -> c.int ---
+
+ /*
+ Get a string from the stdin stream.
+
+ It is up to the user to make sure s is big enough.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/gets.html ]]
+ */
+ gets :: proc(s: [^]byte) -> cstring ---
+
+ /*
+ Create a name for a temporary file.
+
+ Returns: an allocated cstring that needs to be freed, nil on failure
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/tempnam.html ]]
+ */
+ @(link_name=LTEMPNAM)
+ tempnam :: proc(dir: cstring, pfx: cstring) -> cstring ---
+
+ /*
+ Executes the command specified, creating a pipe and returning a pointer to a stream that can
+ read or write from/to the pipe.
+
+ Returns: nil (setting errno) on failure or a pointer to the stream
+
+ Example:
+ fp := posix.popen("ls *", "r")
+ if fp == nil {
+ /* Handle error */
+ }
+
+ path: [1024]byte
+ for posix.fgets(raw_data(path[:]), len(path), fp) != nil {
+ posix.printf("%s", &path)
+ }
+
+ status := posix.pclose(fp)
+ if status == -1 {
+ /* Error reported by pclose() */
+ } else {
+ /* Use functions described under wait() to inspect `status` in order
+ to determine success/failure of the command executed by popen() */
+ }
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html ]]
+ */
+ @(link_name=LPOPEN)
+ popen :: proc(command: cstring, mode: cstring) -> ^FILE ---
+
+ /*
+ Closes a pipe stream to or from a process.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pclose.html ]]
+ */
+ @(link_name=LPCLOSE)
+ pclose :: proc(stream: ^FILE) -> c.int ---
+}
+
+clearerr :: libc.clearerr
+fclose :: libc.fclose
+feof :: libc.feof
+ferror :: libc.ferror
+fflush :: libc.fflush
+fgetc :: libc.fgetc
+fgetpos :: libc.fgetpos
+fgets :: libc.fgets
+fopen :: libc.fopen
+fprintf :: libc.fprintf
+fputc :: libc.fputc
+fread :: libc.fread
+freopen :: libc.freopen
+fscanf :: libc.fscanf
+fseek :: libc.fseek
+fsetpos :: libc.fsetpos
+ftell :: libc.ftell
+fwrite :: libc.fwrite
+getc :: libc.getc
+getchar :: libc.getchar
+perror :: libc.perror
+printf :: libc.printf
+putc :: libc.puts
+putchar :: libc.putchar
+puts :: libc.puts
+remove :: libc.remove
+rename :: libc.rename
+rewind :: libc.rewind
+scanf :: libc.scanf
+setbuf :: libc.setbuf
+setvbuf :: libc.setvbuf
+snprintf :: libc.snprintf
+sscanf :: libc.sscanf
+tmpfile :: libc.tmpfile
+tmpnam :: libc.tmpnam
+vfprintf :: libc.vfprintf
+vfscanf :: libc.vfscanf
+vprintf :: libc.vprintf
+vscanf :: libc.vscanf
+vsnprintf :: libc.vsnprintf
+vsprintf :: libc.vsprintf
+vsscanf :: libc.vsscanf
+ungetc :: libc.ungetc
+
+to_stream :: libc.to_stream
+
+Whence :: libc.Whence
+FILE :: libc.FILE
+fpos_t :: libc.fpos_t
+
+BUFSIZ :: libc.BUFSIZ
+
+_IOFBF :: libc._IOFBF
+_IOLBF :: libc._IOLBF
+_IONBF :: libc._IONBF
+
+SEEK_CUR :: libc.SEEK_CUR
+SEEK_END :: libc.SEEK_END
+SEEK_SET :: libc.SEEK_SET
+
+FILENAME_MAX :: libc.FILENAME_MAX
+FOPEN_MAX :: libc.FOPEN_MAX
+TMP_MAX :: libc.TMP_MAX
+
+EOF :: libc.EOF
+
+stderr := libc.stderr
+stdin := libc.stdin
+stdout := libc.stdout
diff --git a/core/sys/posix/stdlib.odin b/core/sys/posix/stdlib.odin
index a1e2eab50..640c70b5a 100644
--- a/core/sys/posix/stdlib.odin
+++ b/core/sys/posix/stdlib.odin
@@ -1,9 +1,9 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "base:intrinsics"
import "core:c"
-import "core:c/libc"
when ODIN_OS == .Darwin {
foreign import lib "system:System.framework"
@@ -11,56 +11,6 @@ when ODIN_OS == .Darwin {
foreign import lib "system:c"
}
-// stdlib.h - standard library definitions
-
-atof :: libc.atof
-atoi :: libc.atoi
-atol :: libc.atol
-atoll :: libc.atoll
-strtod :: libc.strtod
-strtof :: libc.strtof
-strtol :: libc.strtol
-strtoll :: libc.strtoll
-strtoul :: libc.strtoul
-strtoull :: libc.strtoull
-
-rand :: libc.rand
-srand :: libc.srand
-
-calloc :: libc.calloc
-malloc :: libc.malloc
-realloc :: libc.realloc
-
-abort :: libc.abort
-atexit :: libc.atexit
-at_quick_exit :: libc.at_quick_exit
-exit :: libc.exit
-_Exit :: libc._Exit
-getenv :: libc.getenv
-quick_exit :: libc.quick_exit
-system :: libc.system
-
-bsearch :: libc.bsearch
-qsort :: libc.qsort
-
-abs :: libc.abs
-labs :: libc.labs
-llabs :: libc.llabs
-div :: libc.div
-ldiv :: libc.ldiv
-lldiv :: libc.lldiv
-
-mblen :: libc.mblen
-mbtowc :: libc.mbtowc
-wctomb :: libc.wctomb
-
-mbstowcs :: libc.mbstowcs
-wcstombs :: libc.wcstombs
-
-free :: #force_inline proc(ptr: $T) where intrinsics.type_is_pointer(T) || intrinsics.type_is_multi_pointer(T) || T == cstring {
- libc.free(rawptr(ptr))
-}
-
foreign lib {
/*
Takes a pointer to a radix-64 representation, in which the first digit is the least significant,
@@ -343,21 +293,6 @@ foreign lib {
unlockpt :: proc(fildes: FD) -> result ---
/*
- Uses the string argument to set environment variable values.
-
- Returns: 0 on success, non-zero (setting errno) on failure
-
- Example:
- if posix.putenv("HOME=/usr/home") != 0 {
- fmt.panicf("putenv failure: %v", posix.strerror(posix.errno()))
- }
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/putenv.html ]]
- */
- @(link_name=LPUTENV)
- putenv :: proc(string: cstring) -> c.int ---
-
- /*
Updates or add a variable in the environment of the calling process.
Example:
@@ -427,23 +362,11 @@ foreign lib {
setkey :: proc(key: [^]byte) ---
}
-EXIT_FAILURE :: libc.EXIT_FAILURE
-EXIT_SUCCESS :: libc.EXIT_SUCCESS
-
-RAND_MAX :: libc.RAND_MAX
-MB_CUR_MAX :: libc.MB_CUR_MAX
-
-div_t :: libc.div_t
-ldiv_t :: libc.ldiv_t
-lldiv_t :: libc.lldiv_t
-
when ODIN_OS == .NetBSD {
- @(private) LPUTENV :: "__putenv50"
@(private) LINITSTATE :: "__initstate60"
@(private) LSRANDOM :: "__srandom60"
@(private) LUNSETENV :: "__unsetenv13"
} else {
- @(private) LPUTENV :: "putenv"
@(private) LINITSTATE :: "initstate"
@(private) LSRANDOM :: "srandom"
@(private) LUNSETENV :: "unsetenv"
diff --git a/core/sys/posix/stdlib_libc.odin b/core/sys/posix/stdlib_libc.odin
new file mode 100644
index 000000000..fa4d925b2
--- /dev/null
+++ b/core/sys/posix/stdlib_libc.odin
@@ -0,0 +1,101 @@
+#+build linux, windows, darwin, netbsd, openbsd, freebsd
+package posix
+
+import "base:intrinsics"
+
+import "core:c"
+import "core:c/libc"
+
+when ODIN_OS == .Windows {
+ foreign import lib "system:libucrt.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "system:System.framework"
+} else {
+ foreign import lib "system:c"
+}
+
+// stdlib.h - standard library definitions
+
+atof :: libc.atof
+atoi :: libc.atoi
+atol :: libc.atol
+atoll :: libc.atoll
+strtod :: libc.strtod
+strtof :: libc.strtof
+strtol :: libc.strtol
+strtoll :: libc.strtoll
+strtoul :: libc.strtoul
+strtoull :: libc.strtoull
+
+rand :: libc.rand
+srand :: libc.srand
+
+calloc :: libc.calloc
+malloc :: libc.malloc
+realloc :: libc.realloc
+
+abort :: libc.abort
+atexit :: libc.atexit
+at_quick_exit :: libc.at_quick_exit
+exit :: libc.exit
+_Exit :: libc._Exit
+getenv :: libc.getenv
+quick_exit :: libc.quick_exit
+system :: libc.system
+
+bsearch :: libc.bsearch
+qsort :: libc.qsort
+
+abs :: libc.abs
+labs :: libc.labs
+llabs :: libc.llabs
+div :: libc.div
+ldiv :: libc.ldiv
+lldiv :: libc.lldiv
+
+mblen :: libc.mblen
+mbtowc :: libc.mbtowc
+wctomb :: libc.wctomb
+
+mbstowcs :: libc.mbstowcs
+wcstombs :: libc.wcstombs
+
+free :: #force_inline proc(ptr: $T) where intrinsics.type_is_pointer(T) || intrinsics.type_is_multi_pointer(T) || T == cstring {
+ libc.free(rawptr(ptr))
+}
+
+foreign lib {
+
+ /*
+ Uses the string argument to set environment variable values.
+
+ Returns: 0 on success, non-zero (setting errno) on failure
+
+ Example:
+ if posix.putenv("HOME=/usr/home") != 0 {
+ fmt.panicf("putenv failure: %v", posix.strerror(posix.errno()))
+ }
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/putenv.html ]]
+ */
+ @(link_name=LPUTENV)
+ putenv :: proc(string: cstring) -> c.int ---
+}
+
+EXIT_FAILURE :: libc.EXIT_FAILURE
+EXIT_SUCCESS :: libc.EXIT_SUCCESS
+
+RAND_MAX :: libc.RAND_MAX
+MB_CUR_MAX :: libc.MB_CUR_MAX
+
+div_t :: libc.div_t
+ldiv_t :: libc.ldiv_t
+lldiv_t :: libc.lldiv_t
+
+when ODIN_OS == .Windows {
+ @(private) LPUTENV :: "_putenv"
+} else when ODIN_OS == .NetBSD {
+ @(private) LPUTENV :: "__putenv50"
+} else {
+ @(private) LPUTENV :: "putenv"
+}
diff --git a/core/sys/posix/string.odin b/core/sys/posix/string.odin
index d22f49a96..96b6a9007 100644
--- a/core/sys/posix/string.odin
+++ b/core/sys/posix/string.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -14,16 +15,6 @@ when ODIN_OS == .Darwin {
foreign lib {
/*
- Map the error number to a locale-dependent error message string.
-
- Returns: a string that may be invalidated by subsequent calls
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html ]]
- */
- @(link_name="strerror")
- _strerror :: proc(errnum: Errno) -> cstring ---
-
- /*
Map the error number to a locale-dependent error message string and put it in the buffer.
Returns: ERANGE if the buffer is not big enough
@@ -41,7 +32,3 @@ foreign lib {
*/
strsignal :: proc(sig: Signal) -> cstring ---
}
-
-strerror :: #force_inline proc "contextless" (errnum: Maybe(Errno) = nil) -> cstring {
- return _strerror(errnum.? or_else errno())
-}
diff --git a/core/sys/posix/string_libc.odin b/core/sys/posix/string_libc.odin
new file mode 100644
index 000000000..336352cbc
--- /dev/null
+++ b/core/sys/posix/string_libc.odin
@@ -0,0 +1,30 @@
+#+build linux, windows, darwin, netbsd, openbsd, freebsd
+package posix
+
+when ODIN_OS == .Windows {
+ foreign import lib "system:libucrt.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "system:System.framework"
+} else {
+ foreign import lib "system:c"
+}
+
+// string.h - string operations
+
+// NOTE: most of the symbols in this header are not useful in Odin and have been left out.
+
+foreign lib {
+ /*
+ Map the error number to a locale-dependent error message string.
+
+ Returns: a string that may be invalidated by subsequent calls
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html ]]
+ */
+ @(link_name="strerror")
+ _strerror :: proc(errnum: Errno) -> cstring ---
+}
+
+strerror :: #force_inline proc "contextless" (errnum: Maybe(Errno) = nil) -> cstring {
+ return _strerror(errnum.? or_else errno())
+}
diff --git a/core/sys/posix/sys_ipc.odin b/core/sys/posix/sys_ipc.odin
index f8778ee15..0f7ec06c5 100644
--- a/core/sys/posix/sys_ipc.odin
+++ b/core/sys/posix/sys_ipc.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -84,6 +85,30 @@ when ODIN_OS == .Darwin {
IPC_SET :: 1
IPC_STAT :: 2
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ key_t :: distinct c.int32_t
+
+ ipc_perm :: struct {
+ __ipc_perm_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_perm_seq: c.int,
+ __pad1: c.long,
+ __pad2: c.long,
+ }
+
+ IPC_CREAT :: 0o01000
+ IPC_EXCL :: 0o02000
+ IPC_NOWAIT :: 0o04000
+
+ IPC_PRIVATE :: key_t(0)
+
+ IPC_RMID :: 0
+ IPC_SET :: 1
+ IPC_STAT :: 2
+
}
diff --git a/core/sys/posix/sys_mman.odin b/core/sys/posix/sys_mman.odin
index 217d321ac..0594672ae 100644
--- a/core/sys/posix/sys_mman.odin
+++ b/core/sys/posix/sys_mman.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -115,12 +116,14 @@ Prot_Flag_Bits :: enum c.int {
Prot_Flags :: bit_set[Prot_Flag_Bits; c.int]
Map_Flag_Bits :: enum c.int {
+ // Map anonymous memory.
+ ANONYMOUS = log2(MAP_ANONYMOUS),
// Interpret addr exactly.
- FIXED = log2(MAP_FIXED),
+ FIXED = log2(MAP_FIXED),
// Changes are private.
- PRIVATE = log2(MAP_PRIVATE),
+ PRIVATE = log2(MAP_PRIVATE),
// Changes are shared.
- SHARED = log2(MAP_SHARED),
+ SHARED = log2(MAP_SHARED),
}
Map_Flags :: bit_set[Map_Flag_Bits; c.int]
@@ -163,18 +166,19 @@ when ODIN_OS == .NetBSD {
@(private) LMSYNC :: "msync"
}
-when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
+when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
PROT_EXEC :: 0x04
_PROT_NONE :: 0x00
PROT_READ :: 0x01
PROT_WRITE :: 0x02
- MAP_FIXED :: 0x0010
- MAP_PRIVATE :: 0x0002
- MAP_SHARED :: 0x0001
+ MAP_FIXED :: 0x0010
+ MAP_PRIVATE :: 0x0002
+ MAP_SHARED :: 0x0001
+ MAP_ANONYMOUS :: 0x0020 when ODIN_OS == .Linux else 0x1000
- when ODIN_OS == .Darwin {
+ when ODIN_OS == .Darwin || ODIN_OS == .Linux {
MS_INVALIDATE :: 0x0002
_MS_SYNC :: 0x0010
} else when ODIN_OS == .NetBSD {
@@ -184,6 +188,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
MS_INVALIDATE :: 0x0004
_MS_SYNC :: 0x0002
}
+
MS_ASYNC :: 0x0001
MS_SYNC :: Sync_Flags{Sync_Flags_Bits(log2(_MS_SYNC))}
@@ -205,9 +210,10 @@ when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
PROT_READ :: 0x01
PROT_WRITE :: 0x02
- MAP_FIXED :: 0x0010
- MAP_PRIVATE :: 0x0002
- MAP_SHARED :: 0x0001
+ MAP_FIXED :: 0x0010
+ MAP_PRIVATE :: 0x0002
+ MAP_SHARED :: 0x0001
+ MAP_ANONYMOUS :: 0x1000
MS_ASYNC :: 0x0001
MS_INVALIDATE :: 0x0002
@@ -224,6 +230,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
POSIX_MADV_SEQUENTIAL :: 2
POSIX_MADV_WILLNEED :: 3
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/sys_msg.odin b/core/sys/posix/sys_msg.odin
index a8b86e501..0e78777f9 100644
--- a/core/sys/posix/sys_msg.odin
+++ b/core/sys/posix/sys_msg.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -64,28 +65,22 @@ when ODIN_OS == .Darwin {
MSG_NOERROR :: 0o10000
- // NOTE: this is #pragma pack(4)
-
- msqid_ds :: struct #align(4) {
- msg_perm: ipc_perm, /* [PSX] operation permission structure */
+ msqid_ds :: struct #max_field_align(4) {
+ msg_perm: ipc_perm, /* [PSX] operation permission structure */
msg_first: c.int32_t,
msg_last: c.int32_t,
msg_cbytes: msglen_t,
- 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_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_pad1: c.int32_t,
- using _: struct #align(4) {
- msg_rtime: time_t, /* [PSX] time of last msgrcv() */
- msg_pad2: c.int32_t,
- using _: struct #align(4) {
- msg_ctime: time_t, /* [PSX] time of last change */
- msg_pad3: c.int32_t,
- msg_pad4: [4]c.int32_t,
- },
- },
+ msg_rtime: time_t, /* [PSX] time of last msgrcv() */
+ msg_pad2: c.int32_t,
+ msg_ctime: time_t, /* [PSX] time of last change */
+ msg_pad3: c.int32_t,
+ msg_pad4: [4]c.int32_t,
}
} else when ODIN_OS == .FreeBSD {
@@ -156,6 +151,24 @@ when ODIN_OS == .Darwin {
msg_pad4: [4]c.long,
}
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ msgqnum_t :: distinct c.ulong
+ msglen_t :: distinct c.ulong
+
+ MSG_NOERROR :: 0o10000
+
+ msqid_ds :: struct {
+ msg_perm: ipc_perm, /* [PSX] operation permission structure */
+ 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 */
+ msg_cbytes: c.ulong,
+ 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() */
+ __unused: [2]c.ulong,
+ }
+
}
diff --git a/core/sys/posix/sys_resource.odin b/core/sys/posix/sys_resource.odin
index 6716d60c3..9af2a929b 100644
--- a/core/sys/posix/sys_resource.odin
+++ b/core/sys/posix/sys_resource.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -95,7 +96,7 @@ when ODIN_OS == .NetBSD {
@(private) LGETRUSAGE :: "getrusage"
}
-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 == .Linux {
PRIO_PROCESS :: 0
PRIO_PGRP :: 1
@@ -103,7 +104,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
rlim_t :: distinct c.uint64_t
- RLIM_INFINITY :: (rlim_t(1) << 63) - 1
+ RLIM_INFINITY :: ~rlim_t(0) when ODIN_OS == .Linux else (rlim_t(1) << 63) - 1
RLIM_SAVED_MAX :: RLIM_INFINITY
RLIM_SAVED_CUR :: RLIM_INFINITY
@@ -143,10 +144,15 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
RLIMIT_CPU :: 0
RLIMIT_DATA :: 2
RLIMIT_FSIZE :: 1
- RLIMIT_NOFILE :: 8
+ RLIMIT_NOFILE :: 7 when ODIN_OS == .Linux else 8
RLIMIT_STACK :: 3
- RLIMIT_AS :: 5 when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD else 10
-} else {
- #panic("posix is unimplemented for the current target")
+ when ODIN_OS == .Linux {
+ RLIMIT_AS :: 9
+ } else when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD {
+ RLIMIT_AS :: 5
+ } else {
+ RLIMIT_AS :: 10
+ }
+
}
diff --git a/core/sys/posix/sys_select.odin b/core/sys/posix/sys_select.odin
index 3392e02bc..2058ee777 100644
--- a/core/sys/posix/sys_select.odin
+++ b/core/sys/posix/sys_select.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "base:intrinsics"
@@ -55,7 +56,7 @@ when ODIN_OS == .NetBSD {
LSELECT :: "select"
}
-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 == .Linux {
suseconds_t :: distinct (c.int32_t when ODIN_OS == .Darwin || ODIN_OS == .NetBSD else c.long)
@@ -72,7 +73,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
// NOTE: this seems correct for FreeBSD but they do use a set backed by the long type themselves (thus the align change).
@(private)
- ALIGN :: align_of(c.long) when ODIN_OS == .FreeBSD else align_of(c.int32_t)
+ 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,
@@ -115,6 +116,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
intrinsics.mem_zero(_p, size_of(fd_set))
}
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/sys_sem.odin b/core/sys/posix/sys_sem.odin
index 3fcde325b..6b695e766 100644
--- a/core/sys/posix/sys_sem.odin
+++ b/core/sys/posix/sys_sem.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -79,19 +80,15 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
SETALL :: 9
when ODIN_OS == .Darwin {
- // NOTE: this is #pragma pack(4)
-
- semid_ds :: struct #align(4) {
- sem_perm: ipc_perm, /* [PSX] operation permission structure */
- sem_base: c.int32_t, /* 32 bit base ptr for semaphore set */
- sem_nsems: c.ushort, /* [PSX] number of semaphores in set */
- sem_otime: time_t, /* [PSX] last semop() */
+ semid_ds :: struct #max_field_align(4) {
+ sem_perm: ipc_perm, /* [PSX] operation permission structure */
+ sem_base: c.int32_t, /* 32 bit base ptr for semaphore set */
+ sem_nsems: c.ushort, /* [PSX] number of semaphores in set */
+ sem_otime: time_t, /* [PSX] last semop() */
sem_pad1: c.int32_t,
- using _: struct #align(4) {
- sem_ctime: time_t, /* [PSX] last time changed by semctl() */
- sem_pad2: c.int32_t,
- sem_pad3: [4]c.int32_t,
- },
+ sem_ctime: time_t, /* [PSX] last time changed by semctl() */
+ sem_pad2: c.int32_t,
+ sem_pad3: [4]c.int32_t,
}
} else when ODIN_OS == .FreeBSD {
semid_ds :: struct {
@@ -127,6 +124,34 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
sem_flg: c.short, /* [PSX] operation flags */
}
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ SEM_UNDO :: 0x1000 // undo the operation on exit
+
+ // Commands for `semctl'.
+ GETPID :: 11
+ GETVAL :: 12
+ GETALL :: 13
+ GETNCNT :: 14
+ GETZCNT :: 15
+ SETVAL :: 16
+ SETALL :: 17
+
+ semid_ds :: struct {
+ sem_perm: ipc_perm, // [PSX] operation permission structure
+ sem_otime: time_t, // [PSX] last semop()
+ __sem_otime_high: c.ulong,
+ sem_ctime: time_t, // [PSX] last time changed by semctl()
+ __sem_ctime_high: c.ulong,
+ sem_nsems: c.ulong, // [PSX] number of semaphores in set
+ __glibc_reserved3: c.ulong,
+ __glibc_reserved4: c.ulong,
+ }
+
+ sembuf :: struct {
+ sem_num: c.ushort, /* [PSX] semaphore number */
+ sem_op: c.short, /* [PSX] semaphore operation */
+ sem_flg: c.short, /* [PSX] operation flags */
+ }
+
}
diff --git a/core/sys/posix/sys_shm.odin b/core/sys/posix/sys_shm.odin
index 3bc883ce4..8f3c56b9c 100644
--- a/core/sys/posix/sys_shm.odin
+++ b/core/sys/posix/sys_shm.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -67,20 +68,16 @@ when ODIN_OS == .Darwin {
shmatt_t :: distinct c.ushort
- // NOTE: this is #pragma pack(4)
-
- shmid_ds :: struct #align(4) {
- shm_perm: ipc_perm, /* [PSX] operation permission structure */
- shm_segsz: c.size_t, /* [PSX] size of segment in bytes */
- shm_lpid: pid_t, /* [PSX] process ID of last shared memory operation */
- shm_cpid: pid_t, /* [PSX] process ID of creator */
- shm_nattch: shmatt_t, /* [PSX] number of current attaches */
- using _: struct #align(4) {
- shm_atime: time_t, /* [PSX] time of last shmat() */
- shm_dtime: time_t, /* [PSX] time of last shmdt() */
- shm_ctime: time_t, /* [PSX] time of last change by shmctl() */
- shm_internal: rawptr,
- },
+ shmid_ds :: struct #max_field_align(4) {
+ shm_perm: ipc_perm, /* [PSX] operation permission structure */
+ shm_segsz: c.size_t, /* [PSX] size of segment in bytes */
+ shm_lpid: pid_t, /* [PSX] process ID of last shared memory operation */
+ shm_cpid: pid_t, /* [PSX] process ID of creator */
+ shm_nattch: shmatt_t, /* [PSX] number of current attaches */
+ shm_atime: time_t, /* [PSX] time of last shmat() */
+ shm_dtime: time_t, /* [PSX] time of last shmdt() */
+ shm_ctime: time_t, /* [PSX] time of last change by shmctl() */
+ shm_internal: rawptr,
}
} else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD {
@@ -141,6 +138,24 @@ when ODIN_OS == .Darwin {
_shm_internal: rawptr,
}
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ SHM_RDONLY :: 0o10000
+ SHM_RND :: 0o20000
+
+ SHMLBA :: 4096
+
+ shmatt_t :: distinct c.ulong
+
+ shmid_ds :: struct {
+ shm_perm: ipc_perm, /* [PSX] operation permission structure */
+ shm_segsz: c.size_t, /* [PSX] size of segment in bytes */
+ shm_atime: time_t, /* [PSX] time of last shmat() */
+ shm_dtime: time_t, /* [PSX] time of last shmdt() */
+ shm_ctime: time_t, /* [PSX] time of last change by shmctl() */
+ shm_cpid: pid_t, /* [PSX] process ID of creator */
+ shm_lpid: pid_t, /* [PSX] process ID of last shared memory operation */
+ shm_nattch: shmatt_t, /* [PSX] number of current attaches */
+ _: [2]c.ulong,
+ }
}
diff --git a/core/sys/posix/sys_socket.odin b/core/sys/posix/sys_socket.odin
index 36c3c1467..4dd6074a3 100644
--- a/core/sys/posix/sys_socket.odin
+++ b/core/sys/posix/sys_socket.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -47,6 +48,12 @@ foreign libc {
addr.sun_family = .UNIX
copy(addr.sun_path[:], "/somepath\x00")
+ /*
+ unlink the socket before binding in case
+ of previous runs not cleaning up the socket
+ */
+ posix.unlink("/somepath")
+
if posix.bind(sfd, (^posix.sockaddr)(&addr), size_of(addr)) != .OK {
/* Handle error */
}
@@ -321,16 +328,25 @@ when ODIN_OS == .NetBSD {
@(private) LSOCKET :: "socket"
}
-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 == .Linux {
socklen_t :: distinct c.uint
- _sa_family_t :: distinct c.uint8_t
+ 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 */
+ }
+ } 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 */
+ 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 */
+ }
}
@@ -339,6 +355,11 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
_SS_PAD1SIZE :: 6
@(private)
_SS_PAD2SIZE :: 240
+ } else when ODIN_OS == .Linux {
+ @(private)
+ _SS_SIZE :: 128
+ @(private)
+ _SS_PADSIZE :: _SS_SIZE - size_of(c.uint16_t) - size_of(c.uint64_t)
} else {
@(private)
_SS_MAXSIZE :: 128
@@ -350,28 +371,52 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
_SS_PAD2SIZE :: _SS_MAXSIZE - size_of(c.uint8_t) - size_of(sa_family_t) - _SS_PAD1SIZE - _SS_ALIGNSIZE
}
- sockaddr_storage :: struct {
- ss_len: c.uint8_t, /* address length */
- ss_family: sa_family_t, /* [PSX] address family */
- __ss_pad1: [_SS_PAD1SIZE]c.char,
- __ss_align: c.int64_t, /* force structure storage alignment */
- __ss_pad2: [_SS_PAD2SIZE]c.char,
- }
+ when ODIN_OS == .Linux {
+ sockaddr_storage :: struct {
+ ss_family: sa_family_t, /* [PSX] address family */
+ __ss_padding: [_SS_PADSIZE]c.char,
+ __ss_align: c.uint64_t, /* force structure storage alignment */
+ }
- msghdr :: struct {
- msg_name: rawptr, /* [PSX] optional address */
- msg_namelen: socklen_t, /* [PSX] size of address */
- msg_iov: [^]iovec, /* [PSX] scatter/gather array */
- msg_iovlen: c.int, /* [PSX] members in msg_iov */
- msg_control: rawptr, /* [PSX] ancillary data */
- msg_controllen: socklen_t, /* [PSX] ancillary data buffer length */
- msg_flags: Msg_Flags, /* [PSX] flags on received message */
- }
+ msghdr :: struct {
+ msg_name: rawptr, /* [PSX] optional address */
+ msg_namelen: socklen_t, /* [PSX] size of address */
+ msg_iov: [^]iovec, /* [PSX] scatter/gather array */
+ msg_iovlen: c.size_t, /* [PSX] members in msg_iov */
+ msg_control: rawptr, /* [PSX] ancillary data */
+ msg_controllen: c.size_t, /* [PSX] ancillary data buffer length */
+ msg_flags: Msg_Flags, /* [PSX] flags on received message */
+ }
+
+ cmsghdr :: struct {
+ cmsg_len: c.size_t, /* [PSX] data byte count, including cmsghdr */
+ cmsg_level: c.int, /* [PSX] originating protocol */
+ cmsg_type: c.int, /* [PSX] protocol-specific type */
+ }
+ } else {
+ sockaddr_storage :: struct {
+ ss_len: c.uint8_t, /* address length */
+ ss_family: sa_family_t, /* [PSX] address family */
+ __ss_pad1: [_SS_PAD1SIZE]c.char,
+ __ss_align: c.int64_t, /* force structure storage alignment */
+ __ss_pad2: [_SS_PAD2SIZE]c.char,
+ }
- cmsghdr :: struct {
- cmsg_len: socklen_t, /* [PSX] data byte count, including cmsghdr */
- cmsg_level: c.int, /* [PSX] originating protocol */
- cmsg_type: c.int, /* [PSX] protocol-specific type */
+ msghdr :: struct {
+ msg_name: rawptr, /* [PSX] optional address */
+ msg_namelen: socklen_t, /* [PSX] size of address */
+ msg_iov: [^]iovec, /* [PSX] scatter/gather array */
+ msg_iovlen: c.int, /* [PSX] members in msg_iov */
+ msg_control: rawptr, /* [PSX] ancillary data */
+ msg_controllen: socklen_t, /* [PSX] ancillary data buffer length */
+ msg_flags: Msg_Flags, /* [PSX] flags on received message */
+ }
+
+ cmsghdr :: struct {
+ cmsg_len: socklen_t, /* [PSX] data byte count, including cmsghdr */
+ cmsg_level: c.int, /* [PSX] originating protocol */
+ cmsg_type: c.int, /* [PSX] protocol-specific type */
+ }
}
SCM_RIGHTS :: 0x01
@@ -421,57 +466,90 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
SOCK_STREAM :: 1
// Options to be accessed at socket level, not protocol level.
- SOL_SOCKET :: 0xffff
-
- SO_ACCEPTCONN :: 0x0002
- SO_BROADCAST :: 0x0020
- SO_DEBUG :: 0x0001
- SO_DONTROUTE :: 0x0010
- SO_ERROR :: 0x1007
- SO_KEEPALIVE :: 0x0008
- SO_OOBINLINE :: 0x0100
- SO_RCVBUF :: 0x1002
- SO_RCVLOWAT :: 0x1004
- SO_REUSEADDR :: 0x0004
- SO_SNDBUF :: 0x1001
- SO_SNDLOWAT :: 0x1003
- SO_TYPE :: 0x1008
-
- when ODIN_OS == .Darwin {
- SO_LINGER :: 0x1080
- SO_RCVTIMEO :: 0x1006
- SO_SNDTIMEO :: 0x1005
- } else when ODIN_OS == .FreeBSD {
- SO_LINGER :: 0x0080
- SO_RCVTIMEO :: 0x1006
- SO_SNDTIMEO :: 0x1005
- } else when ODIN_OS == .NetBSD {
- SO_LINGER :: 0x0080
- SO_RCVTIMEO :: 0x100c
- SO_SNDTIMEO :: 0x100b
- } else when ODIN_OS == .OpenBSD {
- SO_LINGER :: 0x0080
- SO_RCVTIMEO :: 0x1006
- SO_SNDTIMEO :: 0x1005
+ when ODIN_OS == .Linux {
+ SOL_SOCKET :: 1
+
+ SO_ACCEPTCONN :: 30
+ SO_BROADCAST :: 6
+ SO_DEBUG :: 1
+ SO_DONTROUTE :: 5
+ SO_ERROR :: 4
+ SO_KEEPALIVE :: 9
+ SO_OOBINLINE :: 10
+ SO_RCVBUF :: 8
+ SO_RCVLOWAT :: 18
+ SO_REUSEADDR :: 2
+ SO_SNDBUF :: 7
+ SO_SNDLOWAT :: 19
+ SO_TYPE :: 3
+ SO_LINGER :: 13
+
+ SO_RCVTIMEO :: 66
+ SO_SNDTIMEO :: 67
+ } else {
+ SOL_SOCKET :: 0xffff
+
+ SO_ACCEPTCONN :: 0x0002
+ SO_BROADCAST :: 0x0020
+ SO_DEBUG :: 0x0001
+ SO_DONTROUTE :: 0x0010
+ SO_ERROR :: 0x1007
+ SO_KEEPALIVE :: 0x0008
+ SO_OOBINLINE :: 0x0100
+ SO_RCVBUF :: 0x1002
+ SO_RCVLOWAT :: 0x1004
+ SO_REUSEADDR :: 0x0004
+ SO_SNDBUF :: 0x1001
+ SO_SNDLOWAT :: 0x1003
+ SO_TYPE :: 0x1008
+
+ when ODIN_OS == .Darwin {
+ SO_LINGER :: 0x1080
+ SO_RCVTIMEO :: 0x1006
+ SO_SNDTIMEO :: 0x1005
+ } else when ODIN_OS == .FreeBSD {
+ SO_LINGER :: 0x0080
+ SO_RCVTIMEO :: 0x1006
+ SO_SNDTIMEO :: 0x1005
+ } else when ODIN_OS == .NetBSD {
+ SO_LINGER :: 0x0080
+ SO_RCVTIMEO :: 0x100c
+ SO_SNDTIMEO :: 0x100b
+ } else when ODIN_OS == .OpenBSD {
+ SO_LINGER :: 0x0080
+ SO_RCVTIMEO :: 0x1006
+ SO_SNDTIMEO :: 0x1005
+ }
}
// The maximum backlog queue length for listen().
SOMAXCONN :: 128
- MSG_CTRUNC :: 0x20
- MSG_DONTROUTE :: 0x4
- MSG_EOR :: 0x8
- MSG_OOB :: 0x1
- MSG_PEEK :: 0x2
- MSG_TRUNC :: 0x10
- MSG_WAITALL :: 0x40
-
- when ODIN_OS == .Darwin {
- MSG_NOSIGNAL :: 0x80000
- } else when ODIN_OS == .FreeBSD {
- MSG_NOSIGNAL :: 0x00020000
- } else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
- MSG_NOSIGNAL :: 0x0400
+ when ODIN_OS == .Linux {
+ MSG_CTRUNC :: 0x008
+ MSG_DONTROUTE :: 0x004
+ MSG_EOR :: 0x080
+ MSG_OOB :: 0x001
+ MSG_PEEK :: 0x002
+ MSG_TRUNC :: 0x020
+ MSG_WAITALL :: 0x100
+ MSG_NOSIGNAL :: 0x4000
+ } else {
+ MSG_CTRUNC :: 0x20
+ MSG_DONTROUTE :: 0x4
+ MSG_EOR :: 0x8
+ MSG_OOB :: 0x1
+ MSG_PEEK :: 0x2
+ MSG_TRUNC :: 0x10
+ MSG_WAITALL :: 0x40
+
+ when ODIN_OS == .Darwin {
+ MSG_NOSIGNAL :: 0x80000
+ } else when ODIN_OS == .FreeBSD {
+ MSG_NOSIGNAL :: 0x00020000
+ } else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
+ MSG_NOSIGNAL :: 0x0400
+ }
}
AF_INET :: 2
@@ -483,13 +561,12 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
AF_INET6 :: 28
} else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
AF_INET6 :: 24
+ } else when ODIN_OS == .Linux {
+ AF_INET6 :: 10
}
SHUT_RD :: 0
SHUT_RDWR :: 2
SHUT_WR :: 1
-} else {
- #panic("posix is unimplemented for the current target")
}
-
diff --git a/core/sys/posix/sys_stat.odin b/core/sys/posix/sys_stat.odin
index dd66d7d14..61b98ef35 100644
--- a/core/sys/posix/sys_stat.odin
+++ b/core/sys/posix/sys_stat.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -280,20 +281,20 @@ when ODIN_OS == .Darwin {
ino_t :: distinct c.uint64_t
stat_t :: struct {
- st_dev: dev_t, /* [XSI] ID of device containing file */
- st_mode: mode_t, /* [XSI] mode of file */
- st_nlink: nlink_t, /* [XSI] number of hard links */
- st_ino: ino_t, /* [XSI] file serial number */
- st_uid: uid_t, /* [XSI] user ID of the file */
- st_gid: gid_t, /* [XSI] group ID of the file */
- st_rdev: dev_t, /* [XSI] device ID */
- st_atim: timespec, /* [XSI] time of last access */
- st_mtim: timespec, /* [XSI] time of last data modification */
- st_ctim: timespec, /* [XSI] time of last status change */
+ st_dev: dev_t, /* [PSX] ID of device containing file */
+ st_mode: mode_t, /* [PSX] mode of file */
+ st_nlink: nlink_t, /* [PSX] number of hard links */
+ st_ino: ino_t, /* [PSX] file serial number */
+ st_uid: uid_t, /* [PSX] user ID of the file */
+ st_gid: gid_t, /* [PSX] group ID of the file */
+ st_rdev: dev_t, /* [PSX] device ID */
+ 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_birthtimespec: timespec, /* time of file creation(birth) */
- st_size: off_t, /* [XSI] file size, in bytes */
- st_blocks: blkcnt_t, /* [XSI] blocks allocated for file */
- st_blksize: blksize_t, /* [XSI] optimal blocksize for I/O */
+ st_size: off_t, /* [PSX] file size, in bytes */
+ st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
+ st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
st_flags: c.uint32_t, /* user defined flags for file */
st_gen: c.uint32_t, /* file generation number */
st_lspare: c.int32_t, /* RESERVED */
@@ -314,47 +315,47 @@ when ODIN_OS == .Darwin {
when ODIN_ARCH == .i386 {
stat_t :: struct {
- st_dev: dev_t, /* [XSI] ID of device containing file */
- st_ino: ino_t, /* [XSI] file serial number */
- st_nlink: nlink_t, /* [XSI] number of hard links */
- st_mode: mode_t, /* [XSI] mode of file */
+ st_dev: dev_t, /* [PSX] ID of device containing file */
+ st_ino: ino_t, /* [PSX] file serial number */
+ st_nlink: nlink_t, /* [PSX] number of hard links */
+ st_mode: mode_t, /* [PSX] mode of file */
st_padding0: c.int16_t,
- st_uid: uid_t, /* [XSI] user ID of the file */
- st_gid: gid_t, /* [XSI] group ID of the file */
+ st_uid: uid_t, /* [PSX] user ID of the file */
+ st_gid: gid_t, /* [PSX] group ID of the file */
st_padding1: c.int32_t,
- st_rdev: dev_t, /* [XSI] device ID */
+ st_rdev: dev_t, /* [PSX] device ID */
st_atim_ext: c.int32_t,
- st_atim: timespec, /* [XSI] time of last access */
+ st_atim: timespec, /* [PSX] time of last access */
st_mtim_ext: c.int32_t,
- st_mtim: timespec, /* [XSI] time of last data modification */
+ st_mtim: timespec, /* [PSX] time of last data modification */
st_ctim_ext: c.int32_t,
- st_ctim: timespec, /* [XSI] time of last status change */
+ st_ctim: timespec, /* [PSX] time of last status change */
st_birthtimespec: timespec, /* time of file creation(birth) */
- st_size: off_t, /* [XSI] file size, in bytes */
- st_blocks: blkcnt_t, /* [XSI] blocks allocated for file */
- st_blksize: blksize_t, /* [XSI] optimal blocksize for I/O */
+ st_size: off_t, /* [PSX] file size, in bytes */
+ st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
+ st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
st_flags: c.uint32_t, /* user defined flags for file */
st_gen: c.uint64_t,
st_spare: [10]c.uint64_t,
}
} else {
stat_t :: struct {
- st_dev: dev_t, /* [XSI] ID of device containing file */
- st_ino: ino_t, /* [XSI] file serial number */
- st_nlink: nlink_t, /* [XSI] number of hard links */
- st_mode: mode_t, /* [XSI] mode of file */
+ st_dev: dev_t, /* [PSX] ID of device containing file */
+ st_ino: ino_t, /* [PSX] file serial number */
+ st_nlink: nlink_t, /* [PSX] number of hard links */
+ st_mode: mode_t, /* [PSX] mode of file */
st_padding0: c.int16_t,
- st_uid: uid_t, /* [XSI] user ID of the file */
- st_gid: gid_t, /* [XSI] group ID of the file */
+ st_uid: uid_t, /* [PSX] user ID of the file */
+ st_gid: gid_t, /* [PSX] group ID of the file */
st_padding1: c.int32_t,
- st_rdev: dev_t, /* [XSI] device ID */
- st_atim: timespec, /* [XSI] time of last access */
- st_mtim: timespec, /* [XSI] time of last data modification */
- st_ctim: timespec, /* [XSI] time of last status change */
+ st_rdev: dev_t, /* [PSX] device ID */
+ 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_birthtimespec: timespec, /* time of file creation(birth) */
- st_size: off_t, /* [XSI] file size, in bytes */
- st_blocks: blkcnt_t, /* [XSI] blocks allocated for file */
- st_blksize: blksize_t, /* [XSI] optimal blocksize for I/O */
+ st_size: off_t, /* [PSX] file size, in bytes */
+ st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
+ st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
st_flags: c.uint32_t, /* user defined flags for file */
st_gen: c.uint64_t,
st_spare: [10]c.uint64_t,
@@ -374,20 +375,20 @@ when ODIN_OS == .Darwin {
ino_t :: distinct c.uint64_t
stat_t :: struct {
- st_dev: dev_t, /* [XSI] ID of device containing file */
- st_mode: mode_t, /* [XSI] mode of file */
- st_ino: ino_t, /* [XSI] file serial number */
- st_nlink: nlink_t, /* [XSI] number of hard links */
- st_uid: uid_t, /* [XSI] user ID of the file */
- st_gid: gid_t, /* [XSI] group ID of the file */
- st_rdev: dev_t, /* [XSI] device ID */
- st_atim: timespec, /* [XSI] time of last access */
- st_mtim: timespec, /* [XSI] time of last data modification */
- st_ctim: timespec, /* [XSI] time of last status change */
+ st_dev: dev_t, /* [PSX] ID of device containing file */
+ st_mode: mode_t, /* [PSX] mode of file */
+ st_ino: ino_t, /* [PSX] file serial number */
+ 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_rdev: dev_t, /* [PSX] device ID */
+ 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_birthtimespec: timespec, /* time of file creation(birth) */
- st_size: off_t, /* [XSI] file size, in bytes */
- st_blocks: blkcnt_t, /* [XSI] blocks allocated for file */
- st_blksize: blksize_t, /* [XSI] optimal blocksize for I/O */
+ st_size: off_t, /* [PSX] file size, in bytes */
+ st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
+ st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
st_flags: c.uint32_t, /* user defined flags for file */
st_gen: c.uint64_t,
st_spare: [2]c.uint32_t,
@@ -406,19 +407,19 @@ when ODIN_OS == .Darwin {
ino_t :: distinct c.uint64_t
stat_t :: struct {
- st_mode: mode_t, /* [XSI] mode of file */
- st_dev: dev_t, /* [XSI] ID of device containing file */
- st_ino: ino_t, /* [XSI] file serial number */
- st_nlink: nlink_t, /* [XSI] number of hard links */
- st_uid: uid_t, /* [XSI] user ID of the file */
- st_gid: gid_t, /* [XSI] group ID of the file */
- st_rdev: dev_t, /* [XSI] device ID */
- st_atim: timespec, /* [XSI] time of last access */
- st_mtim: timespec, /* [XSI] time of last data modification */
- st_ctim: timespec, /* [XSI] time of last status change */
- st_size: off_t, /* [XSI] file size, in bytes */
- st_blocks: blkcnt_t, /* [XSI] blocks allocated for file */
- st_blksize: blksize_t, /* [XSI] optimal blocksize for I/O */
+ st_mode: mode_t, /* [PSX] mode of file */
+ st_dev: dev_t, /* [PSX] ID of device containing file */
+ st_ino: ino_t, /* [PSX] file serial number */
+ 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_rdev: dev_t, /* [PSX] device ID */
+ 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_size: off_t, /* [PSX] file size, in bytes */
+ st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
+ st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
st_flags: c.uint32_t, /* user defined flags for file */
st_gen: c.int32_t,
st_birthtimespec: timespec,
@@ -427,6 +428,58 @@ when ODIN_OS == .Darwin {
UTIME_NOW :: -2
UTIME_OMIT :: -1
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ dev_t :: distinct u64
+ _mode_t :: distinct c.uint
+ blkcnt_t :: distinct i64
+
+ when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
+ nlink_t :: distinct c.uint
+ blksize_t :: distinct c.int
+ } else {
+ nlink_t :: distinct c.size_t
+ blksize_t :: distinct c.long
+ }
+
+ ino_t :: distinct u64
+
+ when ODIN_ARCH == .amd64 {
+ stat_t :: struct {
+ st_dev: dev_t, /* [PSX] ID of device containing file */
+ st_ino: ino_t, /* [PSX] file serial number */
+ st_nlink: nlink_t, /* [PSX] number of hard links */
+ st_mode: mode_t, /* [PSX] mode of file */
+ st_uid: uid_t, /* [PSX] user ID of the file */
+ st_gid: gid_t, /* [PSX] group ID of the file */
+ _pad0: c.uint,
+ st_rdev: dev_t, /* [PSX] device ID */
+ st_size: off_t, /* [PSX] file size, in bytes */
+ st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
+ st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
+ 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 */
+ __unused: [3]c.long,
+ }
+ } else {
+ 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_rdev: dev_t, /* [PSX] device ID */
+ __pad: c.ulonglong,
+ st_size: off_t, /* [PSX] file size, in bytes */
+ st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
+ __pad2: c.int,
+ st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
+ 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 */
+ __unused: [2]c.uint,
+ }
+ }
}
diff --git a/core/sys/posix/sys_statvfs.odin b/core/sys/posix/sys_statvfs.odin
index eb6c16806..47c810135 100644
--- a/core/sys/posix/sys_statvfs.odin
+++ b/core/sys/posix/sys_statvfs.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -130,6 +131,27 @@ when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD {
ST_RDONLY :: 0x00000001
ST_NOSUID :: 0x00000008
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ fsblkcnt_t :: distinct c.uint64_t
+
+ statvfs_t :: struct {
+ f_bsize: c.ulong, /* [PSX] file system block size */
+ f_frsize: c.ulong, /* [PSX] fundamental file system block size */
+ f_blocks: fsblkcnt_t, /* [PSX] total number of blocks on file system in units of f_frsize */
+ f_bfree: fsblkcnt_t, /* [PSX] total number of free blocks */
+ f_bavail: fsblkcnt_t, /* [PSX] number of free blocks available to non-privileged process */
+ f_files: fsblkcnt_t, /* [PSX] total number of file serial numbers */
+ f_ffree: fsblkcnt_t, /* [PSX] total number of free file serial numbers */
+ f_favail: fsblkcnt_t, /* [PSX] number of file serial numbers available to non-privileged process */
+ f_fsid: c.ulong, /* [PSX] file system ID */
+ _: [2*size_of(c.int)-size_of(c.long)]byte,
+ f_flag: VFS_Flags, /* [PSX] bit mask of f_flag values */
+ f_namemax: c.ulong, /* [PSX] maximum filename length */
+ f_type: c.uint,
+ __reserved: [5]c.int,
+ }
+
+ ST_RDONLY :: 0x00000001
+ ST_NOSUID :: 0x00000002
}
diff --git a/core/sys/posix/sys_time.odin b/core/sys/posix/sys_time.odin
index 093fdd688..3036352aa 100644
--- a/core/sys/posix/sys_time.odin
+++ b/core/sys/posix/sys_time.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -66,7 +67,7 @@ when ODIN_OS == .NetBSD {
@(private) LUTIMES :: "utimes"
}
-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 == .Linux {
itimerval :: struct {
it_interval: timeval, /* [PSX] timer interval */
@@ -77,6 +78,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
ITIMER_VIRTUAL :: 1
ITIMER_PROF :: 2
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/sys_times.odin b/core/sys/posix/sys_times.odin
index 685ced515..113e3f963 100644
--- a/core/sys/posix/sys_times.odin
+++ b/core/sys/posix/sys_times.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
when ODIN_OS == .Darwin {
@@ -24,7 +25,7 @@ when ODIN_OS == .NetBSD {
@(private) LTIMES :: "times"
}
-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 == .Linux {
tms :: struct {
tms_utime: clock_t, /* [PSX] user CPU time */
@@ -33,6 +34,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
tms_cstime: clock_t, /* [PSX] terminated children system CPU time */
}
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/sys_uio.odin b/core/sys/posix/sys_uio.odin
index 01664e576..a0ad2934e 100644
--- a/core/sys/posix/sys_uio.odin
+++ b/core/sys/posix/sys_uio.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -30,13 +31,11 @@ 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 {
+when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
iovec :: struct {
iov_base: rawptr, /* [PSX] base address of I/O memory region */
iov_len: c.size_t, /* [PSX] size of the region iov_base points to */
}
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/sys_un.odin b/core/sys/posix/sys_un.odin
index 146882051..ca5c4ee31 100644
--- a/core/sys/posix/sys_un.odin
+++ b/core/sys/posix/sys_un.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -12,6 +13,11 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
sun_path: [104]c.char, /* [PSX] socket pathname */
}
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ sockaddr_un :: struct {
+ sun_family: sa_family_t, /* [PSX] address family */
+ sun_path: [108]c.char, /* [PSX] socket pathname */
+ }
+
}
diff --git a/core/sys/posix/sys_utsname.odin b/core/sys/posix/sys_utsname.odin
index 803f40ffd..64930160f 100644
--- a/core/sys/posix/sys_utsname.odin
+++ b/core/sys/posix/sys_utsname.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -50,6 +51,17 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
machine: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] hardware type */
}
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ @(private)
+ _SYS_NAMELEN :: 65
+
+ utsname :: struct {
+ sysname: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] name of OS */
+ nodename: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] name of this network node */
+ release: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] release level */
+ version: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] version level */
+ machine: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] hardware type */
+ __domainname: [_SYS_NAMELEN]c.char `fmt:"s,0"`,
+ }
}
diff --git a/core/sys/posix/sys_wait.odin b/core/sys/posix/sys_wait.odin
index 8421c8bfd..812bd8c62 100644
--- a/core/sys/posix/sys_wait.odin
+++ b/core/sys/posix/sys_wait.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -124,11 +125,11 @@ WIFCONTINUED :: #force_inline proc "contextless" (x: c.int) -> bool {
idtype_t :: enum c.int {
// Wait for any children and `id` is ignored.
- P_ALL,
+ P_ALL = _P_ALL,
// Wait for any child wiith a process group ID equal to `id`.
- P_PID,
+ P_PID = _P_PID,
// Wait for any child with a process group ID equal to `id`.
- P_PGID,
+ P_PGID = _P_PGID,
}
Wait_Flag_Bits :: enum c.int {
@@ -166,6 +167,10 @@ when ODIN_OS == .Darwin {
WNOWAIT :: 0x00000020
WSTOPPED :: 0x00000008
+ _P_ALL :: 0
+ _P_PID :: 1
+ _P_PGID :: 2
+
@(private)
_WSTATUS :: #force_inline proc "contextless" (x: c.int) -> c.int {
return x & 0o177
@@ -221,6 +226,10 @@ when ODIN_OS == .Darwin {
WNOWAIT :: 8
WSTOPPED :: 2
+ _P_ALL :: 7
+ _P_PID :: 0
+ _P_PGID :: 2
+
@(private)
_WSTATUS :: #force_inline proc "contextless" (x: c.int) -> c.int {
return x & 0o177
@@ -275,6 +284,10 @@ when ODIN_OS == .Darwin {
WNOWAIT :: 0x00010000
WSTOPPED :: 0x00000002
+ _P_ALL :: 0
+ _P_PID :: 1
+ _P_PGID :: 2
+
@(private)
_WSTATUS :: #force_inline proc "contextless" (x: c.int) -> c.int {
return x & 0o177
@@ -330,6 +343,10 @@ when ODIN_OS == .Darwin {
WNOWAIT :: 0x00010000
WSTOPPED :: 0x00000002
+ _P_ALL :: 0
+ _P_PID :: 2
+ _P_PGID :: 1
+
@(private)
_WSTATUS :: #force_inline proc "contextless" (x: c.int) -> c.int {
return x & 0o177
@@ -375,6 +392,54 @@ when ODIN_OS == .Darwin {
return (x & _WCONTINUED) == _WCONTINUED
}
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ id_t :: distinct c.uint
+
+ WCONTINUED :: 8
+ WNOHANG :: 1
+ WUNTRACED :: 2
+
+ WEXITED :: 4
+ WNOWAIT :: 0x1000000
+ WSTOPPED :: 2
+
+ _P_ALL :: 0
+ _P_PID :: 1
+ _P_PGID :: 2
+
+ @(private)
+ _WIFEXITED :: #force_inline proc "contextless" (x: c.int) -> bool {
+ return _WTERMSIG(x) == nil
+ }
+
+ @(private)
+ _WEXITSTATUS :: #force_inline proc "contextless" (x: c.int) -> c.int {
+ return (x & 0xff00) >> 8
+ }
+
+ @(private)
+ _WIFSIGNALED :: #force_inline proc "contextless" (x: c.int) -> bool {
+ return (x & 0xffff) - 1 < 0xff
+ }
+
+ @(private)
+ _WTERMSIG :: #force_inline proc "contextless" (x: c.int) -> Signal {
+ return Signal(x & 0x7f)
+ }
+
+ @(private)
+ _WIFSTOPPED :: #force_inline proc "contextless" (x: c.int) -> bool {
+ return ((x & 0xffff) * 0x10001) >> 8 > 0x7f00
+ }
+
+ @(private)
+ _WSTOPSIG :: #force_inline proc "contextless" (x: c.int) -> Signal {
+ return Signal(_WEXITSTATUS(x))
+ }
+
+ @(private)
+ _WIFCONTINUED :: #force_inline proc "contextless" (x: c.int) -> bool {
+ return x == 0xffff
+ }
}
diff --git a/core/sys/posix/termios.odin b/core/sys/posix/termios.odin
index c73936d58..0c07eceb9 100644
--- a/core/sys/posix/termios.odin
+++ b/core/sys/posix/termios.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -152,7 +153,7 @@ CControl_Flag_Bits :: enum tcflag_t {
CControl_Flags :: bit_set[CControl_Flag_Bits; tcflag_t]
// character size mask
-CSIZE :: CControl_Flags{ .CS6, .CS7, .CS8 }
+CSIZE :: transmute(CControl_Flags)tcflag_t(_CSIZE)
COutput_Flag_Bits :: enum tcflag_t {
OPOST = log2(OPOST), /* enable following output processing */
@@ -181,17 +182,17 @@ COutput_Flag_Bits :: enum tcflag_t {
COutput_Flags :: bit_set[COutput_Flag_Bits; tcflag_t]
// \n delay mask
-NLDLY :: COutput_Flags{ .NL1, COutput_Flag_Bits(9) }
+NLDLY :: transmute(COutput_Flags)tcflag_t(_NLDLY)
// \r delay mask
-CRDLY :: COutput_Flags{ .CR1, .CR2, .CR3 }
+CRDLY :: transmute(COutput_Flags)tcflag_t(_CRDLY)
// horizontal tab delay mask
-TABDLY :: COutput_Flags{ .TAB1, .TAB3, COutput_Flag_Bits(2) }
+TABDLY :: transmute(COutput_Flags)tcflag_t(_TABDLY)
// \b delay mask
-BSDLY :: COutput_Flags{ .BS1 }
+BSDLY :: transmute(COutput_Flags)tcflag_t(_BSDLY)
// vertical tab delay mask
-VTDLY :: COutput_Flags{ .VT1 }
+VTDLY :: transmute(COutput_Flags)tcflag_t(_VTDLY)
// form feed delay mask
-FFDLY :: COutput_Flags{ .FF1 }
+FFDLY :: transmute(COutput_Flags)tcflag_t(_FFDLY)
speed_t :: enum _speed_t {
B0 = B0,
@@ -596,6 +597,4 @@ when ODIN_OS == .Darwin {
TCOOFF :: 0
TCOON :: 1
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/time.odin b/core/sys/posix/time.odin
index 5c6ebcf2f..f9c51c63c 100644
--- a/core/sys/posix/time.odin
+++ b/core/sys/posix/time.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -229,6 +230,16 @@ when ODIN_OS == .Darwin {
getdate_err: Errno = .ENOSYS // NOTE: looks like it's not a thing on OpenBSD.
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ clockid_t :: distinct c.int
+
+ CLOCK_MONOTONIC :: 1
+ CLOCK_PROCESS_CPUTIME_ID :: 2
+ CLOCK_REALTIME :: 0
+ CLOCK_THREAD_CPUTIME_ID :: 3
+
+ foreign lib {
+ getdate_err: Errno
+ }
}
diff --git a/core/sys/posix/ulimit.odin b/core/sys/posix/ulimit.odin
index 067b83271..0f87641fa 100644
--- a/core/sys/posix/ulimit.odin
+++ b/core/sys/posix/ulimit.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -31,13 +32,11 @@ Ulimit_Cmd :: enum c.int {
SETFSIZE = UL_SETFSIZE,
}
-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 == .Linux {
UL_GETFSIZE :: 1
UL_SETFSIZE :: 2
// NOTE: I don't think OpenBSD implements this API.
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/unistd.odin b/core/sys/posix/unistd.odin
index 15dbb576f..0526b3235 100644
--- a/core/sys/posix/unistd.odin
+++ b/core/sys/posix/unistd.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -12,19 +13,6 @@ when ODIN_OS == .Darwin {
foreign lib {
/*
- Checks the file named by the pathname pointed to by the path argument for
- accessibility according to the bit pattern contained in amode.
-
- Example:
- if (posix.access("/tmp/myfile", posix.F_OK) != .OK) {
- fmt.printfln("/tmp/myfile access check failed: %v", posix.strerror(posix.errno()))
- }
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html ]]
- */
- access :: proc(path: cstring, amode: Mode_Flags = F_OK) -> result ---
-
- /*
Equivalent to `access` but relative paths are resolved based on `fd`.
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html ]]
@@ -43,18 +31,6 @@ foreign lib {
alarm :: proc(seconds: c.uint) -> c.uint ---
/*
- Causes the directory named by path to become the current working directory.
-
- Example:
- if (posix.chdir("/tmp") == .OK) {
- fmt.println("changed current directory to /tmp")
- }
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html ]]
- */
- chdir :: proc(path: cstring) -> result ---
-
- /*
Equivalent to chdir but instead of a path the fildes is resolved to a directory.
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html ]]
@@ -205,15 +181,6 @@ foreign lib {
dup2 :: proc(fildes, fildes2: FD) -> FD ---
/*
- Exits but, shall not call functions registered with atexit() nor any registered signal handlers.
- Open streams shall not be flushed.
- Whether open streams are closed (without flushing) is implementation-defined. Finally, the calling process shall be terminated with the consequences described below.
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html ]]
- */
- _exit :: proc(status: c.int) -> ! ---
-
- /*
The exec family of functions shall replace the current process image with a new process image.
The new image shall be constructed from a regular, executable file called the new process image file.
There shall be no return from a successful exec,
@@ -393,44 +360,6 @@ foreign lib {
ftruncate :: proc(fildes: FD, length: off_t) -> result ---
/*
- Places an absolute pathname of the current working directory into buf.
-
- Returns: buf as a cstring on success, nil (setting errno) on failure
-
- Example:
- size: int
- path_max := posix.pathconf(".", ._PATH_MAX)
- if path_max == -1 {
- size = 1024
- } else if path_max > 10240 {
- size = 10240
- } else {
- size = int(path_max)
- }
-
- buf: [dynamic]byte
- cwd: cstring
- for ; cwd == nil; size *= 2 {
- if err := resize(&buf, size); err != nil {
- fmt.panicf("allocation failure: %v", err)
- }
-
- cwd = posix.getcwd(raw_data(buf), len(buf))
- if cwd == nil {
- errno := posix.errno()
- if errno != .ERANGE {
- fmt.panicf("getcwd failure: %v", posix.strerror(errno))
- }
- }
- }
-
- fmt.println(path_max, cwd)
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html ]]
- */
- getcwd :: proc(buf: [^]c.char, size: c.size_t) -> cstring ---
-
- /*
Returns the effective group ID of the calling process.
Returns: the ID, no failure is defined
@@ -830,13 +759,6 @@ foreign lib {
readlinkat :: proc(fd: FD, path: cstring, buf: [^]byte, bufsize: c.size_t) -> c.ssize_t ---
/*
- Remove an (empty) directory.
-
- ]] More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html ]]
- */
- rmdir :: proc(path: cstring) -> result ---
-
- /*
Set the effective group ID.
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/setegid.html ]]
@@ -913,13 +835,6 @@ foreign lib {
sleep :: proc(seconds: c.uint) -> c.uint ---
/*
- Copy nbyte bytes, from src, to dest, exchanging adjecent bytes.
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/swab.html ]]
- */
- swab :: proc(src: [^]byte, dest: [^]byte, nbytes: c.ssize_t) ---
-
- /*
Schedule file system updates.
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sync.html ]]
@@ -959,13 +874,6 @@ foreign lib {
ttyname_r :: proc(fildes: FD, name: [^]byte, namesize: c.size_t) -> Errno ---
/*
- Remove a directory entry.
-
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html ]]
- */
- unlink :: proc(path: cstring) -> result ---
-
- /*
Equivalent to unlink or rmdir (if flag is .REMOVEDIR) but relative paths are relative to the dir fd.
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html ]]
@@ -973,20 +881,6 @@ foreign lib {
unlinkat :: proc(fd: FD, path: cstring, flag: AT_Flags) -> result ---
}
-STDERR_FILENO :: 2
-STDIN_FILENO :: 0
-STDOUT_FILENO :: 1
-
-Mode_Flag_Bits :: enum c.int {
- X_OK = log2(X_OK),
- W_OK = log2(W_OK),
- R_OK = log2(R_OK),
-}
-Mode_Flags :: bit_set[Mode_Flag_Bits; c.int]
-
-#assert(_F_OK == 0)
-F_OK :: Mode_Flags{}
-
CS :: enum c.int {
_PATH = _CS_PATH,
_POSIX_V6_ILP32_OFF32_CFLAGS = _CS_POSIX_V6_ILP32_OFF32_CFLAGS,
@@ -1181,20 +1075,20 @@ when ODIN_OS == .Darwin {
F_TLOCK :: 2
F_ULOCK :: 0
- _CS_PATH :: 1
- _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2
- _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3
- _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4
- _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5
- _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6
- _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7
- _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8
- _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9
- _CS_POSIX_V6_LP64_OFF64_LIBS :: 10
- _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11
- _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12
- _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13
- _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14
+ _CS_PATH :: 1
+ _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2
+ _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3
+ _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4
+ _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5
+ _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6
+ _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7
+ _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8
+ _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9
+ _CS_POSIX_V6_LP64_OFF64_LIBS :: 10
+ _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11
+ _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12
+ _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13
+ _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14
_PC_LINK_MAX :: 1
_PC_MAX_CANON :: 2
@@ -1362,20 +1256,20 @@ when ODIN_OS == .Darwin {
F_TLOCK :: 2
F_ULOCK :: 0
- _CS_PATH :: 1
- _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2
- _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3
- _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4
- _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5
- _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6
- _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7
- _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8
- _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9
- _CS_POSIX_V6_LP64_OFF64_LIBS :: 10
- _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11
- _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12
- _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13
- _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14
+ _CS_PATH :: 1
+ _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2
+ _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3
+ _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4
+ _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5
+ _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6
+ _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7
+ _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8
+ _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9
+ _CS_POSIX_V6_LP64_OFF64_LIBS :: 10
+ _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11
+ _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12
+ _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13
+ _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14
_PC_LINK_MAX :: 1
_PC_MAX_CANON :: 2
@@ -1543,20 +1437,20 @@ when ODIN_OS == .Darwin {
F_TLOCK :: 2
F_ULOCK :: 0
- _CS_PATH :: 1
- _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2
- _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3
- _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4
- _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5
- _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6
- _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7
- _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8
- _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9
- _CS_POSIX_V6_LP64_OFF64_LIBS :: 10
- _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11
- _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12
- _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13
- _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14
+ _CS_PATH :: 1
+ _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2
+ _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3
+ _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4
+ _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5
+ _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6
+ _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7
+ _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8
+ _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9
+ _CS_POSIX_V6_LP64_OFF64_LIBS :: 10
+ _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11
+ _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12
+ _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13
+ _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14
_PC_LINK_MAX :: 1
_PC_MAX_CANON :: 2
@@ -1655,7 +1549,6 @@ when ODIN_OS == .Darwin {
_SC_TTY_NAME_MAX :: 68
_SC_HOST_NAME_MAX :: 69
- _SC_PASS_MAX :: 70
_SC_REGEXP :: 71
_SC_SHELL :: 72
_SC_SYMLOOP_MAX :: 73
@@ -1729,20 +1622,20 @@ when ODIN_OS == .Darwin {
F_TLOCK :: 2
F_ULOCK :: 0
- _CS_PATH :: 1
- _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2
- _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3
- _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4
- _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5
- _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6
- _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7
- _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8
- _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9
- _CS_POSIX_V6_LP64_OFF64_LIBS :: 10
- _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11
- _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12
- _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13
- _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14
+ _CS_PATH :: 1
+ _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2
+ _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3
+ _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4
+ _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5
+ _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6
+ _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7
+ _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8
+ _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9
+ _CS_POSIX_V6_LP64_OFF64_LIBS :: 10
+ _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11
+ _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12
+ _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13
+ _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14
_PC_LINK_MAX :: 1
_PC_MAX_CANON :: 2
@@ -1911,7 +1804,192 @@ when ODIN_OS == .Darwin {
_POSIX_VDISABLE :: '\377'
-} else {
- #panic("posix is unimplemented for the current target")
-}
+} else when ODIN_OS == .Linux {
+
+ _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 :: 2
+
+ _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 1116
+ _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 1117
+ _CS_POSIX_V6_ILP32_OFF32_LIBS :: 1118
+ _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 1120
+ _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 1121
+ _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 1122
+ _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 1124
+ _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 1125
+ _CS_POSIX_V6_LP64_OFF64_LIBS :: 1126
+ _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 1128
+ _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 1129
+ _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 1130
+
+ _PC_LINK_MAX :: 1
+ _PC_MAX_CANON :: 2
+ _PC_MAX_INPUT :: 3
+ _PC_NAME_MAX :: 4
+ _PC_PATH_MAX :: 5
+ _PC_PIPE_BUF :: 6
+ _PC_CHOWN_RESTRICTED :: 7
+ _PC_NO_TRUNC :: 8
+ _PC_VDISABLE :: 9
+ _PC_SYNC_IO :: 10
+ _PC_ASYNC_IO :: 11
+ _PC_PRIO_IO :: 12
+ _PC_FILESIZEBITS :: 14
+ _PC_REC_INCR_XFER_SIZE :: 15
+ _PC_REC_MAX_XFER_SIZE :: 16
+ _PC_REC_MIN_XFER_SIZE :: 17
+ _PC_REC_XFER_ALIGN :: 18
+ _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
+ _SC_NGROUPS_MAX :: 4
+ _SC_OPEN_MAX :: 5
+ _SC_STREAM_MAX :: 6
+ _SC_TZNAME_MAX :: 7
+ _SC_JOB_CONTROL :: 8
+ _SC_SAVED_IDS :: 9
+ _SC_REALTIME_SIGNALS :: 10
+ _SC_PRIORITY_SCHEDULING :: 11
+ _SC_TIMERS :: 12
+ _SC_ASYNCHRONOUS_IO :: 13
+ _SC_PRIORITIZED_IO :: 14
+ _SC_SYNCHRONIZED_IO :: 15
+ _SC_FSYNC :: 16
+ _SC_MAPPED_FILES :: 17
+ _SC_MEMLOCK :: 18
+ _SC_MEMLOCK_RANGE :: 19
+ _SC_MEMORY_PROTECTION :: 20
+ _SC_MESSAGE_PASSING :: 21
+ _SC_SEMAPHORES :: 22
+ _SC_SHARED_MEMORY_OBJECTS :: 23
+ _SC_AIO_LISTIO_MAX :: 24
+ _SC_AIO_MAX :: 25
+ _SC_AIO_PRIO_DELTA_MAX :: 26
+ _SC_DELAYTIMER_MAX :: 27
+ _SC_MQ_OPEN_MAX :: 28
+ _SC_MQ_PRIO_MAX :: 29
+ _SC_VERSION :: 30
+ _SC_PAGESIZE :: 31
+ _SC_PAGE_SIZE :: _SC_PAGESIZE
+ _SC_RTSIG_MAX :: 32
+ _SC_SEM_NSEMS_MAX :: 33
+ _SC_SEM_VALUE_MAX :: 34
+ _SC_SIGQUEUE_MAX :: 35
+ _SC_TIMER_MAX :: 36
+ _SC_BC_BASE_MAX :: 37
+ _SC_BC_DIM_MAX :: 38
+ _SC_BC_SCALE_MAX :: 39
+ _SC_BC_STRING_MAX :: 40
+ _SC_COLL_WEIGHTS_MAX :: 41
+ _SC_EXPR_NEST_MAX :: 43
+ _SC_LINE_MAX :: 44
+ _SC_RE_DUP_MAX :: 45
+ _SC_2_VERSION :: 47
+ _SC_2_C_BIND :: 48
+ _SC_2_C_DEV :: 49
+ _SC_2_FORT_DEV :: 50
+ _SC_2_FORT_RUN :: 51
+ _SC_2_SW_DEV :: 52
+ _SC_2_LOCALEDEF :: 53
+
+ _SC_IOV_MAX :: 62
+ _SC_THREADS :: 69
+ _SC_THREAD_SAFE_FUNCTIONS :: 70
+ _SC_GETGR_R_SIZE_MAX :: 71
+ _SC_GETPW_R_SIZE_MAX :: 72
+ _SC_LOGIN_NAME_MAX :: 73
+ _SC_TTY_NAME_MAX :: 74
+ _SC_THREAD_DESTRUCTOR_ITERATIONS :: 75
+ _SC_THREAD_KEYS_MAX :: 76
+ _SC_THREAD_STACK_MIN :: 77
+ _SC_THREAD_THREADS_MAX :: 78
+ _SC_THREAD_ATTR_STACKADDR :: 79
+ _SC_THREAD_ATTR_STACKSIZE :: 80
+ _SC_THREAD_PRIORITY_SCHEDULING :: 81
+ _SC_THREAD_PRIO_INHERIT :: 82
+ _SC_THREAD_PRIO_PROTECT :: 83
+ _SC_THREAD_PROCESS_SHARED :: 84
+ _SC_NPROCESSORS_CONF :: 85
+ _SC_NPROCESSORS_ONLN :: 86
+ _SC_PHYS_PAGES :: 87
+ _SC_AVPHYS_PAGES :: 88
+ _SC_ATEXIT_MAX :: 89
+ _SC_PASS_MAX :: 90
+ _SC_XOPEN_VERSION :: 91
+ _SC_XOPEN_UNIX :: 92
+ _SC_XOPEN_CRYPT :: 93
+ _SC_XOPEN_ENH_I18N :: 94
+ _SC_XOPEN_SHM :: 95
+ _SC_2_CHAR_TERM :: 96
+ _SC_2_UPE :: 97
+
+ _SC_XOPEN_LEGACY :: 129
+ _SC_XOPEN_REALTIME :: 130
+ _SC_XOPEN_REALTIME_THREADS :: 131
+ _SC_ADVISORY_INFO :: 132
+ _SC_BARRIERS :: 133
+ _SC_CLOCK_SELECTION :: 137
+ _SC_CPUTIME :: 138
+ _SC_THREAD_CPUTIME :: 139
+ _SC_MONOTONIC_CLOCK :: 149
+ _SC_READER_WRITER_LOCKS :: 153
+ _SC_SPIN_LOCKS :: 154
+ _SC_REGEXP :: 155
+ _SC_SHELL :: 157
+ _SC_SPAWN :: 159
+ _SC_SPORADIC_SERVER :: 160
+ _SC_THREAD_SPORADIC_SERVER :: 161
+ _SC_TIMEOUTS :: 164
+ _SC_TYPED_MEMORY_OBJECTS :: 165
+ _SC_2_PBS :: 168
+ _SC_2_PBS_ACCOUNTING :: 169
+ _SC_2_PBS_LOCATE :: 170
+ _SC_2_PBS_MESSAGE :: 171
+ _SC_2_PBS_TRACK :: 172
+ _SC_SYMLOOP_MAX :: 173
+ _SC_2_PBS_CHECKPOINT :: 174
+ _SC_V6_ILP32_OFF32 :: 175
+ _SC_V6_ILP32_OFFBIG :: 176
+ _SC_V6_LP64_OFF64 :: 177
+ _SC_V6_LPBIG_OFFBIG :: 178
+ _SC_HOST_NAME_MAX :: 179
+ _SC_TRACE :: 180
+ _SC_TRACE_EVENT_FILTER :: 181
+ _SC_TRACE_INHERIT :: 182
+ _SC_TRACE_LOG :: 183
+
+ _SC_IPV6 :: 234
+ _SC_RAW_SOCKETS :: 235
+ _SC_V7_ILP32_OFF32 :: 236
+ _SC_V7_ILP32_OFFBIG :: 237
+ _SC_V7_LP64_OFF64 :: 238
+ _SC_V7_LPBIG_OFFBIG :: 239
+ _SC_SS_REPL_MAX :: 240
+ _SC_TRACE_EVENT_NAME_MAX :: 241
+ _SC_TRACE_NAME_MAX :: 242
+ _SC_TRACE_SYS_MAX :: 243
+ _SC_TRACE_USER_EVENT_MAX :: 244
+ _SC_XOPEN_STREAMS :: 245
+ _SC_THREAD_ROBUST_PRIO_INHERIT :: 246
+ _SC_THREAD_ROBUST_PRIO_PROTECT :: 247
+
+ // NOTE: Not implemented.
+ _SC_XOPEN_UUCP :: 0
+ // NOTE: Not implemented.
+ _POSIX_VDISABLE :: 0
+
+}
diff --git a/core/sys/posix/unistd_libc.odin b/core/sys/posix/unistd_libc.odin
new file mode 100644
index 000000000..bbfe3d59d
--- /dev/null
+++ b/core/sys/posix/unistd_libc.odin
@@ -0,0 +1,153 @@
+#+build linux, windows, darwin, netbsd, openbsd, freebsd
+package posix
+
+import "core:c"
+
+when ODIN_OS == .Windows {
+ foreign import lib "system:libucrt.lib"
+} else when ODIN_OS == .Darwin {
+ foreign import lib "system:System.framework"
+} else {
+ foreign import lib "system:c"
+}
+
+// unistd.h - standard symbolic constants and types
+
+foreign lib {
+ /*
+ Checks the file named by the pathname pointed to by the path argument for
+ accessibility according to the bit pattern contained in amode.
+
+ Example:
+ if (posix.access("/tmp/myfile", posix.F_OK) != .OK) {
+ fmt.printfln("/tmp/myfile access check failed: %v", posix.strerror(posix.errno()))
+ }
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html ]]
+ */
+ @(link_name=LACCESS)
+ access :: proc(path: cstring, amode: Mode_Flags = F_OK) -> result ---
+
+ /*
+ Causes the directory named by path to become the current working directory.
+
+ Example:
+ if (posix.chdir("/tmp") == .OK) {
+ fmt.println("changed current directory to /tmp")
+ }
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html ]]
+ */
+ @(link_name=LCHDIR)
+ chdir :: proc(path: cstring) -> result ---
+
+ /*
+ Exits but, shall not call functions registered with atexit() nor any registered signal handlers.
+ Open streams shall not be flushed.
+ Whether open streams are closed (without flushing) is implementation-defined. Finally, the calling process shall be terminated with the consequences described below.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html ]]
+ */
+ _exit :: proc(status: c.int) -> ! ---
+
+ /*
+ Places an absolute pathname of the current working directory into buf.
+
+ Returns: buf as a cstring on success, nil (setting errno) on failure
+
+ Example:
+ size: int
+ path_max := posix.pathconf(".", ._PATH_MAX)
+ if path_max == -1 {
+ size = 1024
+ } else if path_max > 10240 {
+ size = 10240
+ } else {
+ size = int(path_max)
+ }
+
+ buf: [dynamic]byte
+ cwd: cstring
+ for ; cwd == nil; size *= 2 {
+ if err := resize(&buf, size); err != nil {
+ fmt.panicf("allocation failure: %v", err)
+ }
+
+ cwd = posix.getcwd(raw_data(buf), len(buf))
+ if cwd == nil {
+ errno := posix.errno()
+ if errno != .ERANGE {
+ fmt.panicf("getcwd failure: %v", posix.strerror(errno))
+ }
+ }
+ }
+
+ fmt.println(path_max, cwd)
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html ]]
+ */
+ @(link_name=LGETCWD)
+ getcwd :: proc(buf: [^]c.char, size: c.size_t) -> cstring ---
+
+ /*
+ Remove an (empty) directory.
+
+ ]] More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html ]]
+ */
+ @(link_name=LRMDIR)
+ rmdir :: proc(path: cstring) -> result ---
+
+ /*
+ Copy nbyte bytes, from src, to dest, exchanging adjecent bytes.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/swab.html ]]
+ */
+ @(link_name=LSWAB)
+ swab :: proc(src: [^]byte, dest: [^]byte, nbytes: c.ssize_t) ---
+
+ /*
+ Remove a directory entry.
+
+ [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html ]]
+ */
+ @(link_name=LUNLINK)
+ unlink :: proc(path: cstring) -> result ---
+}
+
+when ODIN_OS == .Windows {
+ @(private) LACCESS :: "_access"
+ @(private) LCHDIR :: "_chdir"
+ @(private) LGETCWD :: "_getcwd"
+ @(private) LRMDIR :: "_rmdir"
+ @(private) LSWAB :: "_swab"
+ @(private) LUNLINK :: "_unlink"
+} else {
+ @(private) LACCESS :: "access"
+ @(private) LCHDIR :: "chdir"
+ @(private) LGETCWD :: "getcwd"
+ @(private) LRMDIR :: "rmdir"
+ @(private) LSWAB :: "swab"
+ @(private) LUNLINK :: "unlink"
+}
+
+STDERR_FILENO :: 2
+STDIN_FILENO :: 0
+STDOUT_FILENO :: 1
+
+Mode_Flag_Bits :: enum c.int {
+ X_OK = log2(X_OK),
+ W_OK = log2(W_OK),
+ R_OK = log2(R_OK),
+}
+Mode_Flags :: bit_set[Mode_Flag_Bits; c.int]
+
+#assert(_F_OK == 0)
+F_OK :: Mode_Flags{}
+
+when ODIN_OS == .Windows {
+ _F_OK :: 0
+ X_OK :: 1
+ W_OK :: 2
+ R_OK :: 4
+ #assert(W_OK|R_OK == 6)
+}
diff --git a/core/sys/posix/utime.odin b/core/sys/posix/utime.odin
index 591a6db06..e884eb1a3 100644
--- a/core/sys/posix/utime.odin
+++ b/core/sys/posix/utime.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
when ODIN_OS == .Darwin {
@@ -24,13 +25,11 @@ when ODIN_OS == .NetBSD {
@(private) LUTIME :: "utime"
}
-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 == .Linux {
utimbuf :: struct {
actime: time_t, /* [PSX] access time (seconds since epoch) */
modtime: time_t, /* [PSX] modification time (seconds since epoch) */
}
-} else {
- #panic("posix is unimplemented for the current target")
}
diff --git a/core/sys/posix/wordexp.odin b/core/sys/posix/wordexp.odin
index d730db0f7..a9e6f39a7 100644
--- a/core/sys/posix/wordexp.odin
+++ b/core/sys/posix/wordexp.odin
@@ -1,3 +1,4 @@
+#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
@@ -102,6 +103,25 @@ when ODIN_OS == .Darwin {
WRDE_NOSPACE :: 4
WRDE_SYNTAX :: 6
-} else {
- #panic("posix is unimplemented for the current target")
+} else when ODIN_OS == .Linux {
+
+ wordexp_t :: struct {
+ we_wordc: c.size_t, /* [PSX] count of words matched by words */
+ we_wordv: [^]cstring, /* [PSX] pointer to list of expanded words */
+ we_offs: c.size_t, /* [PSX] slots to reserve at the beginning of we_wordv */
+ }
+
+ WRDE_DOOFFS :: 1 << 0 /* Insert PWORDEXP->we_offs NULLs. */
+ WRDE_APPEND :: 1 << 1 /* Append to results of a previous call. */
+ WRDE_NOCMD :: 1 << 2 /* Don't do command substitution. */
+ WRDE_REUSE :: 1 << 3 /* Reuse storage in PWORDEXP. */
+ WRDE_SHOWERR :: 1 << 4 /* Don't redirect stderr to /dev/null. */
+ WRDE_UNDEF :: 1 << 5 /* Error for expanding undefined variables. */
+
+ WRDE_NOSPACE :: 1
+ WRDE_BADCHAR :: 2
+ WRDE_BADVAL :: 3
+ WRDE_CMDSUB :: 4
+ WRDE_SYNTAX :: 5
+
}
diff --git a/core/sys/unix/pthread_darwin.odin b/core/sys/unix/pthread_darwin.odin
deleted file mode 100644
index eb2cc4c9f..000000000
--- a/core/sys/unix/pthread_darwin.odin
+++ /dev/null
@@ -1,96 +0,0 @@
-#+build darwin
-package unix
-
-import "core:c"
-
-// NOTE(tetra): No 32-bit Macs.
-// Source: _pthread_types.h on my Mac.
-PTHREAD_SIZE :: 8176
-PTHREAD_ATTR_SIZE :: 56
-PTHREAD_MUTEXATTR_SIZE :: 8
-PTHREAD_MUTEX_SIZE :: 56
-PTHREAD_CONDATTR_SIZE :: 8
-PTHREAD_COND_SIZE :: 40
-PTHREAD_ONCE_SIZE :: 8
-PTHREAD_RWLOCK_SIZE :: 192
-PTHREAD_RWLOCKATTR_SIZE :: 16
-
-pthread_t :: distinct u64
-
-pthread_attr_t :: struct {
- sig: c.long,
- _: [PTHREAD_ATTR_SIZE] c.char,
-}
-
-pthread_cond_t :: struct {
- sig: c.long,
- _: [PTHREAD_COND_SIZE] c.char,
-}
-
-pthread_condattr_t :: struct {
- sig: c.long,
- _: [PTHREAD_CONDATTR_SIZE] c.char,
-}
-
-pthread_mutex_t :: struct {
- sig: c.long,
- _: [PTHREAD_MUTEX_SIZE] c.char,
-}
-
-pthread_mutexattr_t :: struct {
- sig: c.long,
- _: [PTHREAD_MUTEXATTR_SIZE] c.char,
-}
-
-pthread_once_t :: struct {
- sig: c.long,
- _: [PTHREAD_ONCE_SIZE] c.char,
-}
-
-pthread_rwlock_t :: struct {
- sig: c.long,
- _: [PTHREAD_RWLOCK_SIZE] c.char,
-}
-
-pthread_rwlockattr_t :: struct {
- sig: c.long,
- _: [PTHREAD_RWLOCKATTR_SIZE] c.char,
-}
-
-SCHED_OTHER :: 1 // Avoid if you are writing portable software.
-SCHED_FIFO :: 4
-SCHED_RR :: 2 // Round robin.
-
-SCHED_PARAM_SIZE :: 4
-
-sched_param :: struct {
- sched_priority: c.int,
- _: [SCHED_PARAM_SIZE] c.char,
-}
-
-// Source: https://github.com/apple/darwin-libpthread/blob/03c4628c8940cca6fd6a82957f683af804f62e7f/pthread/pthread.h#L138
-PTHREAD_CREATE_JOINABLE :: 1
-PTHREAD_CREATE_DETACHED :: 2
-PTHREAD_INHERIT_SCHED :: 1
-PTHREAD_EXPLICIT_SCHED :: 2
-PTHREAD_PROCESS_SHARED :: 1
-PTHREAD_PROCESS_PRIVATE :: 2
-
-
-PTHREAD_MUTEX_NORMAL :: 0
-PTHREAD_MUTEX_RECURSIVE :: 1
-PTHREAD_MUTEX_ERRORCHECK :: 2
-
-PTHREAD_CANCEL_ENABLE :: 0
-PTHREAD_CANCEL_DISABLE :: 1
-PTHREAD_CANCEL_DEFERRED :: 0
-PTHREAD_CANCEL_ASYNCHRONOUS :: 1
-
-foreign import pthread "system:System.framework"
-
-@(default_calling_convention="c")
-foreign pthread {
- pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
- pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
- pthread_cancel :: proc (thread: pthread_t) -> c.int ---
-}
diff --git a/core/sys/unix/pthread_freebsd.odin b/core/sys/unix/pthread_freebsd.odin
deleted file mode 100644
index 38fe7db55..000000000
--- a/core/sys/unix/pthread_freebsd.odin
+++ /dev/null
@@ -1,122 +0,0 @@
-#+build freebsd
-package unix
-
-import "core:c"
-
-pthread_t :: distinct u64
-// pthread_t :: struct #align(16) { x: u64 }
-
-PTHREAD_COND_T_SIZE :: 8
-
-PTHREAD_MUTEXATTR_T_SIZE :: 8
-PTHREAD_CONDATTR_T_SIZE :: 8
-PTHREAD_RWLOCKATTR_T_SIZE :: 8
-PTHREAD_BARRIERATTR_T_SIZE :: 8
-
-// WARNING: The sizes of these things are different yet again
-// on non-X86!
-when size_of(int) == 8 {
- PTHREAD_ATTR_T_SIZE :: 8
- PTHREAD_MUTEX_T_SIZE :: 8
- PTHREAD_RWLOCK_T_SIZE :: 8
- PTHREAD_BARRIER_T_SIZE :: 8
-} else when size_of(int) == 4 { // TODO
- PTHREAD_ATTR_T_SIZE :: 32
- PTHREAD_MUTEX_T_SIZE :: 32
- PTHREAD_RWLOCK_T_SIZE :: 44
- PTHREAD_BARRIER_T_SIZE :: 20
-}
-
-pthread_cond_t :: struct #align(16) {
- _: [PTHREAD_COND_T_SIZE] c.char,
-}
-pthread_mutex_t :: struct #align(16) {
- _: [PTHREAD_MUTEX_T_SIZE] c.char,
-}
-pthread_rwlock_t :: struct #align(16) {
- _: [PTHREAD_RWLOCK_T_SIZE] c.char,
-}
-pthread_barrier_t :: struct #align(16) {
- _: [PTHREAD_BARRIER_T_SIZE] c.char,
-}
-
-pthread_attr_t :: struct #align(16) {
- _: [PTHREAD_ATTR_T_SIZE] c.char,
-}
-pthread_condattr_t :: struct #align(16) {
- _: [PTHREAD_CONDATTR_T_SIZE] c.char,
-}
-pthread_mutexattr_t :: struct #align(16) {
- _: [PTHREAD_MUTEXATTR_T_SIZE] c.char,
-}
-pthread_rwlockattr_t :: struct #align(16) {
- _: [PTHREAD_RWLOCKATTR_T_SIZE] c.char,
-}
-pthread_barrierattr_t :: struct #align(16) {
- _: [PTHREAD_BARRIERATTR_T_SIZE] c.char,
-}
-
-PTHREAD_MUTEX_ERRORCHECK :: 1
-PTHREAD_MUTEX_RECURSIVE :: 2
-PTHREAD_MUTEX_NORMAL :: 3
-
-
-PTHREAD_CREATE_JOINABLE :: 0
-PTHREAD_CREATE_DETACHED :: 1
-PTHREAD_INHERIT_SCHED :: 4
-PTHREAD_EXPLICIT_SCHED :: 0
-PTHREAD_PROCESS_PRIVATE :: 0
-PTHREAD_PROCESS_SHARED :: 1
-
-SCHED_FIFO :: 1
-SCHED_OTHER :: 2
-SCHED_RR :: 3 // Round robin.
-
-
-sched_param :: struct {
- sched_priority: c.int,
-}
-
-_usem :: struct {
- _has_waiters: u32,
- _count: u32,
- _flags: u32,
-}
-_usem2 :: struct {
- _count: u32,
- _flags: u32,
-}
-sem_t :: struct {
- _magic: u32,
- _kern: _usem2,
- _padding: u32,
-}
-
-PTHREAD_CANCEL_ENABLE :: 0
-PTHREAD_CANCEL_DISABLE :: 1
-PTHREAD_CANCEL_DEFERRED :: 0
-PTHREAD_CANCEL_ASYNCHRONOUS :: 2
-
-foreign import "system:pthread"
-
-@(default_calling_convention="c")
-foreign pthread {
- // create named semaphore.
- // used in process-shared semaphores.
- sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---
-
- sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---
- sem_destroy :: proc(sem: ^sem_t) -> c.int ---
- sem_post :: proc(sem: ^sem_t) -> c.int ---
- sem_wait :: proc(sem: ^sem_t) -> c.int ---
- sem_trywait :: proc(sem: ^sem_t) -> c.int ---
- // sem_timedwait :: proc(sem: ^sem_t, timeout: time.TimeSpec) -> c.int ---
-
- // NOTE: unclear whether pthread_yield is well-supported on Linux systems,
- // see https://linux.die.net/man/3/pthread_yield
- pthread_yield :: proc() ---
-
- pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
- pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
- pthread_cancel :: proc (thread: pthread_t) -> c.int ---
-}
diff --git a/core/sys/unix/pthread_haiku.odin b/core/sys/unix/pthread_haiku.odin
deleted file mode 100644
index 1278f34fe..000000000
--- a/core/sys/unix/pthread_haiku.odin
+++ /dev/null
@@ -1,71 +0,0 @@
-package unix
-
-import "core:c"
-
-pthread_t :: distinct rawptr
-pthread_attr_t :: distinct rawptr
-pthread_mutex_t :: distinct rawptr
-pthread_mutexattr_t :: distinct rawptr
-pthread_cond_t :: distinct rawptr
-pthread_condattr_t :: distinct rawptr
-pthread_rwlock_t :: distinct rawptr
-pthread_rwlockattr_t :: distinct rawptr
-pthread_barrier_t :: distinct rawptr
-pthread_barrierattr_t :: distinct rawptr
-pthread_spinlock_t :: distinct rawptr
-
-pthread_key_t :: distinct c.int
-pthread_once_t :: struct {
- state: c.int,
- mutex: pthread_mutex_t,
-}
-
-PTHREAD_MUTEX_DEFAULT :: 0
-PTHREAD_MUTEX_NORMAL :: 1
-PTHREAD_MUTEX_ERRORCHECK :: 2
-PTHREAD_MUTEX_RECURSIVE :: 3
-
-PTHREAD_DETACHED :: 0x1
-PTHREAD_SCOPE_SYSTEM :: 0x2
-PTHREAD_INHERIT_SCHED :: 0x4
-PTHREAD_NOFLOAT :: 0x8
-
-PTHREAD_CREATE_DETACHED :: PTHREAD_DETACHED
-PTHREAD_CREATE_JOINABLE :: 0
-PTHREAD_SCOPE_PROCESS :: 0
-PTHREAD_EXPLICIT_SCHED :: 0
-
-SCHED_FIFO :: 1
-SCHED_RR :: 2
-SCHED_SPORADIC :: 3
-SCHED_OTHER :: 4
-
-sched_param :: struct {
- sched_priority: c.int,
-}
-
-sem_t :: distinct rawptr
-
-PTHREAD_CANCEL_ENABLE :: 0
-PTHREAD_CANCEL_DISABLE :: 1
-PTHREAD_CANCEL_DEFERRED :: 0
-PTHREAD_CANCEL_ASYNCHRONOUS :: 2
-
-foreign import libc "system:c"
-
-@(default_calling_convention="c")
-foreign libc {
- sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---
-
- sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---
- sem_destroy :: proc(sem: ^sem_t) -> c.int ---
- sem_post :: proc(sem: ^sem_t) -> c.int ---
- sem_wait :: proc(sem: ^sem_t) -> c.int ---
- sem_trywait :: proc(sem: ^sem_t) -> c.int ---
-
- pthread_yield :: proc() ---
-
- pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
- pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
- pthread_cancel :: proc (thread: pthread_t) -> c.int ---
-}
diff --git a/core/sys/unix/pthread_linux.odin b/core/sys/unix/pthread_linux.odin
deleted file mode 100644
index d67add24b..000000000
--- a/core/sys/unix/pthread_linux.odin
+++ /dev/null
@@ -1,124 +0,0 @@
-#+build linux
-package unix
-
-import "core:c"
-
-// TODO(tetra): For robustness, I'd like to mark this with align 16.
-// I cannot currently do this.
-// And at the time of writing there is a bug with putting it
-// as the only field in a struct.
-pthread_t :: distinct u64
-// pthread_t :: struct #align(16) { x: u64 };
-
-// NOTE(tetra): Got all the size constants from pthreadtypes-arch.h on my
-// Linux machine.
-
-PTHREAD_COND_T_SIZE :: 48
-
-PTHREAD_MUTEXATTR_T_SIZE :: 4
-PTHREAD_CONDATTR_T_SIZE :: 4
-PTHREAD_RWLOCKATTR_T_SIZE :: 8
-PTHREAD_BARRIERATTR_T_SIZE :: 4
-
-// WARNING: The sizes of these things are different yet again
-// on non-X86!
-when size_of(int) == 8 {
- PTHREAD_ATTR_T_SIZE :: 56
- PTHREAD_MUTEX_T_SIZE :: 40
- PTHREAD_RWLOCK_T_SIZE :: 56
- PTHREAD_BARRIER_T_SIZE :: 32
-} else when size_of(int) == 4 {
- PTHREAD_ATTR_T_SIZE :: 32
- PTHREAD_MUTEX_T_SIZE :: 32
- PTHREAD_RWLOCK_T_SIZE :: 44
- PTHREAD_BARRIER_T_SIZE :: 20
-}
-
-pthread_cond_t :: struct #align(16) {
- _: [PTHREAD_COND_T_SIZE] c.char,
-}
-pthread_mutex_t :: struct #align(16) {
- _: [PTHREAD_MUTEX_T_SIZE] c.char,
-}
-pthread_rwlock_t :: struct #align(16) {
- _: [PTHREAD_RWLOCK_T_SIZE] c.char,
-}
-pthread_barrier_t :: struct #align(16) {
- _: [PTHREAD_BARRIER_T_SIZE] c.char,
-}
-
-pthread_attr_t :: struct #align(16) {
- _: [PTHREAD_ATTR_T_SIZE] c.char,
-}
-pthread_condattr_t :: struct #align(16) {
- _: [PTHREAD_CONDATTR_T_SIZE] c.char,
-}
-pthread_mutexattr_t :: struct #align(16) {
- _: [PTHREAD_MUTEXATTR_T_SIZE] c.char,
-}
-pthread_rwlockattr_t :: struct #align(16) {
- _: [PTHREAD_RWLOCKATTR_T_SIZE] c.char,
-}
-pthread_barrierattr_t :: struct #align(16) {
- _: [PTHREAD_BARRIERATTR_T_SIZE] c.char,
-}
-
-PTHREAD_MUTEX_NORMAL :: 0
-PTHREAD_MUTEX_RECURSIVE :: 1
-PTHREAD_MUTEX_ERRORCHECK :: 2
-
-
-// TODO(tetra, 2019-11-01): Maybe make `enum c.int`s for these?
-PTHREAD_CREATE_JOINABLE :: 0
-PTHREAD_CREATE_DETACHED :: 1
-PTHREAD_INHERIT_SCHED :: 0
-PTHREAD_EXPLICIT_SCHED :: 1
-PTHREAD_PROCESS_PRIVATE :: 0
-PTHREAD_PROCESS_SHARED :: 1
-
-SCHED_OTHER :: 0
-SCHED_FIFO :: 1
-SCHED_RR :: 2 // Round robin.
-
-sched_param :: struct {
- sched_priority: c.int,
-}
-
-sem_t :: struct #align(16) {
- _: [SEM_T_SIZE] c.char,
-}
-
-when size_of(int) == 8 {
- SEM_T_SIZE :: 32
-} else when size_of(int) == 4 {
- SEM_T_SIZE :: 16
-}
-
-PTHREAD_CANCEL_ENABLE :: 0
-PTHREAD_CANCEL_DISABLE :: 1
-PTHREAD_CANCEL_DEFERRED :: 0
-PTHREAD_CANCEL_ASYNCHRONOUS :: 1
-
-foreign import "system:pthread"
-
-@(default_calling_convention="c")
-foreign pthread {
- // create named semaphore.
- // used in process-shared semaphores.
- sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---
-
- sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---
- sem_destroy :: proc(sem: ^sem_t) -> c.int ---
- sem_post :: proc(sem: ^sem_t) -> c.int ---
- sem_wait :: proc(sem: ^sem_t) -> c.int ---
- sem_trywait :: proc(sem: ^sem_t) -> c.int ---
- // sem_timedwait :: proc(sem: ^sem_t, timeout: time.TimeSpec) -> c.int ---;
-
- // NOTE: unclear whether pthread_yield is well-supported on Linux systems,
- // see https://linux.die.net/man/3/pthread_yield
- pthread_yield :: proc() -> c.int ---
-
- pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
- pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
- pthread_cancel :: proc (thread: pthread_t) -> c.int ---
-}
diff --git a/core/sys/unix/pthread_netbsd.odin b/core/sys/unix/pthread_netbsd.odin
deleted file mode 100644
index 9107f1139..000000000
--- a/core/sys/unix/pthread_netbsd.odin
+++ /dev/null
@@ -1,102 +0,0 @@
-package unix
-
-import "core:c"
-
-pthread_t :: distinct rawptr
-
-SEM_T_SIZE :: 8
-
-PTHREAD_CONDATTR_T_SIZE :: 16
-PTHREAD_MUTEXATTR_T_SIZE :: 16
-PTHREAD_RWLOCKATTR_T_SIZE :: 16
-PTHREAD_BARRIERATTR_T_SIZE :: 16
-
-PTHREAD_COND_T_SIZE :: 40
-PTHREAD_MUTEX_T_SIZE :: 48
-PTHREAD_RWLOCK_T_SIZE :: 64
-PTHREAD_BARRIER_T_SIZE :: 48
-PTHREAD_ATTR_T_SIZE :: 16
-
-pthread_cond_t :: struct #align(8) {
- _: [PTHREAD_COND_T_SIZE] c.char,
-}
-
-pthread_mutex_t :: struct #align(8) {
- _: [PTHREAD_MUTEX_T_SIZE] c.char,
-}
-
-pthread_rwlock_t :: struct #align(8) {
- _: [PTHREAD_RWLOCK_T_SIZE] c.char,
-}
-
-pthread_barrier_t :: struct #align(8) {
- _: [PTHREAD_BARRIER_T_SIZE] c.char,
-}
-
-pthread_attr_t :: struct #align(8) {
- _: [PTHREAD_ATTR_T_SIZE] c.char,
-}
-
-pthread_condattr_t :: struct #align(8) {
- _: [PTHREAD_CONDATTR_T_SIZE] c.char,
-}
-
-pthread_mutexattr_t :: struct #align(8) {
- _: [PTHREAD_MUTEXATTR_T_SIZE] c.char,
-}
-
-pthread_rwlockattr_t :: struct #align(8) {
- _: [PTHREAD_RWLOCKATTR_T_SIZE] c.char,
-}
-
-pthread_barrierattr_t :: struct #align(8) {
- _: [PTHREAD_BARRIERATTR_T_SIZE] c.char,
-}
-
-PTHREAD_MUTEX_NORMAL :: 0
-PTHREAD_MUTEX_ERRORCHECK :: 1
-PTHREAD_MUTEX_RECURSIVE :: 2
-
-PTHREAD_CREATE_JOINABLE :: 0
-PTHREAD_CREATE_DETACHED :: 1
-PTHREAD_INHERIT_SCHED :: 0
-PTHREAD_EXPLICIT_SCHED :: 1
-PTHREAD_PROCESS_PRIVATE :: 0
-PTHREAD_PROCESS_SHARED :: 1
-
-SCHED_NONE :: -1
-SCHED_OTHER :: 0
-SCHED_FIFO :: 1
-SCHED_RR :: 3
-
-sched_param :: struct {
- sched_priority: c.int,
-}
-
-sem_t :: struct #align(16) {
- _: [SEM_T_SIZE] c.char,
-}
-
-PTHREAD_CANCEL_ENABLE :: 0
-PTHREAD_CANCEL_DISABLE :: 1
-PTHREAD_CANCEL_DEFERRED :: 0
-PTHREAD_CANCEL_ASYNCHRONOUS :: 1
-
-foreign import "system:pthread"
-
-@(default_calling_convention="c")
-foreign pthread {
- sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---
-
- sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---
- sem_destroy :: proc(sem: ^sem_t) -> c.int ---
- sem_post :: proc(sem: ^sem_t) -> c.int ---
- sem_wait :: proc(sem: ^sem_t) -> c.int ---
- sem_trywait :: proc(sem: ^sem_t) -> c.int ---
-
- pthread_yield :: proc() ---
-
- pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
- pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
- pthread_cancel :: proc (thread: pthread_t) -> c.int ---
-}
diff --git a/core/sys/unix/pthread_openbsd.odin b/core/sys/unix/pthread_openbsd.odin
deleted file mode 100644
index 2c6d9e598..000000000
--- a/core/sys/unix/pthread_openbsd.odin
+++ /dev/null
@@ -1,74 +0,0 @@
-#+build openbsd
-package unix
-
-import "core:c"
-
-pthread_t :: distinct rawptr
-pthread_attr_t :: distinct rawptr
-pthread_mutex_t :: distinct rawptr
-pthread_mutexattr_t :: distinct rawptr
-pthread_cond_t :: distinct rawptr
-pthread_condattr_t :: distinct rawptr
-pthread_rwlock_t :: distinct rawptr
-pthread_rwlockattr_t :: distinct rawptr
-pthread_barrier_t :: distinct rawptr
-pthread_barrierattr_t :: distinct rawptr
-pthread_spinlock_t :: distinct rawptr
-
-pthread_key_t :: distinct c.int
-pthread_once_t :: struct {
- state: c.int,
- mutex: pthread_mutex_t,
-}
-
-PTHREAD_MUTEX_ERRORCHECK :: 1
-PTHREAD_MUTEX_RECURSIVE :: 2
-PTHREAD_MUTEX_NORMAL :: 3
-PTHREAD_MUTEX_STRICT_NP :: 4
-
-PTHREAD_DETACHED :: 0x1
-PTHREAD_SCOPE_SYSTEM :: 0x2
-PTHREAD_INHERIT_SCHED :: 0x4
-PTHREAD_NOFLOAT :: 0x8
-
-PTHREAD_CREATE_DETACHED :: PTHREAD_DETACHED
-PTHREAD_CREATE_JOINABLE :: 0
-PTHREAD_SCOPE_PROCESS :: 0
-PTHREAD_EXPLICIT_SCHED :: 0
-
-SCHED_FIFO :: 1
-SCHED_OTHER :: 2
-SCHED_RR :: 3
-
-sched_param :: struct {
- sched_priority: c.int,
-}
-
-sem_t :: distinct rawptr
-
-PTHREAD_CANCEL_ENABLE :: 0
-PTHREAD_CANCEL_DISABLE :: 1
-PTHREAD_CANCEL_DEFERRED :: 0
-PTHREAD_CANCEL_ASYNCHRONOUS :: 2
-
-foreign import libc "system:c"
-
-@(default_calling_convention="c")
-foreign libc {
- sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---
-
- sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---
- sem_destroy :: proc(sem: ^sem_t) -> c.int ---
- sem_post :: proc(sem: ^sem_t) -> c.int ---
- sem_wait :: proc(sem: ^sem_t) -> c.int ---
- sem_trywait :: proc(sem: ^sem_t) -> c.int ---
- //sem_timedwait :: proc(sem: ^sem_t, timeout: time.TimeSpec) -> c.int ---
-
- // NOTE: unclear whether pthread_yield is well-supported on Linux systems,
- // see https://linux.die.net/man/3/pthread_yield
- pthread_yield :: proc() ---
-
- pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
- pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
- pthread_cancel :: proc (thread: pthread_t) -> c.int ---
-}
diff --git a/core/sys/unix/pthread_unix.odin b/core/sys/unix/pthread_unix.odin
deleted file mode 100644
index 43c4866ed..000000000
--- a/core/sys/unix/pthread_unix.odin
+++ /dev/null
@@ -1,127 +0,0 @@
-#+build linux, darwin, freebsd, openbsd, netbsd, haiku
-package unix
-
-foreign import "system:pthread"
-
-import "core:c"
-
-timespec :: struct {
- tv_sec: i64,
- tv_nsec: i64,
-}
-
-//
-// On success, these functions return 0.
-//
-
-@(default_calling_convention="c")
-foreign pthread {
- pthread_create :: proc(t: ^pthread_t, attrs: ^pthread_attr_t, routine: proc(data: rawptr) -> rawptr, arg: rawptr) -> c.int ---
-
- // retval is a pointer to a location to put the return value of the thread proc.
- pthread_join :: proc(t: pthread_t, retval: ^rawptr) -> c.int ---
-
- pthread_kill :: proc(t: pthread_t, sig: c.int) -> c.int ---
-
- pthread_self :: proc() -> pthread_t ---
-
- pthread_equal :: proc(a, b: pthread_t) -> b32 ---
-
- pthread_detach :: proc(t: pthread_t) -> c.int ---
-
- sched_get_priority_min :: proc(policy: c.int) -> c.int ---
- sched_get_priority_max :: proc(policy: c.int) -> c.int ---
-
- // NOTE: POSIX says this can fail with OOM.
- pthread_attr_init :: proc(attrs: ^pthread_attr_t) -> c.int ---
-
- pthread_attr_destroy :: proc(attrs: ^pthread_attr_t) -> c.int ---
-
- pthread_attr_getschedparam :: proc(attrs: ^pthread_attr_t, param: ^sched_param) -> c.int ---
- pthread_attr_setschedparam :: proc(attrs: ^pthread_attr_t, param: ^sched_param) -> c.int ---
-
- // states: PTHREAD_CREATE_DETACHED, PTHREAD_CREATE_JOINABLE
- pthread_attr_setdetachstate :: proc(attrs: ^pthread_attr_t, detach_state: c.int) -> c.int ---
-
- // NOTE(tetra, 2019-11-06): WARNING: Different systems have different alignment requirements.
- // For maximum usefulness, use the OS's page size.
- // ALSO VERY MAJOR WARNING: `stack_ptr` must be the LAST byte of the stack on systems
- // where the stack grows downwards, which is the common case, so far as I know.
- // On systems where it grows upwards, give the FIRST byte instead.
- // ALSO SLIGHTLY LESS MAJOR WARNING: Using this procedure DISABLES automatically-provided
- // guard pages. If you are using this procedure, YOU must set them up manually.
- // If you forget to do this, you WILL get stack corruption bugs if you do not EXTREMELY
- // know what you are doing!
- pthread_attr_setstack :: proc(attrs: ^pthread_attr_t, stack_ptr: rawptr, stack_size: u64) -> c.int ---
- pthread_attr_getstack :: proc(attrs: ^pthread_attr_t, stack_ptr: ^rawptr, stack_size: ^u64) -> c.int ---
-
- pthread_sigmask :: proc(how: c.int, set: rawptr, oldset: rawptr) -> c.int ---
-
- sched_yield :: proc() -> c.int ---
-}
-
-// NOTE: Unimplemented in Haiku.
-when ODIN_OS != .Haiku {
- foreign pthread {
- // scheds: PTHREAD_INHERIT_SCHED, PTHREAD_EXPLICIT_SCHED
- pthread_attr_setinheritsched :: proc(attrs: ^pthread_attr_t, sched: c.int) -> c.int ---
-
- pthread_attr_getschedpolicy :: proc(t: ^pthread_attr_t, policy: ^c.int) -> c.int ---
- pthread_attr_setschedpolicy :: proc(t: ^pthread_attr_t, policy: c.int) -> c.int ---
- }
-}
-
-@(default_calling_convention="c")
-foreign pthread {
- // NOTE: POSIX says this can fail with OOM.
- pthread_cond_init :: proc(cond: ^pthread_cond_t, attrs: ^pthread_condattr_t) -> c.int ---
-
- pthread_cond_destroy :: proc(cond: ^pthread_cond_t) -> c.int ---
-
- pthread_cond_signal :: proc(cond: ^pthread_cond_t) -> c.int ---
-
- // same as signal, but wakes up _all_ threads that are waiting
- pthread_cond_broadcast :: proc(cond: ^pthread_cond_t) -> c.int ---
-
-
- // assumes the mutex is pre-locked
- pthread_cond_wait :: proc(cond: ^pthread_cond_t, mutex: ^pthread_mutex_t) -> c.int ---
- pthread_cond_timedwait :: proc(cond: ^pthread_cond_t, mutex: ^pthread_mutex_t, timeout: ^timespec) -> c.int ---
-
- pthread_condattr_init :: proc(attrs: ^pthread_condattr_t) -> c.int ---
- pthread_condattr_destroy :: proc(attrs: ^pthread_condattr_t) -> c.int ---
-
- // p-shared = "process-shared" - i.e: is this condition shared among multiple processes?
- // values: PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED
- pthread_condattr_setpshared :: proc(attrs: ^pthread_condattr_t, value: c.int) -> c.int ---
- pthread_condattr_getpshared :: proc(attrs: ^pthread_condattr_t, result: ^c.int) -> c.int ---
-
-}
-
-@(default_calling_convention="c")
-foreign pthread {
- // NOTE: POSIX says this can fail with OOM.
- pthread_mutex_init :: proc(mutex: ^pthread_mutex_t, attrs: ^pthread_mutexattr_t) -> c.int ---
-
- pthread_mutex_destroy :: proc(mutex: ^pthread_mutex_t) -> c.int ---
-
- pthread_mutex_trylock :: proc(mutex: ^pthread_mutex_t) -> c.int ---
-
- pthread_mutex_lock :: proc(mutex: ^pthread_mutex_t) -> c.int ---
-
- pthread_mutex_timedlock :: proc(mutex: ^pthread_mutex_t, timeout: ^timespec) -> c.int ---
-
- pthread_mutex_unlock :: proc(mutex: ^pthread_mutex_t) -> c.int ---
-
-
- pthread_mutexattr_init :: proc(attrs: ^pthread_mutexattr_t) -> c.int ---
- pthread_mutexattr_destroy :: proc(attrs: ^pthread_mutexattr_t) -> c.int ---
- pthread_mutexattr_settype :: proc(attrs: ^pthread_mutexattr_t, type: c.int) -> c.int ---
-
- // p-shared = "process-shared" - i.e: is this mutex shared among multiple processes?
- // values: PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED
- pthread_mutexattr_setpshared :: proc(attrs: ^pthread_mutexattr_t, value: c.int) -> c.int ---
- pthread_mutexattr_getpshared :: proc(attrs: ^pthread_mutexattr_t, result: ^c.int) -> c.int ---
-
- pthread_testcancel :: proc () ---
-}
diff --git a/core/sys/unix/unix.odin b/core/sys/unix/unix.odin
new file mode 100644
index 000000000..e9f58e554
--- /dev/null
+++ b/core/sys/unix/unix.odin
@@ -0,0 +1,8 @@
+package unix
+
+import "core:c"
+
+timespec :: struct {
+ secs: i64,
+ nsecs: c.long,
+}
diff --git a/core/sys/wasm/js/dom.odin b/core/sys/wasm/js/dom.odin
index ffc58a9a3..902dfc941 100644
--- a/core/sys/wasm/js/dom.odin
+++ b/core/sys/wasm/js/dom.odin
@@ -20,6 +20,8 @@ foreign dom_lib {
device_pixel_ratio :: proc() -> f64 ---
window_set_scroll :: proc(x, y: f64) ---
+
+ set_element_style :: proc(id: string, key: string, value: string) ---
}
get_element_value_string :: proc "contextless" (id: string, buf: []byte) -> string {
diff --git a/core/sys/wasm/js/events.odin b/core/sys/wasm/js/events.odin
index 905b3eba9..ffa3a1202 100644
--- a/core/sys/wasm/js/events.odin
+++ b/core/sys/wasm/js/events.odin
@@ -186,8 +186,8 @@ Key_Location :: enum u8 {
Numpad = 3,
}
-KEYBOARD_MAX_KEY_SIZE :: 16
-KEYBOARD_MAX_CODE_SIZE :: 16
+KEYBOARD_MAX_KEY_SIZE :: 32
+KEYBOARD_MAX_CODE_SIZE :: 32
GAMEPAD_MAX_ID_SIZE :: 64
GAMEPAD_MAX_MAPPING_SIZE :: 64
diff --git a/core/sys/wasm/js/odin.js b/core/sys/wasm/js/odin.js
index bf002da74..07a77952c 100644
--- a/core/sys/wasm/js/odin.js
+++ b/core/sys/wasm/js/odin.js
@@ -1259,13 +1259,26 @@ class WebGLInterface {
};
-function odinSetupDefaultImports(wasmMemoryInterface, consoleElement, memory, eventQueue, event_temp) {
+function odinSetupDefaultImports(wasmMemoryInterface, consoleElement, memory) {
const MAX_INFO_CONSOLE_LINES = 512;
let infoConsoleLines = new Array();
let currentLine = {};
currentLine[false] = "";
currentLine[true] = "";
let prevIsError = false;
+
+ let event_temp = {};
+
+ const onEventReceived = (event_data, data, callback) => {
+ event_temp.data = event_data;
+
+ const exports = wasmMemoryInterface.exports;
+ const odin_ctx = exports.default_context_ptr();
+
+ exports.odin_dom_do_event_callback(data, callback, odin_ctx);
+
+ event_temp.data = null;
+ };
const writeToConsole = (line, isError) => {
if (!line) {
@@ -1535,8 +1548,8 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement, memory, ev
wmi.storeInt(off(W, W), e.key.length)
wmi.storeInt(off(W, W), e.code.length)
- wmi.storeString(off(16, 1), e.key);
- wmi.storeString(off(16, 1), e.code);
+ wmi.storeString(off(32, 1), e.key);
+ wmi.storeString(off(32, 1), e.code);
} else if (e.type === 'scroll') {
wmi.storeF64(off(8, 8), window.scrollX);
wmi.storeF64(off(8, 8), window.scrollY);
@@ -1594,7 +1607,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement, memory, ev
event_data.event = e;
event_data.name_code = name_code;
- eventQueue.push({event_data: event_data, data: data, callback: callback});
+ onEventReceived(event_data, data, callback);
};
wasmMemoryInterface.listenerMap[{data: data, callback: callback}] = listener;
element.addEventListener(name, listener, !!use_capture);
@@ -1611,7 +1624,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement, memory, ev
event_data.event = e;
event_data.name_code = name_code;
- eventQueue.push({event_data: event_data, data: data, callback: callback});
+ onEventReceived(event_data, data, callback);
};
wasmMemoryInterface.listenerMap[{data: data, callback: callback}] = listener;
element.addEventListener(name, listener, !!use_capture);
@@ -1802,6 +1815,16 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement, memory, ev
}
},
+ set_element_style: (id_ptr, id_len, key_ptr, key_len, value_ptr, value_len) => {
+ let id = wasmMemoryInterface.loadString(id_ptr, id_len);
+ let key = wasmMemoryInterface.loadString(key_ptr, key_len);
+ let value = wasmMemoryInterface.loadString(value_ptr, value_len);
+ let element = getElement(id);
+ if (element) {
+ element.style[key] = value;
+ }
+ },
+
get_element_key_f64: (id_ptr, id_len, key_ptr, key_len) => {
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
let key = wasmMemoryInterface.loadString(key_ptr, key_len);
@@ -1905,10 +1928,7 @@ async function runWasm(wasmPath, consoleElement, extraForeignImports, wasmMemory
}
wasmMemoryInterface.setIntSize(intSize);
- let eventQueue = new Array();
- let event_temp = {};
-
- let imports = odinSetupDefaultImports(wasmMemoryInterface, consoleElement, wasmMemoryInterface.memory, eventQueue, event_temp);
+ let imports = odinSetupDefaultImports(wasmMemoryInterface, consoleElement, wasmMemoryInterface.memory);
let exports = {};
if (extraForeignImports !== undefined) {
@@ -1933,7 +1953,7 @@ async function runWasm(wasmPath, consoleElement, extraForeignImports, wasmMemory
exports._start();
- // Define a `@export step :: proc(current_type: f64) -> (keep_going: bool) {`
+ // Define a `@export step :: proc(delta_time: f64) -> (keep_going: bool) {`
// in your app and it will get called every frame.
// return `false` to stop the execution of the module.
if (exports.step) {
@@ -1948,14 +1968,7 @@ async function runWasm(wasmPath, consoleElement, extraForeignImports, wasmMemory
const dt = (currTimeStamp - prevTimeStamp)*0.001;
prevTimeStamp = currTimeStamp;
- while (eventQueue.length > 0) {
- let e = eventQueue.shift()
- event_temp.data = e.event_data;
- exports.odin_dom_do_event_callback(e.data, e.callback, odin_ctx);
- }
- event_temp.data = null;
-
- if (!exports.step(currTimeStamp*0.001, odin_ctx)) {
+ if (!exports.step(dt, odin_ctx)) {
exports._end();
return;
}
diff --git a/core/sys/windows/icu.odin b/core/sys/windows/icu.odin
new file mode 100644
index 000000000..6ed8c9b40
--- /dev/null
+++ b/core/sys/windows/icu.odin
@@ -0,0 +1,14 @@
+#+build windows
+package sys_windows
+
+foreign import "system:icu.lib"
+
+UError :: enum i32 {
+ U_ZERO_ERROR = 0,
+}
+
+@(default_calling_convention="system")
+foreign icu {
+ ucal_getWindowsTimeZoneID :: proc(id: wstring, len: i32, winid: wstring, winidCapacity: i32, status: ^UError) -> i32 ---
+ ucal_getDefaultTimeZone :: proc(result: wstring, cap: i32, status: ^UError) -> i32 ---
+}
diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin
index 2771581e6..8be50bceb 100644
--- a/core/sys/windows/kernel32.odin
+++ b/core/sys/windows/kernel32.odin
@@ -381,6 +381,14 @@ foreign kernel32 {
nDefaultTimeOut: DWORD,
lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
) -> HANDLE ---
+ PeekNamedPipe :: proc(
+ hNamedPipe: HANDLE,
+ lpBuffer: rawptr,
+ nBufferSize: u32,
+ lpBytesRead: ^u32,
+ lpTotalBytesAvail: ^u32,
+ lpBytesLeftThisMessage: ^u32,
+ ) -> BOOL ---
CancelIo :: proc(handle: HANDLE) -> BOOL ---
GetOverlappedResult :: proc(
hFile: HANDLE,
diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin
index 934d103e5..e1ace4133 100644
--- a/core/sys/windows/types.odin
+++ b/core/sys/windows/types.odin
@@ -253,8 +253,6 @@ FILE_GENERIC_WRITE: DWORD : STANDARD_RIGHTS_WRITE |
FILE_APPEND_DATA |
SYNCHRONIZE
-FILE_FLAG_OPEN_REPARSE_POINT: DWORD : 0x00200000
-FILE_FLAG_BACKUP_SEMANTICS: DWORD : 0x02000000
SECURITY_SQOS_PRESENT: DWORD : 0x00100000
FIONBIO: c_ulong : 0x8004667e
@@ -2222,11 +2220,22 @@ WAIT_OBJECT_0: DWORD : 0x00000000
WAIT_TIMEOUT: DWORD : 258
WAIT_FAILED: DWORD : 0xFFFFFFFF
+FILE_FLAG_WRITE_THROUGH: DWORD : 0x80000000
+FILE_FLAG_OVERLAPPED: DWORD : 0x40000000
+FILE_FLAG_NO_BUFFERING: DWORD : 0x20000000
+FILE_FLAG_RANDOM_ACCESS: DWORD : 0x10000000
+FILE_FLAG_SEQUENTIAL_SCAN: DWORD : 0x08000000
+FILE_FLAG_DELETE_ON_CLOSE: DWORD : 0x04000000
+FILE_FLAG_BACKUP_SEMANTICS: DWORD : 0x02000000
+FILE_FLAG_POSIX_SEMANTICS: DWORD : 0x01000000
+FILE_FLAG_SESSION_AWARE: DWORD : 0x00800000
+FILE_FLAG_OPEN_REPARSE_POINT: DWORD : 0x00200000
+FILE_FLAG_OPEN_NO_RECALL: DWORD : 0x00100000
+FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD : 0x00080000
+
PIPE_ACCESS_INBOUND: DWORD : 0x00000001
PIPE_ACCESS_OUTBOUND: DWORD : 0x00000002
PIPE_ACCESS_DUPLEX: DWORD : 0x00000003
-FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD : 0x00080000
-FILE_FLAG_OVERLAPPED: DWORD : 0x40000000
PIPE_WAIT: DWORD : 0x00000000
PIPE_TYPE_BYTE: DWORD : 0x00000000
PIPE_TYPE_MESSAGE: DWORD : 0x00000004
diff --git a/core/sys/windows/user32.odin b/core/sys/windows/user32.odin
index 514592e7b..4ae33cd32 100644
--- a/core/sys/windows/user32.odin
+++ b/core/sys/windows/user32.odin
@@ -781,3 +781,64 @@ CF_GDIOBJLAST :: 0x03FF
CF_OWNERDISPLAY :: 0x0080
CF_PRIVATEFIRST :: 0x0200
CF_PRIVATELAST :: 0x02FF
+
+STICKYKEYS :: struct {
+ cbSize: UINT,
+ dwFlags: DWORD,
+}
+LPSTICKYKEYS :: ^STICKYKEYS
+
+SKF_STICKYKEYSON :: 0x1
+SKF_AVAILABLE :: 0x2
+SKF_HOTKEYACTIVE :: 0x4
+SKF_CONFIRMHOTKEY :: 0x8
+SKF_HOTKEYSOUND :: 0x10
+SKF_INDICATOR :: 0x20
+SKF_AUDIBLEFEEDBACK :: 0x40
+SKF_TRISTATE :: 0x80
+SKF_TWOKEYSOFF :: 0x100
+SKF_LSHIFTLOCKED :: 0x10000
+SKF_RSHIFTLOCKED :: 0x20000
+SKF_LCTLLOCKED :: 0x40000
+SKF_RCTLLOCKED :: 0x80000
+SKF_LALTLOCKED :: 0x100000
+SKF_RALTLOCKED :: 0x200000
+SKF_LWINLOCKED :: 0x400000
+SKF_RWINLOCKED :: 0x800000
+SKF_LSHIFTLATCHED :: 0x1000000
+SKF_RSHIFTLATCHED :: 0x2000000
+SKF_LCTLLATCHED :: 0x4000000
+SKF_RCTLLATCHED :: 0x8000000
+SKF_LALTLATCHED :: 0x10000000
+SKF_RALTLATCHED :: 0x20000000
+
+TOGGLEKEYS :: struct {
+ cbSize: UINT,
+ dwFlags: DWORD,
+}
+LPTOGGLEKEYS :: ^TOGGLEKEYS
+
+TKF_TOGGLEKEYSON :: 0x1
+TKF_AVAILABLE :: 0x2
+TKF_HOTKEYACTIVE :: 0x4
+TKF_CONFIRMHOTKEY :: 0x8
+TKF_HOTKEYSOUND :: 0x10
+TKF_INDICATOR :: 0x20
+
+FILTERKEYS :: struct {
+ cbSize: UINT,
+ dwFlags: DWORD,
+ iWaitMSec: DWORD,
+ iDelayMSec: DWORD,
+ iRepeatMSec: DWORD,
+ iBounceMSec: DWORD,
+}
+LPFILTERKEYS :: ^FILTERKEYS
+
+FKF_FILTERKEYSON :: 0x1
+FKF_AVAILABLE :: 0x2
+FKF_HOTKEYACTIVE :: 0x4
+FKF_CONFIRMHOTKEY :: 0x8
+FKF_HOTKEYSOUND :: 0x10
+FKF_INDICATOR :: 0x20
+FKF_CLICKON :: 0x40
diff --git a/core/sys/windows/ux_theme.odin b/core/sys/windows/ux_theme.odin
index 527abd62f..392cf1e18 100644
--- a/core/sys/windows/ux_theme.odin
+++ b/core/sys/windows/ux_theme.odin
@@ -3,7 +3,7 @@ package sys_windows
foreign import uxtheme "system:UxTheme.lib"
-MARGINS :: distinct [4]int
+MARGINS :: distinct [4]i32
PMARGINS :: ^MARGINS
@(default_calling_convention="system")
diff --git a/core/sys/windows/winerror.odin b/core/sys/windows/winerror.odin
index b3b470619..61a7d9d86 100644
--- a/core/sys/windows/winerror.odin
+++ b/core/sys/windows/winerror.odin
@@ -251,26 +251,26 @@ SEVERITY :: enum DWORD {
// Generic test for success on any status value (non-negative numbers indicate success).
SUCCEEDED :: #force_inline proc "contextless" (#any_int result: int) -> bool { return result >= S_OK }
// and the inverse
-FAILED :: #force_inline proc(#any_int result: int) -> bool { return result < S_OK }
+FAILED :: #force_inline proc "contextless" (#any_int result: int) -> bool { return result < S_OK }
// Generic test for error on any status value.
-IS_ERROR :: #force_inline proc(#any_int status: int) -> bool { return u32(status) >> 31 == u32(SEVERITY.ERROR) }
+IS_ERROR :: #force_inline proc "contextless" (#any_int status: int) -> bool { return u32(status) >> 31 == u32(SEVERITY.ERROR) }
// Return the code
-HRESULT_CODE :: #force_inline proc(#any_int hr: int) -> int { return int(u32(hr) & 0xFFFF) }
+HRESULT_CODE :: #force_inline proc "contextless" (#any_int hr: int) -> int { return int(u32(hr) & 0xFFFF) }
// Return the facility
-HRESULT_FACILITY :: #force_inline proc(#any_int hr: int) -> FACILITY { return FACILITY((u32(hr) >> 16) & 0x1FFF) }
+HRESULT_FACILITY :: #force_inline proc "contextless" (#any_int hr: int) -> FACILITY { return FACILITY((u32(hr) >> 16) & 0x1FFF) }
// Return the severity
-HRESULT_SEVERITY :: #force_inline proc(#any_int hr: int) -> SEVERITY { return SEVERITY((u32(hr) >> 31) & 0x1) }
+HRESULT_SEVERITY :: #force_inline proc "contextless" (#any_int hr: int) -> SEVERITY { return SEVERITY((u32(hr) >> 31) & 0x1) }
// Create an HRESULT value from component pieces
-MAKE_HRESULT :: #force_inline proc(#any_int sev: int, #any_int fac: int, #any_int code: int) -> HRESULT {
+MAKE_HRESULT :: #force_inline proc "contextless" (#any_int sev: int, #any_int fac: int, #any_int code: int) -> HRESULT {
return HRESULT((uint(sev)<<31) | (uint(fac)<<16) | (uint(code)))
}
-DECODE_HRESULT :: #force_inline proc(#any_int hr: int) -> (SEVERITY, FACILITY, int) {
+DECODE_HRESULT :: #force_inline proc "contextless" (#any_int hr: int) -> (SEVERITY, FACILITY, int) {
return HRESULT_SEVERITY(hr), HRESULT_FACILITY(hr), HRESULT_CODE(hr)
}