Fix vfork child process not close opened files
This commit is contained in:
		
							parent
							
								
									6cba1c02a1
								
							
						
					
					
						commit
						5d38c8e553
					
				@ -21,6 +21,10 @@ impl FileTable {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn table(&self) -> &Vec<Option<FileTableEntry>> {
 | 
				
			||||||
 | 
					        &self.table
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn dup(
 | 
					    pub fn dup(
 | 
				
			||||||
        &mut self,
 | 
					        &mut self,
 | 
				
			||||||
        fd: FileDesc,
 | 
					        fd: FileDesc,
 | 
				
			||||||
 | 
				
			|||||||
@ -94,6 +94,10 @@ fn restore_parent_process(mut context: *mut CpuContext, current_ref: &ThreadRef)
 | 
				
			|||||||
            return_errno!(EFAULT, "couldn't restore parent file table");
 | 
					            return_errno!(EFAULT, "couldn't restore parent file table");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Close all child opened files
 | 
				
			||||||
 | 
					    close_files_opened_by_child(current_ref, &parent_file_table)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut current_file_table = current_ref.files().lock().unwrap();
 | 
					    let mut current_file_table = current_ref.files().lock().unwrap();
 | 
				
			||||||
    *current_file_table = parent_file_table;
 | 
					    *current_file_table = parent_file_table;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -131,3 +135,24 @@ pub fn check_vfork_for_exec(current_ref: &ThreadRef) -> Option<(ThreadId, Option
 | 
				
			|||||||
        None
 | 
					        None
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn close_files_opened_by_child(current: &ThreadRef, parent_file_table: &FileTable) -> Result<()> {
 | 
				
			||||||
 | 
					    let current_file_table = current.files().lock().unwrap();
 | 
				
			||||||
 | 
					    let child_open_fds: Vec<FileDesc> = current_file_table
 | 
				
			||||||
 | 
					        .table()
 | 
				
			||||||
 | 
					        .iter()
 | 
				
			||||||
 | 
					        .enumerate()
 | 
				
			||||||
 | 
					        .filter(|(fd, _entry)| {
 | 
				
			||||||
 | 
					            // Entry is only shown in the child file table
 | 
				
			||||||
 | 
					            _entry.is_some() && parent_file_table.get_entry(*fd as FileDesc).is_err()
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .map(|(fd, entry)| fd as FileDesc)
 | 
				
			||||||
 | 
					        .collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    drop(current_file_table);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    child_open_fds
 | 
				
			||||||
 | 
					        .iter()
 | 
				
			||||||
 | 
					        .for_each(|&fd| current.close_file(fd).expect("close child file error"));
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user