1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
use alloc::arc::Arc; use arch::vga_bochs; use console::Console; use io::{Read,Write}; use logging::Writer; use prelude::*; use process::{self,KObj,SharedMemBlock}; use singleton::{DropSingleton,Singleton}; use syscall::{self,ErrNum,Handle,HandleSyscall,PackedArgs,Result}; use thread; pub struct SyscallHandler { console: Arc<Console> } static HANDLER: Singleton<SyscallHandler> = Singleton::new(); pub type DropSyscallHandler = DropSingleton<SyscallHandler>; pub fn register_handler(handler: SyscallHandler) -> DropSyscallHandler { HANDLER.register(handler) } pub fn dispatch(num: usize, args: PackedArgs) -> isize { if let Some(handler) = HANDLER.get() { syscall::dispatch(handler, &mut Writer, num, args) } else { 0 } } impl SyscallHandler { pub fn new(console: Arc<Console>) -> Self { SyscallHandler { console: console } } } impl HandleSyscall for SyscallHandler { fn exit_thread(&self, code: i32) -> Result<()> { thread::exit(code) } fn write(&self, file: Handle, bytes: &[u8]) -> Result<usize> { let file = try!(process::resolve_handle(file, |kobj| kobj.write())); file.write(bytes) } fn read(&self, file: Handle, buf: &mut [u8]) -> Result<usize> { let file = try!(process::resolve_handle(file, |kobj| kobj.read())); file.read(buf) } fn alloc_pages(&self, len: usize) -> Result<*mut u8> { match process::alloc(len, true, true) { Ok(slice) => Ok(slice.as_mut_ptr()), Err(_) => Err(ErrNum::OutOfMemory) } } fn free_pages(&self, p: *mut u8) -> Result<bool> { Ok(process::free(p)) } fn open(&self, filename: &str) -> Result<Handle> { let file: Arc<KObj> = match filename { "stdin" => self.console.clone(), "stdout" => self.console.clone(), _ => { return Err(ErrNum::FileNotFound) } }; Ok(process::make_handle(file)) } fn close(&self, handle: Handle) -> Result<()> { if !process::close_handle(handle) { return Err(ErrNum::InvalidHandle) } Ok(()) } fn init_video_mode(&self, width: u16, height: u16, bpp: u8) -> Result<*mut u8> { let slice = try!(vga_bochs::init(width, height, bpp)); Ok(slice.as_mut_ptr()) } fn spawn(&self, executable: &str, inherit: &[Handle]) -> Result<Handle> { let inherit = inherit.iter().map(|handle| *handle); let (_, deferred) = try!(process::spawn(String::from(executable), inherit)); Ok(process::make_handle(Arc::new(deferred))) } fn wait_for_exit(&self, process: Handle) -> Result<i32> { let deferred = try!(process::resolve_handle(process, |kobj| kobj.deferred_i32())); Ok((*deferred).clone().get()) } fn create_shared_mem(&self) -> Result<Handle> { Ok(process::make_handle(Arc::new(SharedMemBlock::new()))) } fn map_shared_mem(&self, block: Handle, len: usize, writable: bool) -> Result<*mut u8> { let block = try!(process::resolve_handle(block, |kobj| kobj.shared_mem_block())); let slice = try!(process::map_shared(block, len, true, writable)); Ok(slice.as_mut_ptr()) } }