Encode many of the file syscalls
This commit is contained in:
parent
0e8487cf83
commit
549fe53bc3
|
@ -2,9 +2,45 @@
|
||||||
|
|
||||||
use context;
|
use context;
|
||||||
use scheme;
|
use scheme;
|
||||||
use syscall::data::Stat;
|
use syscall::data::{Packet, Stat};
|
||||||
use syscall::error::*;
|
use syscall::error::*;
|
||||||
|
|
||||||
|
pub fn file_op(a: usize, fd: usize, c: usize, d: usize) -> Result<usize> {
|
||||||
|
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<usize> {
|
||||||
|
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<usize> {
|
||||||
|
file_op(a, fd, slice.as_mut_ptr() as usize, slice.len())
|
||||||
|
}
|
||||||
|
|
||||||
/// Change the current working directory
|
/// Change the current working directory
|
||||||
pub fn chdir(path: &[u8]) -> Result<usize> {
|
pub fn chdir(path: &[u8]) -> Result<usize> {
|
||||||
let contexts = context::contexts();
|
let contexts = context::contexts();
|
||||||
|
@ -92,12 +128,22 @@ pub fn dup(fd: usize) -> Result<usize> {
|
||||||
file
|
file
|
||||||
};
|
};
|
||||||
|
|
||||||
let scheme = {
|
let file_id = {
|
||||||
let schemes = scheme::schemes();
|
let scheme = {
|
||||||
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
|
let schemes = scheme::schemes();
|
||||||
scheme.clone()
|
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
|
||||||
};
|
scheme.clone()
|
||||||
scheme.dup(file.number)
|
};
|
||||||
|
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
|
/// Register events for file
|
||||||
|
@ -119,129 +165,3 @@ pub fn fevent(fd: usize, flags: usize) -> Result<usize> {
|
||||||
context::event::register(fd, file.scheme, file.number);
|
context::event::register(fd, file.scheme, file.number);
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the canonical path of the file
|
|
||||||
pub fn fpath(fd: usize, buf: &mut [u8]) -> Result<usize> {
|
|
||||||
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<usize> {
|
|
||||||
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<usize> {
|
|
||||||
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<usize> {
|
|
||||||
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<usize> {
|
|
||||||
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<usize> {
|
|
||||||
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<usize> {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ pub use self::fs::*;
|
||||||
pub use self::process::*;
|
pub use self::process::*;
|
||||||
pub use self::validate::*;
|
pub use self::validate::*;
|
||||||
|
|
||||||
use self::data::Stat;
|
|
||||||
use self::error::{Error, Result, ENOSYS};
|
use self::error::{Error, Result, ENOSYS};
|
||||||
use self::number::*;
|
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 {
|
pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack: usize) -> usize {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize, stack: usize) -> Result<usize> {
|
fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize, stack: usize) -> Result<usize> {
|
||||||
match a {
|
match a & SYS_CLASS {
|
||||||
SYS_EXIT => exit(b),
|
SYS_CLASS_FILE => match a & SYS_ARG {
|
||||||
SYS_READ => read(b, validate_slice_mut(c as *mut u8, d)?),
|
SYS_ARG_SLICE => file_op_slice(a, b, validate_slice(c as *const u8, d)?),
|
||||||
SYS_WRITE => write(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)?),
|
||||||
SYS_OPEN => open(validate_slice(b as *const u8, c)?, d),
|
_ => match a {
|
||||||
SYS_CLOSE => close(b),
|
SYS_CLOSE => close(b),
|
||||||
SYS_WAITPID => waitpid(b, c, d),
|
SYS_DUP => dup(b),
|
||||||
SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?),
|
SYS_FEVENT => fevent(b, c),
|
||||||
SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?),
|
_ => file_op(a, b, c, d)
|
||||||
SYS_LSEEK => lseek(b, c, d),
|
}
|
||||||
SYS_GETPID => getpid(),
|
},
|
||||||
SYS_FSTAT => fstat(b, &mut validate_slice_mut(c as *mut Stat, 1)?[0]),
|
SYS_CLASS_PATH => match a {
|
||||||
SYS_DUP => dup(b),
|
SYS_OPEN => open(validate_slice(b as *const u8, c)?, d),
|
||||||
SYS_BRK => brk(b),
|
_ => unreachable!()
|
||||||
SYS_FTRUNCATE => ftruncate(b, c),
|
},
|
||||||
SYS_IOPL => iopl(b),
|
_ => match a {
|
||||||
SYS_FSYNC => fsync(b),
|
SYS_EXIT => exit(b),
|
||||||
SYS_CLONE => clone(b, stack),
|
SYS_WAITPID => waitpid(b, c, d),
|
||||||
SYS_YIELD => sched_yield(),
|
SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?),
|
||||||
SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
|
SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?),
|
||||||
SYS_FEVENT => fevent(b, c),
|
SYS_GETPID => getpid(),
|
||||||
SYS_FPATH => fpath(b, validate_slice_mut(c as *mut u8, d)?),
|
SYS_BRK => brk(b),
|
||||||
SYS_PHYSMAP => physmap(b, c, d),
|
SYS_IOPL => iopl(b),
|
||||||
SYS_PHYSUNMAP => physunmap(b),
|
SYS_CLONE => clone(b, stack),
|
||||||
_ => {
|
SYS_YIELD => sched_yield(),
|
||||||
println!("Unknown syscall {}", a);
|
SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
|
||||||
Err(Error::new(ENOSYS))
|
SYS_PHYSMAP => physmap(b, c, d),
|
||||||
|
SYS_PHYSUNMAP => physunmap(b),
|
||||||
|
_ => Err(Error::new(ENOSYS))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -395,7 +395,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
loop {
|
loop {
|
||||||
let mut buf = [0; 16384];
|
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 {
|
if count > 0 {
|
||||||
data.extend_from_slice(&buf[..count]);
|
data.extend_from_slice(&buf[..count]);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,6 +8,8 @@ pub use self::flag::*;
|
||||||
pub use self::number::*;
|
pub use self::number::*;
|
||||||
pub use self::scheme::*;
|
pub use self::scheme::*;
|
||||||
|
|
||||||
|
use core::mem;
|
||||||
|
|
||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
#[path="x86.rs"]
|
#[path="x86.rs"]
|
||||||
mod arch;
|
mod arch;
|
||||||
|
@ -67,7 +69,7 @@ pub fn fpath(fd: usize, buf: &mut [u8]) -> Result<usize> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> {
|
pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> {
|
||||||
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::<Stat>()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fsync(fd: usize) -> Result<usize> {
|
pub fn fsync(fd: usize) -> Result<usize> {
|
||||||
|
|
|
@ -1,31 +1,45 @@
|
||||||
pub const SYS_BRK: usize = 45;
|
pub const SYS_CLASS: usize = 0xF000_0000;
|
||||||
pub const SYS_CHDIR: usize = 12;
|
pub const SYS_CLASS_PATH: usize=0x1000_0000;
|
||||||
pub const SYS_CLONE: usize = 120;
|
pub const SYS_CLASS_FILE: usize=0x2000_0000;
|
||||||
pub const SYS_CLOSE: usize = 6;
|
|
||||||
pub const SYS_CLOCK_GETTIME: usize = 265;
|
pub const SYS_ARG: usize = 0x0F00_0000;
|
||||||
pub const SYS_DUP: usize = 41;
|
pub const SYS_ARG_SLICE: usize =0x0100_0000;
|
||||||
pub const SYS_EXECVE: usize = 11;
|
pub const SYS_ARG_MSLICE: usize=0x0200_0000;
|
||||||
pub const SYS_EXIT: usize = 1;
|
pub const SYS_ARG_PATH: usize = 0x0300_0000;
|
||||||
pub const SYS_FEVENT: usize = 927;
|
|
||||||
pub const SYS_FPATH: usize = 928;
|
pub const SYS_RET: usize = 0x00F0_0000;
|
||||||
pub const SYS_FSTAT: usize = 28;
|
pub const SYS_RET_FILE: usize = 0x0010_0000;
|
||||||
pub const SYS_FSYNC: usize = 118;
|
|
||||||
pub const SYS_FTRUNCATE: usize = 93;
|
pub const SYS_LINK: usize = SYS_CLASS_PATH | SYS_ARG_PATH | 9;
|
||||||
pub const SYS_FUTEX: usize = 240;
|
pub const SYS_OPEN: usize = SYS_CLASS_PATH | SYS_RET_FILE | 5;
|
||||||
pub const SYS_GETCWD: usize = 183;
|
pub const SYS_MKDIR: usize = SYS_CLASS_PATH | 39;
|
||||||
pub const SYS_GETPID: usize = 20;
|
pub const SYS_RMDIR: usize = SYS_CLASS_PATH | 84;
|
||||||
pub const SYS_IOPL: usize = 110;
|
pub const SYS_UNLINK: usize = SYS_CLASS_PATH | 10;
|
||||||
pub const SYS_LINK: usize = 9;
|
|
||||||
pub const SYS_LSEEK: usize = 19;
|
pub const SYS_CLOSE: usize = SYS_CLASS_FILE | 6;
|
||||||
pub const SYS_MKDIR: usize = 39;
|
pub const SYS_DUP: usize = SYS_CLASS_FILE | SYS_RET_FILE | 41;
|
||||||
pub const SYS_NANOSLEEP: usize = 162;
|
pub const SYS_READ: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 3;
|
||||||
pub const SYS_OPEN: usize = 5;
|
pub const SYS_WRITE: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 4;
|
||||||
pub const SYS_PHYSMAP: usize = 945;
|
pub const SYS_FEVENT: usize = SYS_CLASS_FILE | 927;
|
||||||
pub const SYS_PHYSUNMAP: usize = 946;
|
pub const SYS_LSEEK: usize = SYS_CLASS_FILE | 19;
|
||||||
pub const SYS_PIPE2: usize = 331;
|
pub const SYS_FPATH: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 928;
|
||||||
pub const SYS_READ: usize = 3;
|
pub const SYS_FSTAT: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 28;
|
||||||
pub const SYS_RMDIR: usize = 84;
|
pub const SYS_FSYNC: usize = SYS_CLASS_FILE | 118;
|
||||||
pub const SYS_UNLINK: usize = 10;
|
pub const SYS_FTRUNCATE: usize =SYS_CLASS_FILE | 93;
|
||||||
pub const SYS_WAITPID: usize = 7;
|
|
||||||
pub const SYS_WRITE: usize = 4;
|
pub const SYS_BRK: usize = 45;
|
||||||
pub const SYS_YIELD: usize = 158;
|
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;
|
||||||
|
|
Loading…
Reference in a new issue