use ax_errno::{AxError, AxResult};
use ax_task::current;
use crate::task::AsThread;
pub fn sys_getpid() -> AxResult<isize> {
let curr = current();
let thr = curr.as_thread();
let global_pid = thr.proc_data.proc.pid() as u64;
let nsproxy = thr.proc_data.nsproxy.lock();
let local = nsproxy.pid_ns.lock().local_pid(global_pid);
drop(nsproxy);
if let Some(local) = local {
Ok(local as isize)
} else {
Ok(global_pid as isize)
}
}
pub fn sys_getppid() -> AxResult<isize> {
let curr = current();
let thr = curr.as_thread();
let parent = thr.proc_data.proc.parent().ok_or(AxError::NoSuchProcess)?;
let parent_global_pid = parent.pid() as u64;
let nsproxy = thr.proc_data.nsproxy.lock();
match nsproxy.pid_ns.lock().local_pid(parent_global_pid) {
Some(local) => Ok(local as isize),
None => Ok(0),
}
}
pub fn sys_gettid() -> AxResult<isize> {
Ok(current().as_thread().tid() as _)
}
pub fn sys_getcpu(cpu: *mut u32, node: *mut u32, _tcache: usize) -> AxResult<isize> {
use ax_runtime::hal::percpu::this_cpu_id;
use starry_vm::VmMutPtr;
if !cpu.is_null() {
cpu.vm_write(this_cpu_id() as u32)?;
}
if !node.is_null() {
node.vm_write(0)?;
}
Ok(0)
}
#[cfg(target_arch = "x86_64")]
#[derive(Debug, Eq, PartialEq, num_enum::TryFromPrimitive)]
#[repr(i32)]
enum ArchPrctlCode {
SetGs = 0x1001,
SetFs = 0x1002,
GetFs = 0x1003,
GetGs = 0x1004,
GetCpuid = 0x1011,
SetCpuid = 0x1012,
}
pub fn sys_set_tid_address(clear_child_tid: usize) -> AxResult<isize> {
let curr = current();
let thr = curr.as_thread();
thr.set_clear_child_tid(clear_child_tid);
Ok(thr.tid() as isize)
}
#[cfg(target_arch = "x86_64")]
pub fn sys_arch_prctl(
uctx: &mut ax_runtime::hal::cpu::uspace::UserContext,
code: i32,
addr: usize,
) -> AxResult<isize> {
use starry_vm::VmMutPtr;
let code = ArchPrctlCode::try_from(code).map_err(|_| AxError::InvalidInput)?;
debug!("sys_arch_prctl: code = {code:?}, addr = {addr:#x}");
match code {
ArchPrctlCode::GetFs => {
(addr as *mut usize).vm_write(uctx.tls())?;
Ok(0)
}
ArchPrctlCode::SetFs => {
uctx.set_tls(addr);
Ok(0)
}
ArchPrctlCode::GetGs => {
(addr as *mut usize).vm_write(uctx.gs_base as _)?;
Ok(0)
}
ArchPrctlCode::SetGs => {
uctx.gs_base = addr as _;
Ok(0)
}
ArchPrctlCode::GetCpuid => Ok(0),
ArchPrctlCode::SetCpuid => Err(ax_errno::AxError::NoSuchDevice),
}
}