use alloc::vec::Vec;
use ax_io::Read;
use crate::{
StarryError,
file::get_file_like,
mm::{VmBytes, vm_load_string},
};
fn require_module_privilege(current: &crate::task::UserTaskRef) -> crate::StarryResult<()> {
if current.as_thread().cred().has_cap_sys_module() {
Ok(())
} else {
Err(StarryError::OperationNotPermitted)
}
}
fn allocate_module_image(len: usize) -> crate::StarryResult<Vec<u8>> {
let mut module_image = Vec::new();
module_image
.try_reserve_exact(len)
.map_err(|_| StarryError::NoMemory)?;
module_image.resize(len, 0);
Ok(module_image)
}
pub fn sys_init_module(
current: &crate::task::UserTaskRef,
module_ptr: *const u8,
len: usize,
param_ptr: *const u8,
) -> crate::StarryResult<isize> {
require_module_privilege(current)?;
let mut module_buf = VmBytes::new(current, module_ptr as *mut u8, len);
let mut module_data = allocate_module_image(len)?;
module_buf.read(&mut module_data)?;
let param_buf = if !param_ptr.is_null() {
Some(vm_load_string(current, param_ptr as _)?)
} else {
None
};
warn!(
"[sys_init_module]: module_len={}, params={:?}",
len, param_buf
);
crate::kmod::init_module(&module_data, param_buf.as_deref())?;
Ok(0)
}
pub fn sys_finit_module(
current: &crate::task::UserTaskRef,
module_fd: i32,
param_ptr: *const u8,
flags: u32,
) -> crate::StarryResult<isize> {
require_module_privilege(current)?;
if flags != 0 {
return Err(StarryError::InvalidInput);
}
let file = get_file_like(module_fd)?;
let fsize = file.stat()?.size as usize;
let mut module_data = allocate_module_image(fsize)?;
let mut offset = 0;
while offset < fsize {
let mut buf: &mut [u8] = &mut module_data[offset..];
let n = file.read(&mut buf)?;
if n == 0 {
return Err(StarryError::UnexpectedEof);
}
offset += n;
}
let param_buf = if !param_ptr.is_null() {
Some(vm_load_string(current, param_ptr as _)?)
} else {
None
};
warn!(
"[sys_finit_module]: module_len={}, params={:?}",
module_data.len(),
param_buf
);
crate::kmod::init_module(&module_data, param_buf.as_deref())?;
Ok(0)
}
pub fn sys_delete_module(
current: &crate::task::UserTaskRef,
name_ptr: *const u8,
_flags: u32,
) -> crate::StarryResult<isize> {
require_module_privilege(current)?;
let name = vm_load_string(current, name_ptr as _)?;
warn!("[sys_delete_module]: name={}", name);
crate::kmod::delete_module(&name)?;
Ok(0)
}