diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index 5b61ee8695..833abe0daa 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -534,7 +534,7 @@ impl ProcScheme { token: &mut CleanLockToken, ) -> Result<(usize, InternalFlags)> { let operation_name = operation_str.ok_or(Error::new(EINVAL))?; - // /proc/self → resolve to /proc/ + // /proc/self[/...] → resolve /proc/[/...] if operation_name == "proc/self" || operation_name == "self" { let pid = context::current().read(token.token()).pid; let handle = Handle { @@ -542,7 +542,26 @@ impl ProcScheme { kind: ContextHandle::ProcDir { pid }, }; return new_handle((handle, InternalFlags::POSITIONED), token); - }; + } + if operation_name.starts_with("proc/self/") || operation_name.starts_with("self/") { + let pid = context::current().read(token.token()).pid; + let rest = if operation_name.starts_with("proc/self/") { + &operation_name["proc/self/".len()..] + } else { + &operation_name["self/".len()..] + }; + let resolved = format!("proc/{}/{}", pid, rest); + let mut parts = resolved.split('/'); + let _ = parts.next(); // "proc" + let pid = parts.next().and_then(|p| p.parse::().ok()).unwrap_or(pid); + if let Some(kind) = Self::proc_open(&resolved) { + let handle = Handle { + context: context::current(), + kind, + }; + return new_handle((handle, InternalFlags::POSITIONED), token); + } + } if let Some(kind) = Self::proc_open(operation_name) { let handle = Handle { context: context::current(),