mirror of https://github.com/vinc/moros.git
205 lines
5.4 KiB
Rust
205 lines
5.4 KiB
Rust
use crate::sys;
|
|
use crate::api::process::ExitCode;
|
|
use crate::api::fs::{FileIO, IO};
|
|
use crate::sys::fs::FileInfo;
|
|
use crate::sys::fs::Resource;
|
|
use crate::sys::fs::Device;
|
|
use crate::sys::process::Process;
|
|
|
|
use alloc::vec;
|
|
use core::arch::asm;
|
|
use smoltcp::wire::IpAddress;
|
|
|
|
pub fn exit(code: ExitCode) -> ExitCode {
|
|
//debug!("syscall::exit(code={})", code as usize);
|
|
sys::process::exit();
|
|
code
|
|
}
|
|
|
|
pub fn sleep(seconds: f64) {
|
|
sys::time::sleep(seconds);
|
|
}
|
|
|
|
pub fn delete(path: &str) -> isize {
|
|
if sys::fs::delete(path).is_ok() {
|
|
0
|
|
} else {
|
|
-1
|
|
}
|
|
}
|
|
|
|
pub fn info(path: &str, info: &mut FileInfo) -> isize {
|
|
let path = match sys::fs::canonicalize(path) {
|
|
Ok(path) => path,
|
|
Err(_) => return -1,
|
|
};
|
|
if let Some(res) = sys::fs::info(&path) {
|
|
*info = res;
|
|
0
|
|
} else {
|
|
-1
|
|
}
|
|
}
|
|
|
|
pub fn open(path: &str, flags: usize) -> isize {
|
|
let path = match sys::fs::canonicalize(path) {
|
|
Ok(path) => path,
|
|
Err(_) => return -1,
|
|
};
|
|
if let Some(resource) = sys::fs::open(&path, flags) {
|
|
if let Ok(handle) = sys::process::create_handle(resource) {
|
|
return handle as isize;
|
|
}
|
|
}
|
|
-1
|
|
}
|
|
|
|
pub fn dup(old_handle: usize, new_handle: usize) -> isize {
|
|
if let Some(file) = sys::process::handle(old_handle) {
|
|
sys::process::update_handle(new_handle, *file);
|
|
return new_handle as isize;
|
|
}
|
|
-1
|
|
}
|
|
|
|
pub fn read(handle: usize, buf: &mut [u8]) -> isize {
|
|
if let Some(mut file) = sys::process::handle(handle) {
|
|
if let Ok(bytes) = file.read(buf) {
|
|
sys::process::update_handle(handle, *file);
|
|
return bytes as isize;
|
|
}
|
|
}
|
|
-1
|
|
}
|
|
|
|
pub fn write(handle: usize, buf: &mut [u8]) -> isize {
|
|
if let Some(mut file) = sys::process::handle(handle) {
|
|
if let Ok(bytes) = file.write(buf) {
|
|
sys::process::update_handle(handle, *file);
|
|
return bytes as isize;
|
|
}
|
|
}
|
|
-1
|
|
}
|
|
|
|
pub fn close(handle: usize) {
|
|
if let Some(mut file) = sys::process::handle(handle) {
|
|
file.close();
|
|
sys::process::delete_handle(handle);
|
|
}
|
|
}
|
|
|
|
pub fn spawn(path: &str, args_ptr: usize, args_len: usize) -> ExitCode {
|
|
//debug!("syscall::spawn(path={}, args_ptr={:#X}, args_len={})", path, args_ptr, args_len);
|
|
let path = match sys::fs::canonicalize(path) {
|
|
Ok(path) => path,
|
|
Err(_) => return ExitCode::OpenError,
|
|
};
|
|
if let Some(mut file) = sys::fs::File::open(&path) {
|
|
let mut buf = vec![0; file.size()];
|
|
if let Ok(bytes) = file.read(&mut buf) {
|
|
buf.resize(bytes, 0);
|
|
if let Err(code) = Process::spawn(&buf, args_ptr, args_len) {
|
|
code
|
|
} else {
|
|
ExitCode::Success
|
|
}
|
|
} else {
|
|
ExitCode::ReadError
|
|
}
|
|
} else {
|
|
ExitCode::OpenError
|
|
}
|
|
}
|
|
|
|
pub fn stop(code: usize) -> usize {
|
|
match code {
|
|
0xCAFE => { // Reboot
|
|
unsafe {
|
|
asm!(
|
|
"xor rax, rax",
|
|
"mov cr3, rax"
|
|
);
|
|
}
|
|
}
|
|
0xDEAD => { // Halt
|
|
sys::process::exit();
|
|
sys::acpi::shutdown();
|
|
}
|
|
_ => {
|
|
debug!("STOP SYSCALL: Invalid code '{:#X}' received", code);
|
|
}
|
|
}
|
|
0
|
|
}
|
|
|
|
pub fn poll(list: &[(usize, IO)]) -> isize {
|
|
for (i, (handle, event)) in list.iter().enumerate() {
|
|
if let Some(mut file) = sys::process::handle(*handle) {
|
|
if file.poll(*event) {
|
|
return i as isize;
|
|
}
|
|
}
|
|
}
|
|
-1
|
|
}
|
|
|
|
pub fn connect(handle: usize, addr: IpAddress, port: u16) -> isize {
|
|
if let Some(mut file) = sys::process::handle(handle) {
|
|
let res = match *file {
|
|
Resource::Device(Device::TcpSocket(ref mut dev)) => dev.connect(addr, port),
|
|
Resource::Device(Device::UdpSocket(ref mut dev)) => dev.connect(addr, port),
|
|
_ => Err(()),
|
|
};
|
|
if res.is_ok() {
|
|
sys::process::update_handle(handle, *file);
|
|
return 0;
|
|
}
|
|
}
|
|
-1
|
|
}
|
|
|
|
pub fn listen(handle: usize, port: u16) -> isize {
|
|
if let Some(file) = sys::process::handle(handle) {
|
|
let res = match *file {
|
|
Resource::Device(Device::TcpSocket(mut dev)) => dev.listen(port),
|
|
Resource::Device(Device::UdpSocket(mut dev)) => dev.listen(port),
|
|
_ => Err(()),
|
|
};
|
|
if res.is_ok() {
|
|
return 0;
|
|
}
|
|
}
|
|
-1
|
|
}
|
|
|
|
pub fn accept(handle: usize) -> Result<IpAddress, ()> {
|
|
if let Some(file) = sys::process::handle(handle) {
|
|
return match *file {
|
|
Resource::Device(Device::TcpSocket(mut dev)) => dev.accept(),
|
|
Resource::Device(Device::UdpSocket(mut dev)) => dev.accept(),
|
|
_ => Err(()),
|
|
};
|
|
}
|
|
Err(())
|
|
}
|
|
|
|
use core::alloc::Layout;
|
|
|
|
pub fn alloc(size: usize, align: usize) -> *mut u8 {
|
|
if let Ok(layout) = Layout::from_size_align(size, align) {
|
|
let ptr = unsafe { sys::process::alloc(layout) };
|
|
//debug!("syscall::alloc(size={}, align={}) -> ptr={:?}", size, align, ptr);
|
|
ptr
|
|
} else {
|
|
core::ptr::null_mut()
|
|
}
|
|
}
|
|
|
|
pub fn free(ptr: *mut u8, size: usize, align: usize) {
|
|
if let Ok(layout) = Layout::from_size_align(size, align) {
|
|
//debug!("syscall::free(ptr={:?}, size={}, align={})", ptr, size, align);
|
|
unsafe { sys::process::free(ptr, layout) };
|
|
}
|
|
}
|