Przeglądaj źródła

Proper fix for executable name on Linux.

Jeroen van Rijn 4 miesięcy temu
rodzic
commit
0f2a4b80ef
1 zmienionych plików z 27 dodań i 36 usunięć
  1. 27 36
      core/os/os2/process_linux.odin

+ 27 - 36
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/")