mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 21:06:48 +00:00
support returning Err when creating posix thread
This commit is contained in:
parent
330e495560
commit
45427da50e
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user