aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jkercher43@gmail.com>2024-07-24 10:09:50 -0400
committerjason <jkercher43@gmail.com>2024-07-24 10:09:50 -0400
commitecdd3887b28de42e9a023258a0c5ebbe26d3e7ab (patch)
tree543e95ddb5a7310290f749af5b3524b4e0c36875
parent16bdc6d240c1f09a394951b2504c152137bb10da (diff)
fix process_info assumptions
-rw-r--r--core/os/os2/process_linux.odin101
1 files changed, 63 insertions, 38 deletions
diff --git a/core/os/os2/process_linux.odin b/core/os/os2/process_linux.odin
index f54528d69..f8da3ea08 100644
--- a/core/os/os2/process_linux.odin
+++ b/core/os/os2/process_linux.odin
@@ -114,12 +114,15 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
info.fields = selection
- // Use this so we can use bprintf to make cstrings with less copying
+ // Use this so we can use bprintf to make cstrings with less copying.
+ // The path_backing is manually zero terminated as we go.
path_backing: [48]u8
+
path_slice := path_backing[:len(path_backing) - 1]
- path_cstr := cstring(&path_slice[0])
+ path_cstr := cstring(&path_slice[0])
+ path_len := len(fmt.bprintf(path_slice, "/proc/%d", pid))
+ // path_len unused here as path_backing[path_len] = 0 is assumed.
- _ = fmt.bprintf(path_slice, "/proc/%d", pid)
proc_fd, errno := linux.open(path_cstr, _OPENDIR_FLAGS)
if errno != .NONE {
err = _get_platform_error(errno)
@@ -158,13 +161,63 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
}
}
- if .Working_Dir in selection {
- _ = fmt.bprintf(path_slice, "/proc/%d/cwd", pid)
- info.working_dir, _ = _read_link_cstr(path_cstr, allocator) // allowed to fail
+ cmdline_if: if selection & {.Working_Dir, .Command_Line, .Command_Args, .Executable_Path} != {} {
+ path_len = len(fmt.bprintf(path_slice, "/proc/%d/cmdline", pid))
+ path_backing[path_len] = 0
+
+ cmdline_bytes := _read_entire_pseudo_file(path_cstr, temp_allocator()) or_return
+ if len(cmdline_bytes) == 0 {
+ break cmdline_if
+ }
+ cmdline := string(cmdline_bytes)
+
+ terminator := strings.index_byte(cmdline, 0)
+
+ command_line_exec := cmdline[:terminator]
+
+ // Still need cwd if the execution on the command line is relative.
+ cwd: string
+ cwd_err: Error
+ if .Working_Dir in selection || (.Executable_Path in selection && command_line_exec[0] != '/') {
+ path_len = len(fmt.bprintf(path_slice, "/proc/%d/cwd", pid))
+ path_backing[path_len] = 0
+
+ cwd, cwd_err = _read_link_cstr(path_cstr, temp_allocator()) // allowed to fail
+ if cwd_err == nil && .Working_Dir in selection {
+ info.working_dir = strings.clone(cwd, allocator)
+ }
+ }
+
+ if .Executable_Path in selection {
+ if cmdline[0] == '/' {
+ info.executable_path = strings.clone(cmdline[:terminator], allocator)
+ } else if cwd_err == nil {
+ join_paths: [2]string = { cwd, cmdline[:terminator] }
+ info.executable_path = filepath.join(join_paths[:], allocator)
+ }
+ }
+ if .Command_Line in selection {
+ info.command_line = strings.clone(cmdline[:terminator], allocator)
+ }
+
+ if .Command_Args in selection {
+ // skip to first arg
+ cmdline = cmdline[terminator + 1:]
+
+ arg_list := make([dynamic]string, allocator)
+ for len(cmdline) > 0 {
+ terminator = strings.index_byte(cmdline, 0)
+ append(&arg_list, strings.clone(cmdline[:terminator], allocator))
+ cmdline = cmdline[terminator + 1:]
+ }
+ info.command_args = arg_list[:]
+ }
}
stat_if: if selection & {.PPid, .Priority} != {} {
- _ = fmt.bprintf(path_slice, "/proc/%d/stat", pid)
+ path_len = len(fmt.bprintf(path_slice, "/proc/%d/stat", pid))
+ path_backing[path_len] = 0
+
proc_stat_bytes := _read_entire_pseudo_file(path_cstr, temp_allocator()) or_return
if len(proc_stat_bytes) <= 0 {
break stat_if
@@ -195,38 +248,10 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
}
}
- cmdline_if: if selection & {.Command_Line, .Command_Args, .Executable_Path} != {} {
- _ = fmt.bprintf(path_slice, "/proc/%d/cmdline", pid)
- cmdline_bytes := _read_entire_pseudo_file(path_cstr, temp_allocator()) or_return
- if len(cmdline_bytes) == 0 {
- break cmdline_if
- }
- cmdline := string(cmdline_bytes)
-
- terminator := strings.index_byte(cmdline, 0)
- if .Executable_Path in selection {
- info.executable_path = strings.clone(cmdline[:terminator], allocator)
- }
- if .Command_Line in selection {
- info.command_line = strings.clone(cmdline[:terminator], allocator)
- }
-
- if .Command_Args in selection {
- // skip to first arg
- cmdline = cmdline[terminator + 1:]
-
- arg_list := make([dynamic]string, allocator)
- for len(cmdline) > 0 {
- terminator = strings.index_byte(cmdline, 0)
- append(&arg_list, strings.clone(cmdline[:terminator], allocator))
- cmdline = cmdline[terminator + 1:]
- }
- info.command_args = arg_list[:]
- }
- }
-
if .Environment in selection {
- _ = fmt.bprintf(path_slice, "/proc/%d/environ", pid)
+ path_len = len(fmt.bprintf(path_slice, "/proc/%d/environ", pid))
+ path_backing[path_len] = 0
+
if env_bytes, env_err := _read_entire_pseudo_file(path_cstr, temp_allocator()); env_err == nil {
env := string(env_bytes)