1use core::usize;
16
17use alloc::vec::Vec;
18
19use crate::abi::MAX_ABI_LENGTH;
20use crate::device::manager::DeviceManager;
21use crate::executor::executor::TransparentExecutor;
22use crate::fs::MAX_PATH_LENGTH;
23use crate::library::std::string::{
24 parse_c_string_from_userspace, parse_string_array_from_userspace,
25};
26
27use crate::arch::{Trapframe, get_cpu};
28use crate::sched::scheduler::get_scheduler;
29use crate::task::{
30 CloneFlags, CloneFlagsDef, WaitError, get_parent_waitpid_waker, get_waitpid_waker,
31};
32use crate::timer::ns_to_ticks;
33
34const MAX_ARG_COUNT: usize = 256; pub const EXECVE_FORCE_ABI_REBUILD: usize = 0x1; use super::mytask;
40
41pub fn sys_brk(trapframe: &mut Trapframe) -> usize {
42 let task = mytask().unwrap();
43 let brk = trapframe.get_arg(0);
44 trapframe.increment_pc_next(task);
45 match task.set_brk(brk) {
46 Ok(_) => task.get_brk(),
47 Err(_) => usize::MAX, }
49}
50
51pub fn sys_sbrk(trapframe: &mut Trapframe) -> usize {
52 let task = mytask().unwrap();
53 let increment = trapframe.get_arg(0);
54 let brk = task.get_brk();
55 trapframe.increment_pc_next(task);
56 match task.set_brk(unsafe { brk.unchecked_add(increment) }) {
57 Ok(_) => brk,
58 Err(_) => usize::MAX, }
60}
61
62pub fn sys_putchar(trapframe: &mut Trapframe) -> usize {
63 let c = trapframe.get_arg(0) as u32;
64 let task = mytask().unwrap();
65 trapframe.increment_pc_next(task);
66 if let Some(ch) = char::from_u32(c) {
67 let manager = DeviceManager::get_manager();
68 if let Some(device_id) = manager.get_first_device_by_type(crate::device::DeviceType::Char) {
69 if let Some(char_device) = manager.get_device(device_id).unwrap().as_char_device() {
70 if let Err(e) = char_device.write_byte(ch as u8) {
72 crate::print!("Error writing character: {}", e);
73 return usize::MAX; }
75 return 0;
77 }
78 }
79 }
80 return usize::MAX; }
82
83pub fn sys_getchar(trapframe: &mut Trapframe) -> usize {
84 let task = mytask().unwrap();
85 trapframe.increment_pc_next(task);
86
87 let manager = DeviceManager::get_manager();
89 if let Some(borrowed_device) = manager.get_device_by_name("tty0") {
90 if let Some(char_device) = borrowed_device.as_char_device() {
91 if let Some(byte) = char_device.read_byte() {
93 return byte as usize;
94 }
95 }
96 }
97
98 0 }
100
101pub fn sys_exit(trapframe: &mut Trapframe) -> usize {
102 let task = mytask().unwrap();
103 task.vcpu.lock().store(trapframe);
104 let exit_code = trapframe.get_arg(0) as i32;
105 task.exit(exit_code);
106 usize::MAX }
108
109pub fn sys_clone(trapframe: &mut Trapframe) -> usize {
110 let parent_task = mytask().unwrap();
111 trapframe.increment_pc_next(parent_task); parent_task.vcpu.lock().store(trapframe);
114 let clone_flags = CloneFlags::from_raw(trapframe.get_arg(0) as u64);
115 let child_stack = trapframe.get_arg(1); let child_fn = trapframe.get_arg(2); let child_arg = trapframe.get_arg(3); let tls_ptr = trapframe.get_arg(4); match parent_task.clone_task(clone_flags) {
124 Ok(mut child_task) => {
125 child_task.vcpu.lock().iregs.set_return_value(0); if child_stack != 0 {
131 child_task.vcpu.lock().set_sp(child_stack);
132 }
133
134 if child_fn != 0 {
136 child_task.vcpu.lock().set_pc(child_fn as u64);
137 }
138
139 if child_arg != 0 {
141 child_task.vcpu.lock().iregs.set_arg(0, child_arg);
142 }
143
144 let scheduler = get_scheduler();
145 let cpu_id = get_cpu().get_cpuid();
146 let parent_id = parent_task.get_id();
147
148 if clone_flags.is_set(CloneFlagsDef::SetTls) {
150 unsafe {
153 if let Some(abi) = child_task.default_abi.get_mut().as_mut() {
154 abi.set_tls_pointer(tls_ptr);
155 }
156 }
157
158 child_task.vcpu.lock().set_tls_pointer(tls_ptr);
160 }
161
162 let child_id = scheduler.add_task(child_task, cpu_id);
164 if let Some(child) = scheduler.get_task_by_id(child_id) {
168 child.set_parent_id(parent_id);
169 }
170 if let Some(parent) = scheduler.get_task_by_id(parent_id) {
171 parent.add_child(child_id);
172 }
173
174 let child_ns_pid = scheduler
176 .get_task_by_id(child_id)
177 .map(|t| t.get_namespace_id())
178 .unwrap_or(0);
179
180 child_ns_pid
182 }
183 Err(_) => {
184 usize::MAX }
186 }
187}
188
189pub fn sys_set_tls(trapframe: &mut Trapframe) -> usize {
191 let task = mytask().unwrap();
192 let tls_ptr = trapframe.get_arg(0);
193
194 unsafe {
197 if let Some(abi) = task.default_abi.get_mut().as_mut() {
198 abi.set_tls_pointer(tls_ptr);
199 }
200 }
201
202 task.vcpu.lock().set_tls_pointer(tls_ptr);
204
205 trapframe.increment_pc_next(task);
206 0 }
208
209pub fn sys_get_tls(trapframe: &mut Trapframe) -> usize {
211 let task = mytask().unwrap();
212
213 let tls_ptr = unsafe {
216 task.default_abi
217 .get()
218 .as_ref()
219 .and_then(|abi| abi.get_tls_pointer())
220 .unwrap_or(0)
221 };
222
223 trapframe.increment_pc_next(task);
224 tls_ptr }
226
227pub fn sys_set_tid_address(trapframe: &mut Trapframe) -> usize {
229 let task = mytask().unwrap();
230 let tid_ptr = trapframe.get_arg(0);
231
232 unsafe {
235 if let Some(abi) = task.default_abi.get_mut().as_mut() {
236 abi.set_clear_child_tid(tid_ptr);
237 }
238 }
239
240 trapframe.increment_pc_next(task);
241 task.get_namespace_id() }
243
244pub fn sys_execve(trapframe: &mut Trapframe) -> usize {
245 let task = mytask().unwrap();
246
247 trapframe.increment_pc_next(task);
251
252 let path_ptr = trapframe.get_arg(0);
254 let argv_ptr = trapframe.get_arg(1);
255 let envp_ptr = trapframe.get_arg(2);
256 let flags = trapframe.get_arg(3); let path_str = match parse_c_string_from_userspace(task, path_ptr, MAX_PATH_LENGTH) {
260 Ok(path) => {
261 path
263 }
264 Err(_) => {
265 return usize::MAX; }
268 };
269
270 let argv_strings =
272 match parse_string_array_from_userspace(task, argv_ptr, MAX_ARG_COUNT, MAX_PATH_LENGTH) {
273 Ok(args) => {
274 args
276 }
277 Err(_) => {
278 return usize::MAX; }
281 };
282
283 let envp_strings =
284 match parse_string_array_from_userspace(task, envp_ptr, MAX_ARG_COUNT, MAX_PATH_LENGTH) {
285 Ok(env) => {
286 env
288 }
289 Err(_) => {
290 return usize::MAX; }
293 };
294
295 let argv_refs: Vec<&str> = argv_strings.iter().map(|s| s.as_str()).collect();
297 let envp_refs: Vec<&str> = envp_strings.iter().map(|s| s.as_str()).collect();
298
299 let force_abi_rebuild = (flags & EXECVE_FORCE_ABI_REBUILD) != 0;
301
302 match TransparentExecutor::execute_binary(
306 &path_str,
307 &argv_refs,
308 &envp_refs,
309 task,
310 trapframe,
311 force_abi_rebuild,
312 ) {
313 Ok(_) => {
314 trapframe.get_return_value()
319 }
320 Err(e) => {
321 crate::println!(
322 "[EXECVE] Task {}: execute_binary failed for path='{}': {}",
323 task.get_id(),
324 path_str,
325 e
326 );
327 usize::MAX }
331 }
332}
333
334pub fn sys_execve_abi(trapframe: &mut Trapframe) -> usize {
335 let task = mytask().unwrap();
336
337 trapframe.increment_pc_next(task);
339
340 let path_ptr = trapframe.get_arg(0);
342 let argv_ptr = trapframe.get_arg(1);
343 let envp_ptr = trapframe.get_arg(2);
344 let abi_str_ptr = trapframe.get_arg(3);
345 let flags = trapframe.get_arg(4); let path_str = match parse_c_string_from_userspace(task, path_ptr, MAX_PATH_LENGTH) {
349 Ok(path) => path,
350 Err(_) => return usize::MAX, };
352
353 let abi_str = match parse_c_string_from_userspace(task, abi_str_ptr, MAX_ABI_LENGTH) {
355 Ok(abi) => abi,
356 Err(_) => return usize::MAX, };
358
359 let argv_strings = match parse_string_array_from_userspace(task, argv_ptr, 256, MAX_PATH_LENGTH)
361 {
362 Ok(args) => args,
363 Err(_) => return usize::MAX, };
365
366 let envp_strings = match parse_string_array_from_userspace(task, envp_ptr, 256, MAX_PATH_LENGTH)
367 {
368 Ok(env) => env,
369 Err(_) => return usize::MAX, };
371
372 let argv_refs: Vec<&str> = argv_strings.iter().map(|s| s.as_str()).collect();
374 let envp_refs: Vec<&str> = envp_strings.iter().map(|s| s.as_str()).collect();
375
376 let force_abi_rebuild = (flags & EXECVE_FORCE_ABI_REBUILD) != 0;
378
379 match TransparentExecutor::execute_with_abi(
381 &path_str,
382 &argv_refs,
383 &envp_refs,
384 &abi_str,
385 task,
386 trapframe,
387 force_abi_rebuild,
388 ) {
389 Ok(()) => {
390 trapframe.get_return_value()
394 }
395 Err(_) => {
396 usize::MAX }
400 }
401}
402
403pub fn sys_waitpid(trapframe: &mut Trapframe) -> usize {
404 let task = mytask().unwrap();
405 let pid = trapframe.get_arg(0) as i32;
407 let status_ptr = trapframe.get_arg(1) as *mut i32;
408 let options = trapframe.get_arg(2) as i32;
409
410 let wnohang = (options & 0x1) != 0;
412
413 loop {
415 if pid == -1 {
416 for child_pid in task.get_children().clone() {
418 match task.wait(child_pid) {
419 Ok(status) => {
420 if status_ptr != core::ptr::null_mut() {
422 let status_ptr = task
423 .vm_manager
424 .translate_vaddr(status_ptr as usize)
425 .unwrap() as *mut i32;
426 unsafe {
427 *status_ptr = status;
428 }
429 }
430 trapframe.increment_pc_next(task);
431 if let Some(local) = task.get_namespace().resolve_local_id(child_pid) {
433 return local;
434 }
435 continue;
437 }
438 Err(error) => match error {
439 WaitError::ChildNotExited(_) => continue,
440 _ => {
441 trapframe.increment_pc_next(task);
442 return usize::MAX;
443 }
444 },
445 }
446 }
447
448 if wnohang {
450 trapframe.increment_pc_next(task);
452 return 0; }
454
455 let parent_waker = get_parent_waitpid_waker(task.get_id());
457 parent_waker.wait(task.get_id(), trapframe);
458 continue;
460 }
461
462 if pid <= 0 {
464 trapframe.increment_pc_next(task);
465 return usize::MAX;
466 }
467
468 let target_global = match task.get_namespace().resolve_global_id(pid as usize) {
469 Some(g) => g,
470 None => {
471 trapframe.increment_pc_next(task);
472 return usize::MAX;
473 }
474 };
475
476 match task.wait(target_global) {
477 Ok(status) => {
478 if status_ptr != core::ptr::null_mut() {
480 let status_ptr = task
481 .vm_manager
482 .translate_vaddr(status_ptr as usize)
483 .unwrap() as *mut i32;
484 unsafe {
485 *status_ptr = status;
486 }
487 }
488 trapframe.increment_pc_next(task);
489 return pid as usize;
490 }
491 Err(error) => {
492 match error {
493 WaitError::NoSuchChild(_) => {
494 trapframe.increment_pc_next(task);
495 return usize::MAX;
496 }
497 WaitError::ChildTaskNotFound(_) => {
498 trapframe.increment_pc_next(task);
499 crate::print!("Child task with PID {} not found", pid);
500 return usize::MAX;
501 }
502 WaitError::ChildNotExited(_) => {
503 if wnohang {
505 trapframe.increment_pc_next(task);
507 return 0; }
509
510 let child_waker = get_waitpid_waker(target_global);
512 child_waker.wait(task.get_id(), trapframe);
513 assert_eq!(mytask().unwrap().get_id(), task.get_id());
514 continue;
516 }
517 }
518 }
519 }
520 }
521}
522
523pub fn sys_getpid(trapframe: &mut Trapframe) -> usize {
524 let task = mytask().unwrap();
525 trapframe.increment_pc_next(task);
526 task.get_namespace_id() as usize
529}
530
531pub fn sys_getppid(trapframe: &mut Trapframe) -> usize {
532 let task = mytask().unwrap();
533 trapframe.increment_pc_next(task);
534 match task.get_parent_id() {
537 Some(parent_global) => task
538 .get_namespace()
539 .resolve_local_id(parent_global)
540 .unwrap_or(0),
541 None => 0,
542 }
543}
544
545pub fn sys_sleep(trapframe: &mut Trapframe) -> usize {
546 let nanosecs = trapframe.get_arg(0) as u64;
547 let task = mytask().unwrap();
548
549 let ticks = ns_to_ticks(nanosecs);
550
551 trapframe.increment_pc_next(task);
553
554 task.sleep(trapframe, ticks);
556
557 0
559}
560
561pub fn sys_yield(trapframe: &mut Trapframe) -> usize {
569 let task = mytask().unwrap();
570
571 trapframe.increment_pc_next(task);
573
574 get_scheduler().schedule(trapframe);
576
577 0
578}
579
580pub fn sys_exit_group(trapframe: &mut Trapframe) -> usize {
598 let task = mytask().unwrap();
599 task.vcpu.lock().store(trapframe);
600 let exit_code = trapframe.get_arg(0) as i32;
601 task.exit_group(exit_code);
602 usize::MAX }
604
605pub fn sys_register_abi_zone(trapframe: &mut Trapframe) -> usize {
616 let task = mytask().unwrap();
617 let start = trapframe.get_arg(0);
618 let len = trapframe.get_arg(1);
619 let abi_name_ptr = trapframe.get_arg(2);
620
621 trapframe.increment_pc_next(task);
622
623 let abi_name = match parse_c_string_from_userspace(task, abi_name_ptr, MAX_ABI_LENGTH) {
625 Ok(name) => name,
626 Err(_) => {
627 crate::early_println!("[syscall] Failed to parse ABI name from user space");
628 return usize::MAX; }
630 };
631
632 crate::early_println!(
633 "[syscall] Registering ABI zone: start={:#x}, len={:#x}, abi={}",
634 start,
635 len,
636 abi_name
637 );
638
639 let abi = match crate::abi::AbiRegistry::instantiate(&abi_name) {
641 Some(abi) => abi,
642 None => {
643 crate::early_println!("[syscall] ABI '{}' not found in registry", abi_name);
644 return usize::MAX; }
646 };
647
648 let zone = crate::task::AbiZone {
650 range: start..(start + len),
651 abi,
652 };
653
654 unsafe {
657 task.abi_zones.get_mut().insert(start, zone);
658 }
659
660 crate::early_println!("[syscall] Successfully registered ABI zone");
661 0
662}
663
664pub fn sys_unregister_abi_zone(trapframe: &mut Trapframe) -> usize {
673 let task = mytask().unwrap();
674 let start = trapframe.get_arg(0);
675
676 trapframe.increment_pc_next(task);
677
678 crate::early_println!("[syscall] Unregistering ABI zone at start={:#x}", start);
679
680 let result = unsafe { task.abi_zones.get_mut().remove(&start) };
683 match result {
684 Some(_) => {
685 crate::early_println!("[syscall] Successfully unregistered ABI zone");
686 0
687 }
688 None => {
689 crate::early_println!("[syscall] ABI zone not found at start={:#x}", start);
690 usize::MAX }
692 }
693}
694
695pub const NS_CREATE_TASK: usize = 0x01; pub const NS_CREATE_VFS: usize = 0x02; pub const NS_CREATE_NET: usize = 0x04; pub const NS_CREATE_IPC: usize = 0x08; const SYSCALL_ERROR: usize = usize::MAX;
703
704pub fn sys_create_namespace(trapframe: &mut Trapframe) -> usize {
720 use crate::fs::VfsManager;
721 use crate::task::namespace::TaskNamespace;
722
723 let task = mytask().unwrap();
724 let flags = trapframe.get_arg(0);
725 let name_ptr = trapframe.get_arg(1);
726
727 trapframe.increment_pc_next(task);
728
729 let name = if name_ptr == 0 {
731 alloc::format!("ns_{}", task.get_id())
732 } else {
733 match parse_c_string_from_userspace(task, name_ptr, 64) {
734 Ok(s) => s,
735 Err(_) => {
736 crate::early_println!("[syscall] Failed to parse namespace name");
737 return SYSCALL_ERROR;
738 }
739 }
740 };
741
742 crate::early_println!(
743 "[syscall] Creating namespace '{}' with flags={:#x}",
744 name,
745 flags
746 );
747
748 if flags & NS_CREATE_TASK != 0 {
750 let new_task_ns = TaskNamespace::new_child(task.get_namespace().clone(), name.clone());
751 task.set_namespace(new_task_ns);
752 crate::early_println!("[syscall] Created task namespace '{}'", name);
753 }
754
755 if flags & NS_CREATE_VFS != 0 {
757 let source_vfs = match task.get_vfs() {
760 Some(vfs) => vfs,
761 None => return SYSCALL_ERROR,
762 };
763
764 let new_vfs = match VfsManager::clone_mount_namespace_deep(&source_vfs) {
765 Ok(vfs) => vfs,
766 Err(e) => {
767 crate::early_println!(
768 "[syscall] Failed to clone VFS namespace '{}': {}",
769 name,
770 e.message
771 );
772 return SYSCALL_ERROR;
773 }
774 };
775
776 let cwd_path = source_vfs.get_cwd_path();
778 let _ = new_vfs.set_cwd_by_path(&cwd_path);
779
780 task.set_vfs(new_vfs);
781 crate::early_println!("[syscall] Created VFS namespace '{}'", name);
782 }
783
784 if flags & NS_CREATE_NET != 0 {
786 crate::early_println!("[syscall] Network namespace not yet implemented");
787 }
788
789 if flags & NS_CREATE_IPC != 0 {
791 crate::early_println!("[syscall] IPC namespace not yet implemented");
792 }
793
794 0
795}