redox/kernel/syscall/mod.rs

114 lines
3 KiB
Rust
Raw Normal View History

2016-08-14 23:58:35 +02:00
///! Syscall handlers
use core::slice;
pub use self::fs::*;
pub use self::process::*;
/// Filesystem syscalls
pub mod fs;
/// Process syscalls
pub mod process;
/// System call list
/// See http://syscalls.kernelgrok.com/ for numbers
2016-08-15 02:22:50 +02:00
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(C)]
2016-08-14 23:58:35 +02:00
pub enum Call {
/// Exit syscall
Exit = 1,
2016-08-14 23:58:35 +02:00
/// Read syscall
Read = 3,
2016-08-14 23:58:35 +02:00
/// Write syscall
Write = 4,
2016-08-14 23:58:35 +02:00
/// Open syscall
Open = 5,
2016-08-14 23:58:35 +02:00
/// Close syscall
Close = 6,
2016-08-15 00:07:41 +02:00
/// Execute syscall
Exec = 11,
2016-08-20 22:32:45 +02:00
/// Get process ID
GetPid = 20,
/// Yield to scheduler
SchedYield = 158
2016-08-14 23:58:35 +02:00
}
/// Convert numbers to calls
/// See http://syscalls.kernelgrok.com/
impl Call {
fn from(number: usize) -> Result<Call> {
2016-08-14 23:58:35 +02:00
match number {
1 => Ok(Call::Exit),
3 => Ok(Call::Read),
4 => Ok(Call::Write),
5 => Ok(Call::Open),
6 => Ok(Call::Close),
11 => Ok(Call::Exec),
2016-08-20 22:32:45 +02:00
20 => Ok(Call::GetPid),
158 => Ok(Call::SchedYield),
_ => Err(Error::NoCall)
2016-08-14 23:58:35 +02:00
}
}
}
/// The error number for an invalid value
/// See http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Errors/unix_system_errors.html for numbers
2016-08-15 02:22:50 +02:00
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(C)]
2016-08-14 23:58:35 +02:00
pub enum Error {
/// Operation not permitted
NotPermitted = 1,
2016-08-14 23:58:35 +02:00
/// No such file or directory
NoEntry = 2,
2016-08-18 16:30:45 +02:00
/// No such process
NoProcess = 3,
2016-08-15 02:16:56 +02:00
/// Bad file number
BadFile = 9,
/// Try again
TryAgain = 11,
/// File exists
FileExists = 17,
2016-08-14 23:58:35 +02:00
/// Invalid argument
InvalidValue = 22,
2016-08-15 02:16:56 +02:00
/// Too many open files
TooManyFiles = 24,
2016-08-14 23:58:35 +02:00
/// Syscall not implemented
NoCall = 38
2016-08-14 23:58:35 +02:00
}
pub type Result<T> = ::core::result::Result<T, Error>;
/// Convert a pointer and length to slice, if valid
/// TODO: Check validity
2016-08-15 00:07:41 +02:00
pub fn convert_slice<T>(ptr: *const T, len: usize) -> Result<&'static [T]> {
Ok(unsafe { slice::from_raw_parts(ptr, len) })
2016-08-14 23:58:35 +02:00
}
/// Convert a pointer and length to slice, if valid
/// TODO: Check validity
2016-08-15 00:07:41 +02:00
pub fn convert_slice_mut<T>(ptr: *mut T, len: usize) -> Result<&'static mut [T]> {
Ok(unsafe { slice::from_raw_parts_mut(ptr, len) })
2016-08-14 23:58:35 +02:00
}
pub fn handle(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize) -> Result<usize> {
match Call::from(a)? {
2016-08-14 23:58:35 +02:00
Call::Exit => exit(b),
2016-08-15 00:07:41 +02:00
Call::Read => read(b, convert_slice_mut(c as *mut u8, d)?),
Call::Write => write(b, convert_slice(c as *const u8, d)?),
Call::Open => open(convert_slice(b as *const u8, c)?, d),
2016-08-14 23:58:35 +02:00
Call::Close => close(b),
2016-08-20 22:32:45 +02:00
Call::Exec => exec(convert_slice(b as *const u8, c)?, convert_slice(d as *const [usize; 2], e)?),
Call::GetPid => getpid(),
Call::SchedYield => sched_yield()
}
2016-08-14 23:58:35 +02:00
}
#[no_mangle]
pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize {
match handle(a, b, c, d, e, f) {
Ok(value) => value,
Err(value) => !(value as usize)
}
}