mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-20 16:36:46 +00:00
update to master
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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 ---
|
||||
|
||||
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 ---
|
||||
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,
|
||||
|
||||
Lifo = Fifo | Reversed,
|
||||
}
|
||||
|
||||
mach_vm_trunc_page :: proc(v: u64) -> u64 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
+66
-59
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
+22
-3
@@ -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)
|
||||
}
|
||||
|
||||
// TODO(flysand): inotify_rm_watch
|
||||
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)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -30,6 +30,11 @@ Id :: distinct uint
|
||||
*/
|
||||
Fd :: distinct i32
|
||||
|
||||
/*
|
||||
Represents a watch descriptor.
|
||||
*/
|
||||
Wd :: distinct i32
|
||||
|
||||
/*
|
||||
Type for PID file descriptors.
|
||||
*/
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#+build darwin, linux, freebsd, openbsd, netbsd
|
||||
package posix
|
||||
|
||||
import "core:c"
|
||||
|
||||
+56
-31
@@ -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 ]]
|
||||
*/
|
||||
@@ -53,15 +54,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.
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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{}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+175
-8
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+107
-45
@@ -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. */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||
package posix
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||
package posix
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
when ODIN_OS == .Linux {
|
||||
|
||||
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 */
|
||||
}
|
||||
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")
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
+102
-9
@@ -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,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+13
-2
@@ -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. */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
+175
-123
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
+8
-165
@@ -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"
|
||||
@@ -32,16 +32,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.
|
||||
|
||||
@@ -115,34 +105,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.
|
||||
|
||||
@@ -181,60 +143,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.
|
||||
|
||||
@@ -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/"
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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,
|
||||
@@ -342,21 +292,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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||
package posix
|
||||
|
||||
import "core:c"
|
||||
@@ -13,16 +14,6 @@ when ODIN_OS == .Darwin {
|
||||
// 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 ---
|
||||
|
||||
/*
|
||||
Map the error number to a locale-dependent error message string and put it in the buffer.
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
+33
-20
@@ -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,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
+39
-14
@@ -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 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+31
-16
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
+149
-72
@@ -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_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_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 */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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: socklen_t, /* [PSX] data byte count, including cmsghdr */
|
||||
cmsg_level: c.int, /* [PSX] originating protocol */
|
||||
cmsg_type: c.int, /* [PSX] protocol-specific type */
|
||||
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,
|
||||
}
|
||||
|
||||
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
|
||||
when ODIN_OS == .Linux {
|
||||
SOL_SOCKET :: 1
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
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 == .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
|
||||
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")
|
||||
}
|
||||
|
||||
|
||||
+120
-67
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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"`,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
+245
-167
@@ -1,3 +1,4 @@
|
||||
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||
package posix
|
||||
|
||||
import "core:c"
|
||||
@@ -11,19 +12,6 @@ when ODIN_OS == .Darwin {
|
||||
// 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 ]]
|
||||
*/
|
||||
access :: proc(path: cstring, amode: Mode_Flags = F_OK) -> result ---
|
||||
|
||||
/*
|
||||
Equivalent to `access` but relative paths are resolved based on `fd`.
|
||||
|
||||
@@ -42,18 +30,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.
|
||||
|
||||
@@ -204,15 +180,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.
|
||||
@@ -392,44 +359,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.
|
||||
|
||||
@@ -829,13 +758,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.
|
||||
|
||||
@@ -912,13 +834,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.
|
||||
|
||||
@@ -958,13 +873,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.
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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 ---
|
||||
}
|
||||
@@ -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 ---
|
||||
}
|
||||
@@ -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 ---
|
||||
}
|
||||
@@ -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 ---
|
||||
}
|
||||
@@ -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 ---
|
||||
}
|
||||
@@ -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 ---
|
||||
}
|
||||
@@ -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 () ---
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package unix
|
||||
|
||||
import "core:c"
|
||||
|
||||
timespec :: struct {
|
||||
secs: i64,
|
||||
nsecs: c.long,
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
+31
-18
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 ---
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user