extern crate alloc;
use alloc::string::String;
use alloc::sync::Arc;
use axhal::{
arch::{flush_tlb, write_page_table_root},
KERNEL_PROCESS_ID,
};
use axprocess::{yield_now_task, PID2PC};
use axruntime::KERNEL_PAGE_TABLE;
use axtask::{TaskId, EXITED_TASKS};
use axerrno::AxResult;
use axfs::api::{File, OpenFlags};
pub fn new_file(path: &str, flags: &OpenFlags) -> AxResult<File> {
let mut file = File::options();
file.read(flags.readable());
file.write(flags.writable());
file.create(flags.creatable());
file.create_new(flags.new_creatable());
file.open(path)
}
pub fn init_current_dir() {
axfs::api::set_current_dir("/").expect("reset current dir failed");
}
pub type FileFlags = OpenFlags;
pub fn recycle_user_process() {
let kernel_process = Arc::clone(PID2PC.lock().get(&KERNEL_PROCESS_ID).unwrap());
loop {
let pid2pc = PID2PC.lock();
kernel_process
.children
.lock()
.retain(|x| x.pid() == KERNEL_PROCESS_ID || pid2pc.contains_key(&x.pid()));
let all_finished = pid2pc.len() == 1;
drop(pid2pc);
if all_finished {
break;
}
yield_now_task();
}
TaskId::clear();
unsafe {
write_page_table_root(KERNEL_PAGE_TABLE.root_paddr());
flush_tlb(None);
};
EXITED_TASKS.lock().clear();
init_current_dir();
}
pub fn println(s: &str) {
axlog::ax_println!("{}", s);
}
pub fn read_file(path: &str) -> Option<String> {
axfs::api::read_to_string(path).ok()
}
pub fn write<C: AsRef<[u8]>>(path: &str, contents: C) -> Option<()> {
axfs::api::write(path, contents).ok()
}
pub fn create_dir(path: &str) -> Option<()> {
axfs::api::create_dir(path).ok()
}