Merge branch 'cap2' of https://github.com/Yoric/redox into Yoric-cap2
This commit is contained in:
commit
297b6e09fc
18 changed files with 254 additions and 108 deletions
|
@ -2,13 +2,13 @@
|
|||
use core::sync::atomic::Ordering;
|
||||
|
||||
use context;
|
||||
use scheme;
|
||||
use scheme::{self, FileHandle};
|
||||
use syscall;
|
||||
use syscall::data::{Packet, Stat};
|
||||
use syscall::error::*;
|
||||
use syscall::flag::{MODE_DIR, MODE_FILE};
|
||||
|
||||
pub fn file_op(a: usize, fd: usize, c: usize, d: usize) -> Result<usize> {
|
||||
pub fn file_op(a: usize, fd: FileHandle, c: usize, d: usize) -> Result<usize> {
|
||||
let (file, pid, uid, gid) = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
|
@ -25,7 +25,7 @@ pub fn file_op(a: usize, fd: usize, c: usize, d: usize) -> Result<usize> {
|
|||
|
||||
let mut packet = Packet {
|
||||
id: 0,
|
||||
pid: pid,
|
||||
pid: pid.into(),
|
||||
uid: uid,
|
||||
gid: gid,
|
||||
a: a,
|
||||
|
@ -39,11 +39,11 @@ pub fn file_op(a: usize, fd: usize, c: usize, d: usize) -> Result<usize> {
|
|||
Error::demux(packet.a)
|
||||
}
|
||||
|
||||
pub fn file_op_slice(a: usize, fd: usize, slice: &[u8]) -> Result<usize> {
|
||||
pub fn file_op_slice(a: usize, fd: FileHandle, 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> {
|
||||
pub fn file_op_mut_slice(a: usize, fd: FileHandle, slice: &mut [u8]) -> Result<usize> {
|
||||
file_op(a, fd, slice.as_mut_ptr() as usize, slice.len())
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ pub fn getcwd(buf: &mut [u8]) -> Result<usize> {
|
|||
}
|
||||
|
||||
/// Open syscall
|
||||
pub fn open(path: &[u8], flags: usize) -> Result<usize> {
|
||||
pub fn open(path: &[u8], flags: usize) -> Result<FileHandle> {
|
||||
let (path_canon, uid, gid) = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
|
@ -135,8 +135,8 @@ pub fn pipe2(fds: &mut [usize], flags: usize) -> Result<usize> {
|
|||
event: None,
|
||||
}).ok_or(Error::new(EMFILE))?;
|
||||
|
||||
fds[0] = read_fd;
|
||||
fds[1] = write_fd;
|
||||
fds[0] = read_fd.into();
|
||||
fds[1] = write_fd.into();
|
||||
|
||||
Ok(0)
|
||||
} else {
|
||||
|
@ -211,7 +211,7 @@ pub fn unlink(path: &[u8]) -> Result<usize> {
|
|||
}
|
||||
|
||||
/// Close syscall
|
||||
pub fn close(fd: usize) -> Result<usize> {
|
||||
pub fn close(fd: FileHandle) -> Result<usize> {
|
||||
let file = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
|
@ -233,7 +233,7 @@ pub fn close(fd: usize) -> Result<usize> {
|
|||
}
|
||||
|
||||
/// Duplicate file descriptor
|
||||
pub fn dup(fd: usize, buf: &[u8]) -> Result<usize> {
|
||||
pub fn dup(fd: FileHandle, buf: &[u8]) -> Result<FileHandle> {
|
||||
let file = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
|
@ -262,15 +262,15 @@ pub fn dup(fd: usize, buf: &[u8]) -> Result<usize> {
|
|||
}
|
||||
|
||||
/// Register events for file
|
||||
pub fn fevent(fd: usize, flags: usize) -> Result<usize> {
|
||||
pub fn fevent(fd: FileHandle, flags: 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 mut files = context.files.lock();
|
||||
let mut file = files.get_mut(fd).ok_or(Error::new(EBADF))?.ok_or(Error::new(EBADF))?;
|
||||
let mut file = files.get_mut(fd.into()).ok_or(Error::new(EBADF))?.ok_or(Error::new(EBADF))?;
|
||||
if let Some(event_id) = file.event.take() {
|
||||
println!("{}: {}:{}: events already registered: {}", fd, file.scheme, file.number, event_id);
|
||||
println!("{:?}: {:?}:{}: events already registered: {}", fd, file.scheme, file.number, event_id);
|
||||
context::event::unregister(fd, file.scheme, event_id);
|
||||
}
|
||||
file.clone()
|
||||
|
@ -287,7 +287,7 @@ pub fn fevent(fd: usize, flags: usize) -> Result<usize> {
|
|||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
let mut files = context.files.lock();
|
||||
let mut file = files.get_mut(fd).ok_or(Error::new(EBADF))?.ok_or(Error::new(EBADF))?;
|
||||
let mut file = files.get_mut(fd.into()).ok_or(Error::new(EBADF))?.ok_or(Error::new(EBADF))?;
|
||||
file.event = Some(event_id);
|
||||
}
|
||||
context::event::register(fd, file.scheme, event_id);
|
||||
|
|
|
@ -14,6 +14,9 @@ use self::data::TimeSpec;
|
|||
use self::error::{Error, Result, ENOSYS};
|
||||
use self::number::*;
|
||||
|
||||
use context::ContextId;
|
||||
use scheme::FileHandle;
|
||||
|
||||
/// Filesystem syscalls
|
||||
pub mod fs;
|
||||
|
||||
|
@ -34,19 +37,22 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
|
|||
#[inline(always)]
|
||||
fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack: usize) -> Result<usize> {
|
||||
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, validate_slice(c as *const u8, d)?),
|
||||
SYS_FEVENT => fevent(b, c),
|
||||
SYS_FUNMAP => funmap(b),
|
||||
_ => file_op(a, b, c, d)
|
||||
SYS_CLASS_FILE => {
|
||||
let fd = FileHandle::from(b);
|
||||
match a & SYS_ARG {
|
||||
SYS_ARG_SLICE => file_op_slice(a, fd, validate_slice(c as *const u8, d)?),
|
||||
SYS_ARG_MSLICE => file_op_mut_slice(a, fd, validate_slice_mut(c as *mut u8, d)?),
|
||||
_ => match a {
|
||||
SYS_CLOSE => close(fd),
|
||||
SYS_DUP => dup(fd, validate_slice(c as *const u8, d)?).map(FileHandle::into),
|
||||
SYS_FEVENT => fevent(fd, c),
|
||||
SYS_FUNMAP => funmap(b),
|
||||
_ => file_op(a, fd, c, d)
|
||||
}
|
||||
}
|
||||
},
|
||||
SYS_CLASS_PATH => match a {
|
||||
SYS_OPEN => open(validate_slice(b as *const u8, c)?, d),
|
||||
SYS_OPEN => open(validate_slice(b as *const u8, c)?, d).map(FileHandle::into),
|
||||
SYS_MKDIR => mkdir(validate_slice(b as *const u8, c)?, d as u16),
|
||||
SYS_RMDIR => rmdir(validate_slice(b as *const u8, c)?),
|
||||
SYS_UNLINK => unlink(validate_slice(b as *const u8, c)?),
|
||||
|
@ -54,13 +60,13 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
|
|||
},
|
||||
_ => match a {
|
||||
SYS_EXIT => exit(b),
|
||||
SYS_WAITPID => waitpid(b, c, d),
|
||||
SYS_WAITPID => waitpid(ContextId::from(b), c, d).map(ContextId::into),
|
||||
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_GETPID => getpid().map(ContextId::into),
|
||||
SYS_BRK => brk(b),
|
||||
SYS_IOPL => iopl(b),
|
||||
SYS_CLONE => clone(b, stack),
|
||||
SYS_CLONE => clone(b, stack).map(ContextId::into),
|
||||
SYS_YIELD => sched_yield(),
|
||||
SYS_NANOSLEEP => nanosleep(validate_slice(b as *const TimeSpec, 1).map(|req| &req[0])?, validate_slice_mut(c as *mut TimeSpec, 1).ok().map(|rem| &mut rem[0])),
|
||||
SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
|
||||
|
|
|
@ -12,9 +12,10 @@ use arch::paging::{ActivePageTable, InactivePageTable, Page, PhysicalAddress, Vi
|
|||
use arch::paging::temporary_page::TemporaryPage;
|
||||
use arch::start::usermode;
|
||||
use context;
|
||||
use context::ContextId;
|
||||
use context::memory::Grant;
|
||||
use elf::{self, program_header};
|
||||
use scheme;
|
||||
use scheme::{self, FileHandle};
|
||||
use syscall;
|
||||
use syscall::data::Stat;
|
||||
use syscall::error::*;
|
||||
|
@ -53,7 +54,7 @@ pub fn brk(address: usize) -> Result<usize> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
||||
pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
|
||||
let ppid;
|
||||
let pid;
|
||||
{
|
||||
|
@ -720,10 +721,10 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
|||
if let Some(context_lock) = contexts.get(ppid) {
|
||||
let mut context = context_lock.write();
|
||||
if ! context.unblock() {
|
||||
println!("{} not blocked for exec vfork unblock", ppid);
|
||||
println!("{:?} not blocked for exec vfork unblock", ppid);
|
||||
}
|
||||
} else {
|
||||
println!("{} not found for exec vfork unblock", ppid);
|
||||
println!("{:?} not found for exec vfork unblock", ppid);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -749,7 +750,7 @@ pub fn exit(status: usize) -> ! {
|
|||
let mut close_files = Vec::new();
|
||||
let (pid, ppid) = {
|
||||
let mut context = context_lock.write();
|
||||
if Arc::strong_count(&context.files) == 1 {
|
||||
if Arc::strong_count(&context.files) == 1 { // FIXME: Looks like a race condition.
|
||||
mem::swap(context.files.lock().deref_mut(), &mut close_files);
|
||||
}
|
||||
context.files = Arc::new(Mutex::new(Vec::new()));
|
||||
|
@ -760,7 +761,7 @@ pub fn exit(status: usize) -> ! {
|
|||
for (fd, file_option) in close_files.drain(..).enumerate() {
|
||||
if let Some(file) = file_option {
|
||||
if let Some(event_id) = file.event {
|
||||
context::event::unregister(fd, file.scheme, event_id);
|
||||
context::event::unregister(FileHandle::from(fd), file.scheme, event_id);
|
||||
}
|
||||
|
||||
let scheme_option = {
|
||||
|
@ -811,7 +812,7 @@ pub fn exit(status: usize) -> ! {
|
|||
let mut parent = parent_lock.write();
|
||||
if vfork {
|
||||
if ! parent.unblock() {
|
||||
println!("{} not blocked for exit vfork unblock", ppid);
|
||||
println!("{:?} not blocked for exit vfork unblock", ppid);
|
||||
}
|
||||
}
|
||||
parent.waitpid.clone()
|
||||
|
@ -822,7 +823,7 @@ pub fn exit(status: usize) -> ! {
|
|||
}
|
||||
waitpid.send(pid, status);
|
||||
} else {
|
||||
println!("{} not found for exit vfork unblock", ppid);
|
||||
println!("{:?} not found for exit vfork unblock", ppid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -853,7 +854,7 @@ pub fn getgid() -> Result<usize> {
|
|||
Ok(context.rgid as usize)
|
||||
}
|
||||
|
||||
pub fn getpid() -> Result<usize> {
|
||||
pub fn getpid() -> Result<ContextId> {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
|
@ -872,7 +873,7 @@ pub fn iopl(_level: usize) -> Result<usize> {
|
|||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn kill(pid: usize, sig: usize) -> Result<usize> {
|
||||
pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
|
||||
use syscall::flag::*;
|
||||
|
||||
let _context_lock = {
|
||||
|
@ -882,19 +883,19 @@ pub fn kill(pid: usize, sig: usize) -> Result<usize> {
|
|||
};
|
||||
|
||||
let term = || {
|
||||
println!("Terminate {}", pid);
|
||||
println!("Terminate {:?}", pid);
|
||||
};
|
||||
|
||||
let core = || {
|
||||
println!("Core {}", pid);
|
||||
println!("Core {:?}", pid);
|
||||
};
|
||||
|
||||
let stop = || {
|
||||
println!("Stop {}", pid);
|
||||
println!("Stop {:?}", pid);
|
||||
};
|
||||
|
||||
let cont = || {
|
||||
println!("Continue {}", pid);
|
||||
println!("Continue {:?}", pid);
|
||||
};
|
||||
|
||||
match sig {
|
||||
|
@ -1056,7 +1057,7 @@ pub fn virttophys(virtual_address: usize) -> Result<usize> {
|
|||
}
|
||||
}
|
||||
|
||||
fn reap(pid: usize) -> Result<usize> {
|
||||
fn reap(pid: ContextId) -> Result<ContextId> {
|
||||
// Spin until not running
|
||||
let mut running = false;
|
||||
while running {
|
||||
|
@ -1074,7 +1075,7 @@ fn reap(pid: usize) -> Result<usize> {
|
|||
contexts.remove(pid).ok_or(Error::new(ESRCH)).and(Ok(pid))
|
||||
}
|
||||
|
||||
pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result<usize> {
|
||||
pub fn waitpid(pid: ContextId, status_ptr: usize, flags: usize) -> Result<ContextId> {
|
||||
let waitpid = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
|
@ -1089,13 +1090,13 @@ pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result<usize> {
|
|||
&mut tmp
|
||||
};
|
||||
|
||||
if pid == 0 {
|
||||
if pid.into() == 0 {
|
||||
if flags & WNOHANG == WNOHANG {
|
||||
if let Some((w_pid, status)) = waitpid.receive_any_nonblock() {
|
||||
status_slice[0] = status;
|
||||
reap(w_pid)
|
||||
} else {
|
||||
Ok(0)
|
||||
Ok(ContextId::from(0))
|
||||
}
|
||||
} else {
|
||||
let (w_pid, status) = waitpid.receive_any();
|
||||
|
@ -1108,7 +1109,7 @@ pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result<usize> {
|
|||
status_slice[0] = status;
|
||||
reap(pid)
|
||||
} else {
|
||||
Ok(0)
|
||||
Ok(ContextId::from(0))
|
||||
}
|
||||
} else {
|
||||
let status = waitpid.receive(&pid);
|
||||
|
@ -1117,3 +1118,4 @@ pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result<usize> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue