@@ -109,14 +109,42 @@ fn fork_and_wait() -> Result<()> {
109109/// The reason we need this is because we actually need to attach to the
110110/// *supervised* process, not the *supervisor* process, which exists in
111111/// a different set of namespaces than the ones we want to attach to.
112+ ///
113+ /// Tries `/proc/<pid>/task/<pid>/children` first (requires CONFIG_PROC_CHILDREN),
114+ /// then falls back to scanning `/proc` for processes whose PPid matches.
112115fn first_child_pid_of ( parent : libc:: pid_t ) -> Result < libc:: pid_t > {
113- let child_set = fs:: read_to_string ( format ! ( "/proc/{parent}/task/{parent}/children" ) ) ?;
114- let first_child = child_set. split ( " " ) . collect :: < Vec < _ > > ( ) [ 0 ] ;
116+ // Fast path: use the children file if available (CONFIG_PROC_CHILDREN=y).
117+ let children_path = format ! ( "/proc/{parent}/task/{parent}/children" ) ;
118+ if let Ok ( child_set) = fs:: read_to_string ( & children_path) {
119+ let first_child = child_set. split ( ' ' ) . next ( ) . unwrap_or ( "" ) ;
120+ if let Ok ( v) = first_child. parse :: < libc:: pid_t > ( ) {
121+ return Ok ( v) ;
122+ }
123+ }
115124
116- match first_child. parse :: < libc:: pid_t > ( ) {
117- Ok ( v) => Ok ( v) ,
118- _ => Err ( anyhow ! ( "failed to find child PID" ) ) ,
125+ // Fallback: scan /proc for a process whose PPid matches parent.
126+ let ppid_needle = format ! ( "PPid:\t {parent}" ) ;
127+ for entry in fs:: read_dir ( "/proc" ) ? {
128+ let entry = entry?;
129+ let name = entry. file_name ( ) ;
130+ let name_str = name. to_string_lossy ( ) ;
131+ // Only look at numeric directories (PIDs).
132+ if !name_str. chars ( ) . next ( ) . map_or ( false , |c| c. is_ascii_digit ( ) ) {
133+ continue ;
134+ }
135+ let status_path = format ! ( "/proc/{name_str}/status" ) ;
136+ if let Ok ( status) = fs:: read_to_string ( & status_path) {
137+ if status. lines ( ) . any ( |line| line == ppid_needle) {
138+ if let Ok ( pid) = name_str. parse :: < libc:: pid_t > ( ) {
139+ return Ok ( pid) ;
140+ }
141+ }
142+ }
119143 }
144+
145+ Err ( anyhow ! (
146+ "failed to find child PID of {parent} (no children file, /proc scan found nothing)"
147+ ) )
120148}
121149
122150fn render_uidgid_mappings ( mappings : & [ IdMapping ] ) -> String {
0 commit comments