mirror of
https://github.com/odin-lang/Odin.git
synced 2025-12-28 17:04:34 +00:00
257 lines
6.4 KiB
Odin
257 lines
6.4 KiB
Odin
#+build darwin, netbsd, openbsd, freebsd
|
|
package kqueue
|
|
|
|
when ODIN_OS == .Darwin {
|
|
foreign import lib "system:System"
|
|
} 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 ---
|
|
}
|