| 240 | #[cfg(target_os = "linux")] |
| 241 | #[allow(clippy::similar_names)] |
| 242 | pub fn collect_cmdline_paths(pid: u32, stop_pid: u32, exclude: &[PathBuf]) -> Vec<PathBuf> { |
| 243 | const MAX_DEPTH: usize = 64; |
| 244 | let mut paths = Vec::new(); |
| 245 | let mut current = pid; |
| 246 | |
| 247 | // Collect from the immediate PID first |
| 248 | for p in cmdline_absolute_paths(current) { |
| 249 | if !exclude.contains(&p) && !paths.contains(&p) { |
| 250 | paths.push(p); |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | // Then walk ancestors (same traversal as collect_ancestor_binaries) |
| 255 | for _ in 0..MAX_DEPTH { |
| 256 | let ppid = match read_ppid(current) { |
| 257 | Some(p) if p > 0 && p != current => p, |
| 258 | _ => break, |
| 259 | }; |
| 260 | |
| 261 | for p in cmdline_absolute_paths(ppid) { |
| 262 | if !exclude.contains(&p) && !paths.contains(&p) { |
| 263 | paths.push(p); |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | if ppid == stop_pid || ppid == 1 { |
| 268 | break; |
| 269 | } |
| 270 | current = ppid; |
| 271 | } |
| 272 | |
| 273 | paths |
| 274 | } |
| 275 | |
| 276 | /// Parse `/proc/<pid>/net/tcp` (and `/proc/<pid>/net/tcp6`) to find the socket |
| 277 | /// inode for a given local port. |