update to master

This commit is contained in:
Colin Davidson
2024-11-20 15:51:08 -08:00
276 changed files with 15801 additions and 4509 deletions
@@ -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")
+500 -14
View File
@@ -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 {
+46 -1
View File
@@ -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)
+16
View File
@@ -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
View File
@@ -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
*/
+25
View File
@@ -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
View File
@@ -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
+23
View File
@@ -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
View File
@@ -1,3 +1,4 @@
#+build darwin, linux, freebsd, openbsd, netbsd
package posix
import "core:c"
+56 -31
View File
@@ -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 */
}
}
+10 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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. */
}
}
+9 -2
View File
@@ -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
}
+32 -4
View File
@@ -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
}
+2 -3
View File
@@ -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
View File
@@ -1,3 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
+87 -2
View File
@@ -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")
+8
View File
@@ -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"
}
+96 -2
View File
@@ -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
}
+6 -88
View File
@@ -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
View File
@@ -1,3 +1,4 @@
#+build linux, darwin, netbsd, openbsd, freebsd
package posix
import "core:c"
+2 -3
View File
@@ -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")
}
+36 -3
View File
@@ -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")
}
+62 -29
View File
@@ -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")
}
+2 -3
View File
@@ -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")
}
+21 -3
View File
@@ -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
}
+6 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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. */
}
}
+2 -3
View File
@@ -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 -5
View File
@@ -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"
+11
View File
@@ -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
View File
@@ -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
}
+145
View File
@@ -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
View File
@@ -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/"
}
+207
View File
@@ -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 -78
View File
@@ -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"
+101
View File
@@ -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 -14
View File
@@ -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())
}
+30
View File
@@ -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())
}
+27 -2
View File
@@ -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
}
+17 -13
View File
@@ -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
View File
@@ -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,
}
}
+12 -6
View File
@@ -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
}
}
+3 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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,
}
}
}
+24 -2
View File
@@ -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
}
+2 -3
View File
@@ -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")
}
+2 -3
View File
@@ -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")
}
+2 -3
View File
@@ -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")
}
+8 -2
View File
@@ -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 */
}
}
+14 -2
View File
@@ -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"`,
}
}
+70 -5
View File
@@ -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
}
}
+8 -9
View File
@@ -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")
}
+13 -2
View File
@@ -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
}
}
+2 -3
View File
@@ -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
View File
@@ -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
}
+153
View File
@@ -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)
}
+2 -3
View File
@@ -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")
}
+22 -2
View File
@@ -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
}
-96
View File
@@ -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 ---
}
-122
View File
@@ -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 ---
}
-71
View File
@@ -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 ---
}
-124
View File
@@ -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 ---
}
-102
View File
@@ -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 ---
}
-74
View File
@@ -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 ---
}
-127
View File
@@ -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 () ---
}
+8
View File
@@ -0,0 +1,8 @@
package unix
import "core:c"
timespec :: struct {
secs: i64,
nsecs: c.long,
}
+2
View File
@@ -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 {
+2 -2
View File
@@ -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
View File
@@ -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;
}
+14
View File
@@ -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 ---
}
+8
View File
@@ -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,
+13 -4
View File
@@ -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
+61
View File
@@ -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
+1 -1
View File
@@ -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")
+7 -7
View File
@@ -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)
}