1use alloc::vec::Vec;
16
17use crate::abi::MAX_ABI_LENGTH;
18use crate::device::manager::DeviceManager;
19use crate::executor::executor::TransparentExecutor;
20use crate::fs::MAX_PATH_LENGTH;
21use crate::library::std::string::{parse_c_string_from_userspace, parse_string_array_from_userspace};
22
23use crate::arch::{get_cpu, Trapframe};
24use crate::sched::scheduler::get_scheduler;
25use crate::task::{get_parent_waker, get_task_waker, CloneFlags, WaitError};
26
27const MAX_ARG_COUNT: usize = 256; pub const EXECVE_FORCE_ABI_REBUILD: usize = 0x1; use super::mytask;
33
34pub fn sys_brk(trapframe: &mut Trapframe) -> usize {
35 let task = mytask().unwrap();
36 let brk = trapframe.get_arg(0);
37 trapframe.increment_pc_next(task);
38 match task.set_brk(brk) {
39 Ok(_) => task.get_brk(),
40 Err(_) => usize::MAX, }
42}
43
44pub fn sys_sbrk(trapframe: &mut Trapframe) -> usize {
45 let task = mytask().unwrap();
46 let increment = trapframe.get_arg(0);
47 let brk = task.get_brk();
48 trapframe.increment_pc_next(task);
49 match task.set_brk(unsafe { brk.unchecked_add(increment) }) {
50 Ok(_) => brk,
51 Err(_) => usize::MAX, }
53}
54
55pub fn sys_putchar(trapframe: &mut Trapframe) -> usize {
56 let c = trapframe.get_arg(0) as u32;
57 let task = mytask().unwrap();
58 trapframe.increment_pc_next(task);
59 if let Some(ch) = char::from_u32(c) {
60 let manager = DeviceManager::get_manager();
61 if let Some(device_id) = manager.get_first_device_by_type(crate::device::DeviceType::Char) {
62 if let Some(char_device) = manager.get_device(device_id).unwrap().as_char_device() {
63 if let Err(e) = char_device.write_byte(ch as u8) {
65 crate::print!("Error writing character: {}", e);
66 return usize::MAX; }
68 return 0;
70 }
71 }
72 }
73 return usize::MAX; }
75
76pub fn sys_getchar(trapframe: &mut Trapframe) -> usize {
77 let task = mytask().unwrap();
78 trapframe.increment_pc_next(task);
79
80 let manager = DeviceManager::get_manager();
82 if let Some(borrowed_device) = manager.get_device_by_name("tty0") {
83 if let Some(char_device) = borrowed_device.as_char_device() {
84 if let Some(byte) = char_device.read_byte() {
86 return byte as usize;
87 }
88 }
89 }
90
91 0 }
93
94pub fn sys_exit(trapframe: &mut Trapframe) -> usize {
95 let task = mytask().unwrap();
96 task.vcpu.store(trapframe);
97 let exit_code = trapframe.get_arg(0) as i32;
98 task.exit(exit_code);
99 get_scheduler().schedule(get_cpu());
101}
102
103pub fn sys_clone(trapframe: &mut Trapframe) -> usize {
104 let parent_task = mytask().unwrap();
105 trapframe.increment_pc_next(parent_task); parent_task.vcpu.store(trapframe);
108 let clone_flags = CloneFlags::from_raw(trapframe.get_arg(0) as u64);
109
110 match parent_task.clone_task(clone_flags) {
112 Ok(mut child_task) => {
113 let child_id = child_task.get_id();
114 child_task.vcpu.regs.reg[10] = 0; get_scheduler().add_task(child_task, get_cpu().get_cpuid());
116 child_id
118 },
119 Err(_) => {
120 usize::MAX }
122 }
123}
124
125pub fn sys_execve(trapframe: &mut Trapframe) -> usize {
126 let task = mytask().unwrap();
127
128 trapframe.increment_pc_next(task);
130
131 let path_ptr = trapframe.get_arg(0);
133 let argv_ptr = trapframe.get_arg(1);
134 let envp_ptr = trapframe.get_arg(2);
135 let flags = trapframe.get_arg(3); let path_str = match parse_c_string_from_userspace(task, path_ptr, MAX_PATH_LENGTH) {
139 Ok(path) => path,
140 Err(_) => return usize::MAX, };
142
143 let argv_strings = match parse_string_array_from_userspace(task, argv_ptr, MAX_ARG_COUNT, MAX_PATH_LENGTH) {
145 Ok(args) => args,
146 Err(_) => return usize::MAX, };
148
149 let envp_strings = match parse_string_array_from_userspace(task, envp_ptr, MAX_ARG_COUNT, MAX_PATH_LENGTH) {
150 Ok(env) => env,
151 Err(_) => return usize::MAX, };
153
154 let argv_refs: Vec<&str> = argv_strings.iter().map(|s| s.as_str()).collect();
156 let envp_refs: Vec<&str> = envp_strings.iter().map(|s| s.as_str()).collect();
157
158 let force_abi_rebuild = (flags & EXECVE_FORCE_ABI_REBUILD) != 0;
160
161 match TransparentExecutor::execute_binary(&path_str, &argv_refs, &envp_refs, task, trapframe, force_abi_rebuild) {
163 Ok(_) => {
164 trapframe.get_return_value()
168 },
169 Err(_) => {
170 usize::MAX }
174 }
175}
176
177pub fn sys_execve_abi(trapframe: &mut Trapframe) -> usize {
178 let task = mytask().unwrap();
179
180 trapframe.increment_pc_next(task);
182
183 let path_ptr = trapframe.get_arg(0);
185 let argv_ptr = trapframe.get_arg(1);
186 let envp_ptr = trapframe.get_arg(2);
187 let abi_str_ptr = trapframe.get_arg(3);
188 let flags = trapframe.get_arg(4); let path_str = match parse_c_string_from_userspace(task, path_ptr, MAX_PATH_LENGTH) {
192 Ok(path) => path,
193 Err(_) => return usize::MAX, };
195
196 let abi_str = match parse_c_string_from_userspace(task, abi_str_ptr, MAX_ABI_LENGTH) {
198 Ok(abi) => abi,
199 Err(_) => return usize::MAX, };
201
202 let argv_strings = match parse_string_array_from_userspace(task, argv_ptr, 256, MAX_PATH_LENGTH) {
204 Ok(args) => args,
205 Err(_) => return usize::MAX, };
207
208 let envp_strings = match parse_string_array_from_userspace(task, envp_ptr, 256, MAX_PATH_LENGTH) {
209 Ok(env) => env,
210 Err(_) => return usize::MAX, };
212
213 let argv_refs: Vec<&str> = argv_strings.iter().map(|s| s.as_str()).collect();
215 let envp_refs: Vec<&str> = envp_strings.iter().map(|s| s.as_str()).collect();
216
217 let force_abi_rebuild = (flags & EXECVE_FORCE_ABI_REBUILD) != 0;
219
220 match TransparentExecutor::execute_with_abi(
222 &path_str,
223 &argv_refs,
224 &envp_refs,
225 &abi_str,
226 task,
227 trapframe,
228 force_abi_rebuild,
229 ) {
230 Ok(()) => {
231 trapframe.get_return_value()
235 }
236 Err(_) => {
237 usize::MAX }
241 }
242}
243
244pub fn sys_waitpid(trapframe: &mut Trapframe) -> usize {
245 let task = mytask().unwrap();
246 let pid = trapframe.get_arg(0) as i32;
247 let status_ptr = trapframe.get_arg(1) as *mut i32;
248 let _options = trapframe.get_arg(2) as i32; if pid == -1 {
251 for pid in task.get_children().clone() {
253 match task.wait(pid) {
254 Ok(status) => {
255 if status_ptr != core::ptr::null_mut() {
257 let status_ptr = task.vm_manager.translate_vaddr(status_ptr as usize).unwrap() as *mut i32;
258 unsafe {
259 *status_ptr = status;
260 }
261 }
262 trapframe.increment_pc_next(task);
263 return pid;
264 },
265 Err(error) => {
266 match error {
267 WaitError::ChildNotExited(_) => continue,
268 _ => {
269 trapframe.increment_pc_next(task);
270 return usize::MAX;
271 },
272 }
273 }
274 }
275 }
276
277 let parent_waker = get_parent_waker(task.get_id());
281 parent_waker.wait(task, trapframe);
282 }
283
284 match task.wait(pid as usize) {
286 Ok(status) => {
287 if status_ptr != core::ptr::null_mut() {
289 let status_ptr = task.vm_manager.translate_vaddr(status_ptr as usize).unwrap() as *mut i32;
290 unsafe {
291 *status_ptr = status;
292 }
293 }
294 trapframe.increment_pc_next(task);
295 return pid as usize;
296 }
297 Err(error) => {
298 match error {
299 WaitError::NoSuchChild(_) => {
300 trapframe.increment_pc_next(task);
301 return usize::MAX;
302 },
303 WaitError::ChildTaskNotFound(_) => {
304 trapframe.increment_pc_next(task);
305 crate::print!("Child task with PID {} not found", pid);
306 return usize::MAX;
307 },
308 WaitError::ChildNotExited(_) => {
309 let child_waker = get_task_waker(pid as usize);
311 child_waker.wait(task, trapframe);
312 },
313 }
314 }
315 }
316}
317
318pub fn sys_getpid(trapframe: &mut Trapframe) -> usize {
319 let task = mytask().unwrap();
320 trapframe.increment_pc_next(task);
321 task.get_id() as usize
322}
323
324pub fn sys_getppid(trapframe: &mut Trapframe) -> usize {
325 let task = mytask().unwrap();
326 trapframe.increment_pc_next(task);
327 task.get_parent_id().unwrap_or(task.get_id()) as usize
328}
329