diff --git a/kernel/syscall/fs.rs b/kernel/syscall/fs.rs index 91c36e4..1552f25 100644 --- a/kernel/syscall/fs.rs +++ b/kernel/syscall/fs.rs @@ -2,9 +2,45 @@ use context; use scheme; -use syscall::data::Stat; +use syscall::data::{Packet, Stat}; use syscall::error::*; +pub fn file_op(a: usize, fd: usize, c: usize, d: usize) -> Result { + let file = { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + let file = context.get_file(fd).ok_or(Error::new(EBADF))?; + file + }; + + let scheme = { + let schemes = scheme::schemes(); + let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; + scheme.clone() + }; + + let mut packet = Packet { + id: 0, + a: a, + b: file.number, + c: c, + d: d + }; + + scheme.handle(&mut packet); + + Error::demux(packet.a) +} + +pub fn file_op_slice(a: usize, fd: usize, slice: &[u8]) -> Result { + file_op(a, fd, slice.as_ptr() as usize, slice.len()) +} + +pub fn file_op_mut_slice(a: usize, fd: usize, slice: &mut [u8]) -> Result { + file_op(a, fd, slice.as_mut_ptr() as usize, slice.len()) +} + /// Change the current working directory pub fn chdir(path: &[u8]) -> Result { let contexts = context::contexts(); @@ -92,12 +128,22 @@ pub fn dup(fd: usize) -> Result { file }; - let scheme = { - let schemes = scheme::schemes(); - let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; - scheme.clone() - }; - scheme.dup(file.number) + let file_id = { + let scheme = { + let schemes = scheme::schemes(); + let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; + scheme.clone() + }; + scheme.dup(file.number) + }?; + + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + context.add_file(::context::file::File { + scheme: file.scheme, + number: file_id + }).ok_or(Error::new(EMFILE)) } /// Register events for file @@ -119,129 +165,3 @@ pub fn fevent(fd: usize, flags: usize) -> Result { context::event::register(fd, file.scheme, file.number); Ok(0) } - -/// Get the canonical path of the file -pub fn fpath(fd: usize, buf: &mut [u8]) -> Result { - let file = { - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - let file = context.get_file(fd).ok_or(Error::new(EBADF))?; - file - }; - - let scheme = { - let schemes = scheme::schemes(); - let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; - scheme.clone() - }; - scheme.fpath(file.number, buf) -} - -/// Get information about the file -pub fn fstat(fd: usize, stat: &mut Stat) -> Result { - let file = { - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - let file = context.get_file(fd).ok_or(Error::new(EBADF))?; - file - }; - - let scheme = { - let schemes = scheme::schemes(); - let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; - scheme.clone() - }; - scheme.fstat(file.number, stat) -} - -/// Sync the file descriptor -pub fn fsync(fd: usize) -> Result { - let file = { - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - let file = context.get_file(fd).ok_or(Error::new(EBADF))?; - file - }; - - let scheme = { - let schemes = scheme::schemes(); - let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; - scheme.clone() - }; - scheme.fsync(file.number) -} - -/// Truncate the file descriptor -pub fn ftruncate(fd: usize, len: usize) -> Result { - let file = { - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - let file = context.get_file(fd).ok_or(Error::new(EBADF))?; - file - }; - - let scheme = { - let schemes = scheme::schemes(); - let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; - scheme.clone() - }; - scheme.ftruncate(file.number, len) -} - -/// Seek to an offset -pub fn lseek(fd: usize, pos: usize, whence: usize) -> Result { - let file = { - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - let file = context.get_file(fd).ok_or(Error::new(EBADF))?; - file - }; - - let scheme = { - let schemes = scheme::schemes(); - let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; - scheme.clone() - }; - scheme.seek(file.number, pos, whence) -} - -/// Read syscall -pub fn read(fd: usize, buf: &mut [u8]) -> Result { - let file = { - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - let file = context.get_file(fd).ok_or(Error::new(EBADF))?; - file - }; - - let scheme = { - let schemes = scheme::schemes(); - let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; - scheme.clone() - }; - scheme.read(file.number, buf) -} - -/// Write syscall -pub fn write(fd: usize, buf: &[u8]) -> Result { - let file = { - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - let file = context.get_file(fd).ok_or(Error::new(EBADF))?; - file - }; - - let scheme = { - let schemes = scheme::schemes(); - let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; - scheme.clone() - }; - scheme.write(file.number, buf) -} diff --git a/kernel/syscall/mod.rs b/kernel/syscall/mod.rs index 1bb5a56..3edecf9 100644 --- a/kernel/syscall/mod.rs +++ b/kernel/syscall/mod.rs @@ -8,7 +8,6 @@ pub use self::fs::*; pub use self::process::*; pub use self::validate::*; -use self::data::Stat; use self::error::{Error, Result, ENOSYS}; use self::number::*; @@ -25,33 +24,35 @@ pub mod validate; pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack: usize) -> usize { #[inline(always)] fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize, stack: usize) -> Result { - match a { - SYS_EXIT => exit(b), - SYS_READ => read(b, validate_slice_mut(c as *mut u8, d)?), - SYS_WRITE => write(b, validate_slice(c as *const u8, d)?), - SYS_OPEN => open(validate_slice(b as *const u8, c)?, d), - SYS_CLOSE => close(b), - SYS_WAITPID => waitpid(b, c, d), - SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?), - SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?), - SYS_LSEEK => lseek(b, c, d), - SYS_GETPID => getpid(), - SYS_FSTAT => fstat(b, &mut validate_slice_mut(c as *mut Stat, 1)?[0]), - SYS_DUP => dup(b), - SYS_BRK => brk(b), - SYS_FTRUNCATE => ftruncate(b, c), - SYS_IOPL => iopl(b), - SYS_FSYNC => fsync(b), - SYS_CLONE => clone(b, stack), - SYS_YIELD => sched_yield(), - SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?), - SYS_FEVENT => fevent(b, c), - SYS_FPATH => fpath(b, validate_slice_mut(c as *mut u8, d)?), - SYS_PHYSMAP => physmap(b, c, d), - SYS_PHYSUNMAP => physunmap(b), - _ => { - println!("Unknown syscall {}", a); - Err(Error::new(ENOSYS)) + match a & SYS_CLASS { + SYS_CLASS_FILE => match a & SYS_ARG { + SYS_ARG_SLICE => file_op_slice(a, b, validate_slice(c as *const u8, d)?), + SYS_ARG_MSLICE => file_op_mut_slice(a, b, validate_slice_mut(c as *mut u8, d)?), + _ => match a { + SYS_CLOSE => close(b), + SYS_DUP => dup(b), + SYS_FEVENT => fevent(b, c), + _ => file_op(a, b, c, d) + } + }, + SYS_CLASS_PATH => match a { + SYS_OPEN => open(validate_slice(b as *const u8, c)?, d), + _ => unreachable!() + }, + _ => match a { + SYS_EXIT => exit(b), + SYS_WAITPID => waitpid(b, c, d), + SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?), + SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?), + SYS_GETPID => getpid(), + SYS_BRK => brk(b), + SYS_IOPL => iopl(b), + SYS_CLONE => clone(b, stack), + SYS_YIELD => sched_yield(), + SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?), + SYS_PHYSMAP => physmap(b, c, d), + SYS_PHYSUNMAP => physunmap(b), + _ => Err(Error::new(ENOSYS)) } } } diff --git a/kernel/syscall/process.rs b/kernel/syscall/process.rs index 5150b95..4877503 100644 --- a/kernel/syscall/process.rs +++ b/kernel/syscall/process.rs @@ -395,7 +395,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result { let mut data = vec![]; loop { let mut buf = [0; 16384]; - let count = syscall::read(file, &mut buf)?; + let count = syscall::file_op_mut_slice(syscall::number::SYS_READ, file, &mut buf)?; if count > 0 { data.extend_from_slice(&buf[..count]); } else { diff --git a/syscall/src/lib.rs b/syscall/src/lib.rs index 2f4ea89..9e3968a 100644 --- a/syscall/src/lib.rs +++ b/syscall/src/lib.rs @@ -8,6 +8,8 @@ pub use self::flag::*; pub use self::number::*; pub use self::scheme::*; +use core::mem; + #[cfg(target_arch = "x86")] #[path="x86.rs"] mod arch; @@ -67,7 +69,7 @@ pub fn fpath(fd: usize, buf: &mut [u8]) -> Result { } pub fn fstat(fd: usize, stat: &mut Stat) -> Result { - unsafe { syscall2(SYS_FSTAT, fd, stat as *mut Stat as usize) } + unsafe { syscall3(SYS_FSTAT, fd, stat as *mut Stat as usize, mem::size_of::()) } } pub fn fsync(fd: usize) -> Result { diff --git a/syscall/src/number.rs b/syscall/src/number.rs index c0f341c..5378172 100644 --- a/syscall/src/number.rs +++ b/syscall/src/number.rs @@ -1,31 +1,45 @@ -pub const SYS_BRK: usize = 45; -pub const SYS_CHDIR: usize = 12; -pub const SYS_CLONE: usize = 120; -pub const SYS_CLOSE: usize = 6; -pub const SYS_CLOCK_GETTIME: usize = 265; -pub const SYS_DUP: usize = 41; -pub const SYS_EXECVE: usize = 11; -pub const SYS_EXIT: usize = 1; -pub const SYS_FEVENT: usize = 927; -pub const SYS_FPATH: usize = 928; -pub const SYS_FSTAT: usize = 28; -pub const SYS_FSYNC: usize = 118; -pub const SYS_FTRUNCATE: usize = 93; -pub const SYS_FUTEX: usize = 240; -pub const SYS_GETCWD: usize = 183; -pub const SYS_GETPID: usize = 20; -pub const SYS_IOPL: usize = 110; -pub const SYS_LINK: usize = 9; -pub const SYS_LSEEK: usize = 19; -pub const SYS_MKDIR: usize = 39; -pub const SYS_NANOSLEEP: usize = 162; -pub const SYS_OPEN: usize = 5; -pub const SYS_PHYSMAP: usize = 945; -pub const SYS_PHYSUNMAP: usize = 946; -pub const SYS_PIPE2: usize = 331; -pub const SYS_READ: usize = 3; -pub const SYS_RMDIR: usize = 84; -pub const SYS_UNLINK: usize = 10; -pub const SYS_WAITPID: usize = 7; -pub const SYS_WRITE: usize = 4; -pub const SYS_YIELD: usize = 158; +pub const SYS_CLASS: usize = 0xF000_0000; +pub const SYS_CLASS_PATH: usize=0x1000_0000; +pub const SYS_CLASS_FILE: usize=0x2000_0000; + +pub const SYS_ARG: usize = 0x0F00_0000; +pub const SYS_ARG_SLICE: usize =0x0100_0000; +pub const SYS_ARG_MSLICE: usize=0x0200_0000; +pub const SYS_ARG_PATH: usize = 0x0300_0000; + +pub const SYS_RET: usize = 0x00F0_0000; +pub const SYS_RET_FILE: usize = 0x0010_0000; + +pub const SYS_LINK: usize = SYS_CLASS_PATH | SYS_ARG_PATH | 9; +pub const SYS_OPEN: usize = SYS_CLASS_PATH | SYS_RET_FILE | 5; +pub const SYS_MKDIR: usize = SYS_CLASS_PATH | 39; +pub const SYS_RMDIR: usize = SYS_CLASS_PATH | 84; +pub const SYS_UNLINK: usize = SYS_CLASS_PATH | 10; + +pub const SYS_CLOSE: usize = SYS_CLASS_FILE | 6; +pub const SYS_DUP: usize = SYS_CLASS_FILE | SYS_RET_FILE | 41; +pub const SYS_READ: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 3; +pub const SYS_WRITE: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 4; +pub const SYS_FEVENT: usize = SYS_CLASS_FILE | 927; +pub const SYS_LSEEK: usize = SYS_CLASS_FILE | 19; +pub const SYS_FPATH: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 928; +pub const SYS_FSTAT: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 28; +pub const SYS_FSYNC: usize = SYS_CLASS_FILE | 118; +pub const SYS_FTRUNCATE: usize =SYS_CLASS_FILE | 93; + +pub const SYS_BRK: usize = 45; +pub const SYS_CHDIR: usize = 12; +pub const SYS_CLOCK_GETTIME: usize = 265; +pub const SYS_CLONE: usize = 120; +pub const SYS_EXECVE: usize = 11; +pub const SYS_EXIT: usize = 1; +pub const SYS_FUTEX: usize = 240; +pub const SYS_GETCWD: usize = 183; +pub const SYS_GETPID: usize = 20; +pub const SYS_IOPL: usize = 110; +pub const SYS_NANOSLEEP: usize =162; +pub const SYS_PHYSMAP: usize = 945; +pub const SYS_PHYSUNMAP: usize =946; +pub const SYS_PIPE2: usize = 331; +pub const SYS_WAITPID: usize = 7; +pub const SYS_YIELD: usize = 158;