mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-29 10:50:05 +00:00
os2: process API for Darwin and most of it for BSDs
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
//+build darwin, netbsd, openbsd, freebsd
|
||||
package kqueue
|
||||
|
||||
when ODIN_OS == .Darwin {
|
||||
foreign import lib "system:System.framework"
|
||||
} else {
|
||||
foreign import lib "system:c"
|
||||
}
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
import "core:c"
|
||||
import "core:sys/posix"
|
||||
|
||||
KQ :: posix.FD
|
||||
|
||||
kqueue :: proc() -> (kq: KQ, err: posix.Errno) {
|
||||
kq = _kqueue()
|
||||
if kq == -1 {
|
||||
err = posix.errno()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
kevent :: proc(kq: KQ, change_list: []KEvent, event_list: []KEvent, timeout: ^posix.timespec) -> (n_events: c.int, err: posix.Errno) {
|
||||
n_events = _kevent(
|
||||
kq,
|
||||
raw_data(change_list),
|
||||
c.int(len(change_list)),
|
||||
raw_data(event_list),
|
||||
c.int(len(event_list)),
|
||||
timeout,
|
||||
)
|
||||
if n_events == -1 {
|
||||
err = posix.errno()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
Flag :: enum _Flags_Backing {
|
||||
Add = log2(0x0001), // Add event to kq (implies .Enable).
|
||||
Delete = log2(0x0002), // Delete event from kq.
|
||||
Enable = log2(0x0004), // Enable event.
|
||||
Disable = log2(0x0008), // Disable event (not reported).
|
||||
One_Shot = log2(0x0010), // Only report one occurrence.
|
||||
Clear = log2(0x0020), // Clear event state after reporting.
|
||||
Receipt = log2(0x0040), // Force immediate event output.
|
||||
Dispatch = log2(0x0080), // Disable event after reporting.
|
||||
|
||||
Error = log2(0x4000), // Error, data contains errno.
|
||||
EOF = log2(0x8000), // EOF detected.
|
||||
}
|
||||
Flags :: bit_set[Flag; _Flags_Backing]
|
||||
|
||||
Filter :: enum _Filter_Backing {
|
||||
Read = _FILTER_READ, // Check for read availability on the file descriptor.
|
||||
Write = _FILTER_WRITE, // Check for write availability on the file descriptor.
|
||||
AIO = _FILTER_AIO, // Attached to AIO requests.
|
||||
VNode = _FILTER_VNODE, // Check for changes to the subject file.
|
||||
Proc = _FILTER_PROC, // Check for changes to the subject process.
|
||||
Signal = _FILTER_SIGNAL, // Check for signals delivered to the process.
|
||||
Timer = _FILTER_TIMER, // Timers.
|
||||
}
|
||||
|
||||
RW_Flag :: enum u32 {
|
||||
Low_Water_Mark = log2(0x00000001),
|
||||
}
|
||||
RW_Flags :: bit_set[RW_Flag; u32]
|
||||
|
||||
VNode_Flag :: enum u32 {
|
||||
Delete = log2(0x00000001), // Deleted.
|
||||
Write = log2(0x00000002), // Contents changed.
|
||||
Extend = log2(0x00000004), // Size increased.
|
||||
Attrib = log2(0x00000008), // Attributes changed.
|
||||
Link = log2(0x00000010), // Link count changed.
|
||||
Rename = log2(0x00000020), // Renamed.
|
||||
Revoke = log2(0x00000040), // Access was revoked.
|
||||
}
|
||||
VNode_Flags :: bit_set[VNode_Flag; u32]
|
||||
|
||||
Proc_Flag :: enum u32 {
|
||||
Exit = log2(0x80000000), // Process exited.
|
||||
Fork = log2(0x40000000), // Process forked.
|
||||
Exec = log2(0x20000000), // Process exec'd.
|
||||
Signal = log2(0x08000000), // Shared with `Filter.Signal`.
|
||||
}
|
||||
Proc_Flags :: bit_set[Proc_Flag; u32]
|
||||
|
||||
Timer_Flag :: enum u32 {
|
||||
Seconds = log2(0x00000001), // Data is seconds.
|
||||
USeconds = log2(0x00000002), // Data is microseconds.
|
||||
NSeconds = log2(_NOTE_NSECONDS), // Data is nanoseconds.
|
||||
Absolute = log2(_NOTE_ABSOLUTE), // Absolute timeout.
|
||||
}
|
||||
Timer_Flags :: bit_set[Timer_Flag; u32]
|
||||
|
||||
when ODIN_OS == .Darwin {
|
||||
|
||||
_Filter_Backing :: distinct i16
|
||||
_Flags_Backing :: distinct u16
|
||||
|
||||
_FILTER_READ :: -1
|
||||
_FILTER_WRITE :: -2
|
||||
_FILTER_AIO :: -3
|
||||
_FILTER_VNODE :: -4
|
||||
_FILTER_PROC :: -5
|
||||
_FILTER_SIGNAL :: -6
|
||||
_FILTER_TIMER :: -7
|
||||
|
||||
_NOTE_NSECONDS :: 0x00000004
|
||||
_NOTE_ABSOLUTE :: 0x00000008
|
||||
|
||||
KEvent :: struct #align(4) {
|
||||
// Value used to identify this event. The exact interpretation is determined by the attached filter.
|
||||
ident: uintptr,
|
||||
// Filter for event.
|
||||
filter: Filter,
|
||||
// General flags.
|
||||
flags: Flags,
|
||||
// Filter specific flags.
|
||||
fflags: struct #raw_union {
|
||||
rw: RW_Flags,
|
||||
vnode: VNode_Flags,
|
||||
fproc: Proc_Flags,
|
||||
// vm: VM_Flags,
|
||||
timer: Timer_Flags,
|
||||
},
|
||||
// Filter specific data.
|
||||
data: c.long /* intptr_t */,
|
||||
// Opaque user data passed through the kernel unchanged.
|
||||
udata: rawptr,
|
||||
}
|
||||
|
||||
} else when ODIN_OS == .FreeBSD {
|
||||
|
||||
_Filter_Backing :: distinct i16
|
||||
_Flags_Backing :: distinct u16
|
||||
|
||||
_FILTER_READ :: -1
|
||||
_FILTER_WRITE :: -2
|
||||
_FILTER_AIO :: -3
|
||||
_FILTER_VNODE :: -4
|
||||
_FILTER_PROC :: -5
|
||||
_FILTER_SIGNAL :: -6
|
||||
_FILTER_TIMER :: -7
|
||||
|
||||
_NOTE_NSECONDS :: 0x00000004
|
||||
_NOTE_ABSOLUTE :: 0x00000008
|
||||
|
||||
KEvent :: struct {
|
||||
// Value used to identify this event. The exact interpretation is determined by the attached filter.
|
||||
ident: uintptr,
|
||||
// Filter for event.
|
||||
filter: Filter,
|
||||
// General flags.
|
||||
flags: Flags,
|
||||
// Filter specific flags.
|
||||
fflags: struct #raw_union {
|
||||
rw: RW_Flags,
|
||||
vnode: VNode_Flags,
|
||||
fproc: Proc_Flags,
|
||||
// vm: VM_Flags,
|
||||
timer: Timer_Flags,
|
||||
},
|
||||
// Filter specific data.
|
||||
data: i64,
|
||||
// Opaque user data passed through the kernel unchanged.
|
||||
udata: rawptr,
|
||||
// Extensions.
|
||||
ext: [4]u64,
|
||||
}
|
||||
} else when ODIN_OS == .NetBSD {
|
||||
|
||||
_Filter_Backing :: distinct u32
|
||||
_Flags_Backing :: distinct u32
|
||||
|
||||
_FILTER_READ :: 0
|
||||
_FILTER_WRITE :: 1
|
||||
_FILTER_AIO :: 2
|
||||
_FILTER_VNODE :: 3
|
||||
_FILTER_PROC :: 4
|
||||
_FILTER_SIGNAL :: 5
|
||||
_FILTER_TIMER :: 6
|
||||
|
||||
_NOTE_NSECONDS :: 0x00000003
|
||||
_NOTE_ABSOLUTE :: 0x00000010
|
||||
|
||||
KEvent :: struct #align(4) {
|
||||
// Value used to identify this event. The exact interpretation is determined by the attached filter.
|
||||
ident: uintptr,
|
||||
// Filter for event.
|
||||
filter: Filter,
|
||||
// General flags.
|
||||
flags: Flags,
|
||||
// Filter specific flags.
|
||||
fflags: struct #raw_union {
|
||||
rw: RW_Flags,
|
||||
vnode: VNode_Flags,
|
||||
fproc: Proc_Flags,
|
||||
// vm: VM_Flags,
|
||||
timer: Timer_Flags,
|
||||
},
|
||||
// Filter specific data.
|
||||
data: i64,
|
||||
// Opaque user data passed through the kernel unchanged.
|
||||
udata: rawptr,
|
||||
// Extensions.
|
||||
ext: [4]u64,
|
||||
}
|
||||
} else when ODIN_OS == .OpenBSD {
|
||||
|
||||
_Filter_Backing :: distinct i16
|
||||
_Flags_Backing :: distinct u16
|
||||
|
||||
_FILTER_READ :: -1
|
||||
_FILTER_WRITE :: -2
|
||||
_FILTER_AIO :: -3
|
||||
_FILTER_VNODE :: -4
|
||||
_FILTER_PROC :: -5
|
||||
_FILTER_SIGNAL :: -6
|
||||
_FILTER_TIMER :: -7
|
||||
|
||||
_NOTE_NSECONDS :: 0x00000003
|
||||
_NOTE_ABSOLUTE :: 0x00000010
|
||||
|
||||
KEvent :: struct #align(4) {
|
||||
// Value used to identify this event. The exact interpretation is determined by the attached filter.
|
||||
ident: uintptr,
|
||||
// Filter for event.
|
||||
filter: Filter,
|
||||
// General flags.
|
||||
flags: Flags,
|
||||
// Filter specific flags.
|
||||
fflags: struct #raw_union {
|
||||
rw: RW_Flags,
|
||||
vnode: VNode_Flags,
|
||||
fproc: Proc_Flags,
|
||||
// vm: VM_Flags,
|
||||
timer: Timer_Flags,
|
||||
},
|
||||
// Filter specific data.
|
||||
data: i64,
|
||||
// Opaque user data passed through the kernel unchanged.
|
||||
udata: rawptr,
|
||||
}
|
||||
}
|
||||
|
||||
@(private)
|
||||
log2 :: intrinsics.constant_log2
|
||||
|
||||
foreign lib {
|
||||
@(link_name="kqueue")
|
||||
_kqueue :: proc() -> KQ ---
|
||||
@(link_name="kevent")
|
||||
_kevent :: proc(kq: KQ, change_list: [^]KEvent, n_changes: c.int, event_list: [^]KEvent, n_events: c.int, timeout: ^posix.timespec) -> c.int ---
|
||||
}
|
||||
Reference in New Issue
Block a user