aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2025-05-04 01:05:10 +0200
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2025-05-04 01:05:10 +0200
commit0f2a4b80efcb8e30a31fe74e10c2fcc503537466 (patch)
treec071993d012f76888da37ac82931adf28ba7f2ff
parentdeededfb0a99742a4e7cca2464c7f4a6b3d07604 (diff)
Proper fix for executable name on Linux.
-rw-r--r--core/os/os2/process_linux.odin63
1 files changed, 27 insertions, 36 deletions
diff --git a/core/os/os2/process_linux.odin b/core/os/os2/process_linux.odin
index a0815ca7d..1480e66b5 100644
--- a/core/os/os2/process_linux.odin
+++ b/core/os/os2/process_linux.odin
@@ -162,7 +162,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
}
}
- cmdline_if: if selection & {.Working_Dir, .Command_Line, .Command_Args, .Executable_Path} != {} {
+ cmdline_if: if selection & {.Working_Dir, .Command_Line, .Command_Args} != {} {
strings.builder_reset(&path_builder)
strings.write_string(&path_builder, "/proc/")
strings.write_int(&path_builder, pid)
@@ -178,12 +178,12 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
terminator := strings.index_byte(cmdline, 0)
assert(terminator > 0)
- command_line_exec := cmdline[:terminator]
+ // 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] != '/') {
+ if .Working_Dir in selection {
strings.builder_reset(&path_builder)
strings.write_string(&path_builder, "/proc/")
strings.write_int(&path_builder, pid)
@@ -199,39 +199,6 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
}
}
- if .Executable_Path in selection {
- if cwd_err == nil {
- info.executable_path = strings.clone(command_line_exec, allocator) or_return
- info.fields += {.Executable_Path}
- } else {
- break cmdline_if
- }
- /*
- NOTE(Jeroen):
-
- This old version returns the wrong executable path for things like `bash` or `sh`,
- for whom `/proc/<pid>/cmdline` will just report "bash" or "sh",
- resulting in misleading paths like `$PWD/sh`, even though that executable doesn't exist there.
-
- A way to "fix" this would be to invoke `which <name>` or scour the $PATH variable, but a better way
- would be preferred.
-
- To be fair, `htop` also suffers from this problem and will list `bash`, `tmux`, `xfce4-panel` as just their
- executable name in the command line column. So I think we shouldn't prepend the current directory when an executable is
- found in the $PATH, which is what seems to be happening here.
-
- if command_line_exec[0] == '/' {
- info.executable_path = strings.clone(command_line_exec, allocator) or_return
- info.fields += {.Executable_Path}
- } else if cwd_err == nil {
- info.executable_path = join_path({cwd, command_line_exec}, allocator) or_return
- info.fields += {.Executable_Path}
- } else {
- break cmdline_if
- }
- */
- }
-
if selection & {.Command_Line, .Command_Args} != {} {
// skip to first arg
//cmdline = cmdline[terminator + 1:]
@@ -344,6 +311,30 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
}
}
+ if .Executable_Path in selection {
+ /*
+ NOTE(Jeroen):
+
+ The old version returned the wrong executable path for things like `bash` or `sh`,
+ for whom `/proc/<pid>/cmdline` will just report "bash" or "sh",
+ resulting in misleading paths like `$PWD/sh`, even though that executable doesn't exist there.
+
+ Thanks to Yawning for suggesting `/proc/self/exe`.
+ */
+
+ strings.builder_reset(&path_builder)
+ strings.write_string(&path_builder, "/proc/")
+ strings.write_int(&path_builder, pid)
+ strings.write_string(&path_builder, "/exe")
+
+ if exe_bytes, exe_err := _read_link(strings.to_string(path_builder), temp_allocator()); exe_err == nil {
+ info.executable_path = strings.clone(string(exe_bytes), allocator) or_return
+ info.fields += {.Executable_Path}
+ } else {
+ err = exe_err
+ }
+ }
+
if .Environment in selection {
strings.builder_reset(&path_builder)
strings.write_string(&path_builder, "/proc/")