mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 16:18:52 +00:00
os2: process API for Darwin and most of it for BSDs
This commit is contained in:
@@ -8,6 +8,7 @@ import "core:bytes"
|
||||
import "core:sys/darwin"
|
||||
import "core:sys/posix"
|
||||
import "core:sys/unix"
|
||||
import "core:time"
|
||||
|
||||
foreign import lib "system:System.framework"
|
||||
|
||||
@@ -19,8 +20,6 @@ foreign lib {
|
||||
) -> posix.result ---
|
||||
}
|
||||
|
||||
import "core:fmt"
|
||||
|
||||
_process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator: runtime.Allocator) -> (info: Process_Info, err: Error) {
|
||||
get_pidinfo :: proc(pid: int, selection: Process_Info_Fields) -> (ppid: u32, prio: Maybe(i32), uid: posix.uid_t, ok: bool) {
|
||||
// Short info is enough and requires less permissions if the priority isn't requested.
|
||||
@@ -258,31 +257,56 @@ _process_list :: proc(allocator: runtime.Allocator) -> (list: []int, err: Error)
|
||||
}
|
||||
|
||||
_process_open :: proc(pid: int, flags: Process_Open_Flags) -> (process: Process, err: Error) {
|
||||
|
||||
// NOTE(laytan): pids can get reused, and afaik posix/macos doesn't have a unique identifier
|
||||
// for a specific process execution, next best thing to me is checking the time the process
|
||||
// started as some extra "uniqueness". We could also hash a bunch of the fields in this info.
|
||||
|
||||
// This incidentally also checks if the pid is actually valid so that's nice.
|
||||
|
||||
pinfo: darwin.proc_bsdinfo
|
||||
ret := darwin.proc_pidinfo(posix.pid_t(pid), .BSDINFO, 0, &pinfo, size_of(pinfo))
|
||||
if ret <= 0 {
|
||||
rusage: darwin.rusage_info_v0
|
||||
if ret := darwin.proc_pid_rusage(posix.pid_t(pid), .V0, &rusage); ret != 0 {
|
||||
err = _get_platform_error()
|
||||
return
|
||||
}
|
||||
|
||||
assert(ret == size_of(pinfo))
|
||||
process = { int(pid), uintptr(pinfo.pbi_start_tvusec) }
|
||||
// XOR fold the UUID so it fits the handle, I think this is enough to verify pid uniqueness.
|
||||
#assert(size_of(uintptr) == size_of(u64))
|
||||
a := intrinsics.unaligned_load((^u64)(&rusage.ri_uuid))
|
||||
b := intrinsics.unaligned_load((^u64)(&rusage.ri_uuid[8]))
|
||||
process.handle = uintptr(a ~ b)
|
||||
|
||||
process.pid = int(pid)
|
||||
return
|
||||
}
|
||||
|
||||
process_posix_handle_still_valid :: proc(p: Process) -> bool {
|
||||
pinfo: darwin.proc_bsdinfo
|
||||
ret := darwin.proc_pidinfo(posix.pid_t(p.pid), .BSDINFO, 0, &pinfo, size_of(pinfo))
|
||||
if ret <= 0 {
|
||||
return false
|
||||
_process_handle_still_valid :: proc(p: Process) -> Error {
|
||||
rusage: darwin.rusage_info_v0
|
||||
if ret := darwin.proc_pid_rusage(posix.pid_t(p.pid), .V0, &rusage); ret != 0 {
|
||||
return _get_platform_error()
|
||||
}
|
||||
|
||||
return uintptr(pinfo.pbi_start_tvusec) == p.handle
|
||||
// XOR fold the UUID so it fits the handle, I think this is enough to verify pid uniqueness.
|
||||
#assert(size_of(uintptr) == size_of(u64))
|
||||
a := intrinsics.unaligned_load((^u64)(&rusage.ri_uuid))
|
||||
b := intrinsics.unaligned_load((^u64)(&rusage.ri_uuid[8]))
|
||||
handle := uintptr(a ~ b)
|
||||
|
||||
if p.handle != handle {
|
||||
return posix.Errno.ESRCH
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
_process_state_update_times :: proc(p: Process, state: ^Process_State) {
|
||||
rusage: darwin.rusage_info_v0
|
||||
if ret := darwin.proc_pid_rusage(posix.pid_t(p.pid), .V0, &rusage); ret != 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// NOTE(laytan): I have no clue if this is correct, the output seems correct comparing it with `time`'s output.
|
||||
HZ :: 20000000
|
||||
|
||||
state.user_time = (
|
||||
(time.Duration(rusage.ri_user_time) / HZ * time.Second) +
|
||||
time.Duration(rusage.ri_user_time % HZ))
|
||||
state.system_time = (
|
||||
(time.Duration(rusage.ri_system_time) / HZ * time.Second) +
|
||||
time.Duration(rusage.ri_system_time % HZ))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user