starry_api/imp/task/
execve.rs1use core::ffi::c_char;
2
3use alloc::{string::ToString, vec::Vec};
4use axerrno::{LinuxError, LinuxResult};
5use axhal::arch::TrapFrame;
6use axtask::{TaskExtRef, current};
7use starry_core::mm::{load_user_app, map_trampoline};
8
9use crate::ptr::UserConstPtr;
10
11pub fn sys_execve(
12 tf: &mut TrapFrame,
13 path: UserConstPtr<c_char>,
14 argv: UserConstPtr<UserConstPtr<c_char>>,
15 envp: UserConstPtr<UserConstPtr<c_char>>,
16) -> LinuxResult<isize> {
17 let path = path.get_as_str()?.to_string();
18
19 let args = argv
20 .get_as_null_terminated()?
21 .iter()
22 .map(|arg| arg.get_as_str().map(Into::into))
23 .collect::<Result<Vec<_>, _>>()?;
24 let envs = envp
25 .get_as_null_terminated()?
26 .iter()
27 .map(|env| env.get_as_str().map(Into::into))
28 .collect::<Result<Vec<_>, _>>()?;
29
30 info!(
31 "sys_execve: path: {:?}, args: {:?}, envs: {:?}",
32 path, args, envs
33 );
34
35 let curr = current();
36 let curr_ext = curr.task_ext();
37
38 if curr_ext.thread.process().threads().len() > 1 {
39 error!("sys_execve: multi-thread not supported");
41 return Err(LinuxError::EAGAIN);
42 }
43
44 let mut aspace = curr_ext.process_data().aspace.lock();
45 aspace.unmap_user_areas()?;
46 map_trampoline(&mut aspace)?;
47 axhal::arch::flush_tlb(None);
48
49 let (entry_point, user_stack_base) =
50 load_user_app(&mut aspace, &args, &envs).map_err(|_| {
51 error!("Failed to load app {}", path);
52 LinuxError::ENOENT
53 })?;
54 drop(aspace);
55
56 let name = path
57 .rsplit_once('/')
58 .map_or(path.as_str(), |(_, name)| name);
59 curr.set_name(name);
60 *curr_ext.process_data().exe_path.write() = path;
61
62 tf.set_ip(entry_point.as_usize());
65 tf.set_sp(user_stack_base.as_usize());
66 Ok(0)
67}