support returning Err when creating posix thread

This commit is contained in:
Jianfeng Jiang 2023-03-14 19:41:08 +08:00 committed by Tate, Hongliang Tian
parent 330e495560
commit 45427da50e
3 changed files with 47 additions and 53 deletions

View File

@ -86,7 +86,7 @@ pub fn run_first_process() -> ! {
unreachable!()
}
fn run_busybox() -> Result<()> {
fn run_busybox() -> Result<Arc<Process>> {
let executable_path = "/busybox/busybox";
let argv = ["sh", "-l"];
let envp = [
@ -108,6 +108,5 @@ fn run_busybox() -> Result<()> {
.collect();
println!("");
println!("BusyBox v1.35.0 built-in shell (ash)\n");
Process::spawn_user_process(executable_path, argv, envp);
Ok(())
Process::spawn_user_process(executable_path, argv, envp)
}

View File

@ -14,7 +14,7 @@ use crate::fs::file_table::FileTable;
use crate::fs::fs_resolver::FsResolver;
use crate::prelude::*;
use crate::rights::Full;
use crate::thread::{thread_table, Thread};
use crate::thread::{allocate_tid, thread_table, Thread};
use crate::tty::get_n_tty;
use crate::vm::vmar::Vmar;
use jinux_frame::sync::WaitQueue;
@ -140,63 +140,58 @@ impl Process {
executable_path: &str,
argv: Vec<CString>,
envp: Vec<CString>,
) -> Arc<Self> {
let process = Process::create_user_process(executable_path, argv, envp);
) -> Result<Arc<Self>> {
let process = Process::create_user_process(executable_path, argv, envp)?;
// FIXME: How to determine the fg process group?
let pgid = process.pgid();
// FIXME: tty should be a parameter?
let tty = get_n_tty();
tty.set_fg(pgid);
process.run();
process
Ok(process)
}
fn create_user_process(
executable_path: &str,
argv: Vec<CString>,
envp: Vec<CString>,
) -> Arc<Self> {
let user_process = Arc::new_cyclic(|weak_process_ref| {
let weak_process = weak_process_ref.clone();
let root_vmar = Vmar::<Full>::new_root().unwrap();
let fs = FsResolver::new();
let thread = Thread::new_posix_thread_from_executable(
&root_vmar,
&fs,
executable_path,
weak_process,
argv,
envp,
);
let pid = thread.tid();
// spawn process will be called in a kernel thread, so the parent process is always none.
let parent = Weak::new();
let user_vm = UserVm::new();
let file_table = FileTable::new_with_stdio();
let fs = FsResolver::new();
let sig_dispositions = SigDispositions::new();
) -> Result<Arc<Self>> {
let root_vmar = Vmar::<Full>::new_root()?;
let fs = FsResolver::new();
let pid = allocate_tid();
let parent = Weak::new();
let process_group = Weak::new();
let user_vm = UserVm::new();
let file_table = FileTable::new_with_stdio();
let sig_dispositions = SigDispositions::new();
let user_process = Arc::new(Process::new(
pid,
parent,
vec![],
Some(executable_path.to_string()),
Some(user_vm),
Arc::new(root_vmar),
process_group,
Arc::new(Mutex::new(file_table)),
Arc::new(RwLock::new(fs)),
Arc::new(Mutex::new(sig_dispositions)),
));
let thread = Thread::new_posix_thread_from_executable(
pid,
&user_process.root_vmar(),
&user_process.fs().read(),
executable_path,
Arc::downgrade(&user_process),
argv,
envp,
)?;
user_process.threads().lock().push(thread);
let process = Process::new(
pid,
parent,
vec![thread],
Some(executable_path.to_string()),
Some(user_vm),
Arc::new(root_vmar),
Weak::new(),
Arc::new(Mutex::new(file_table)),
Arc::new(RwLock::new(fs)),
Arc::new(Mutex::new(sig_dispositions)),
);
process
});
// Set process group
user_process.create_and_set_process_group();
process_table::add_process(user_process.clone());
if let Some(parent) = user_process.parent() {
parent.add_child(user_process.clone());
}
user_process
Ok(user_process)
}
/// returns the pid of the process

View File

@ -5,7 +5,7 @@ use crate::{
prelude::*,
process::{program_loader::load_program_to_root_vmar, Process},
rights::Full,
thread::{allocate_tid, Thread},
thread::{Thread, Tid},
vm::vmar::Vmar,
};
@ -13,25 +13,27 @@ use super::{builder::PosixThreadBuilder, name::ThreadName, PosixThread};
pub trait PosixThreadExt {
fn as_posix_thread(&self) -> Option<&PosixThread>;
fn new_posix_thread_from_executable(
tid: Tid,
root_vmar: &Vmar<Full>,
fs_resolver: &FsResolver,
executable_path: &str,
process: Weak<Process>,
argv: Vec<CString>,
envp: Vec<CString>,
) -> Arc<Self>;
) -> Result<Arc<Self>>;
}
impl PosixThreadExt for Thread {
/// This function should only be called when launch shell()
fn new_posix_thread_from_executable(
tid: Tid,
root_vmar: &Vmar<Full>,
fs_resolver: &FsResolver,
executable_path: &str,
process: Weak<Process>,
argv: Vec<CString>,
envp: Vec<CString>,
) -> Arc<Self> {
) -> Result<Arc<Self>> {
let elf_load_info = load_program_to_root_vmar(
root_vmar,
executable_path.to_string(),
@ -39,20 +41,18 @@ impl PosixThreadExt for Thread {
envp,
fs_resolver,
1,
)
.unwrap();
)?;
let vm_space = root_vmar.vm_space().clone();
let mut cpu_ctx = CpuContext::default();
cpu_ctx.set_rip(elf_load_info.entry_point() as _);
cpu_ctx.set_rsp(elf_load_info.user_stack_top() as _);
let user_space = Arc::new(UserSpace::new(vm_space, cpu_ctx));
let thread_name = Some(ThreadName::new_from_executable_path(executable_path).unwrap());
let tid = allocate_tid();
let thread_name = Some(ThreadName::new_from_executable_path(executable_path)?);
let thread_builder = PosixThreadBuilder::new(tid, user_space)
.thread_name(thread_name)
.process(process);
thread_builder.build()
Ok(thread_builder.build())
}
fn as_posix_thread(&self) -> Option<&PosixThread> {