Implement dup2. Add debugging lines.
This commit is contained in:
parent
5be2cbfaf4
commit
364e1b542a
|
@ -220,6 +220,25 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
/// Insert a file with a specific handle number. This is used by dup2
|
||||
/// Return the file descriptor number or None if the slot was not empty, or i was invalid
|
||||
pub fn insert_file(&self, i: FileHandle, file: File) -> Option<FileHandle> {
|
||||
let mut files = self.files.lock();
|
||||
if i.into() < super::CONTEXT_MAX_FILES {
|
||||
while i.into() >= files.len() {
|
||||
files.push(None);
|
||||
}
|
||||
if files[i.into()].is_none() {
|
||||
files[i.into()] = Some(file);
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove a file
|
||||
// TODO: adjust files vector to smaller size if possible
|
||||
pub fn remove_file(&self, i: FileHandle) -> Option<File> {
|
||||
|
|
|
@ -89,6 +89,8 @@ pub fn open(path: &[u8], flags: usize) -> Result<FileHandle> {
|
|||
(context.canonicalize(path), context.euid, context.egid, context.ens)
|
||||
};
|
||||
|
||||
//println!("open {}", unsafe { ::core::str::from_utf8_unchecked(&path_canon) });
|
||||
|
||||
let mut parts = path_canon.splitn(2, |&b| b == b':');
|
||||
let scheme_name_opt = parts.next();
|
||||
let reference_opt = parts.next();
|
||||
|
@ -261,6 +263,41 @@ pub fn dup(fd: FileHandle, buf: &[u8]) -> Result<FileHandle> {
|
|||
}).ok_or(Error::new(EMFILE))
|
||||
}
|
||||
|
||||
/// Duplicate file descriptor, replacing another
|
||||
pub fn dup2(fd: FileHandle, new_fd: FileHandle, buf: &[u8]) -> Result<FileHandle> {
|
||||
if fd == new_fd {
|
||||
Ok(new_fd)
|
||||
} else {
|
||||
let _ = close(new_fd)?;
|
||||
|
||||
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 new_id = {
|
||||
let scheme = {
|
||||
let schemes = scheme::schemes();
|
||||
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
|
||||
scheme.clone()
|
||||
};
|
||||
scheme.dup(file.number, buf)?
|
||||
};
|
||||
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
context.insert_file(new_fd, ::context::file::File {
|
||||
scheme: file.scheme,
|
||||
number: new_id,
|
||||
event: None,
|
||||
}).ok_or(Error::new(EBADF))
|
||||
}
|
||||
}
|
||||
|
||||
/// Register events for file
|
||||
pub fn fevent(fd: FileHandle, flags: usize) -> Result<usize> {
|
||||
let file = {
|
||||
|
|
|
@ -53,6 +53,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
|
|||
_ => match a {
|
||||
SYS_CLOSE => close(fd),
|
||||
SYS_DUP => dup(fd, validate_slice(c as *const u8, d)?).map(FileHandle::into),
|
||||
SYS_DUP2 => dup2(fd, FileHandle::from(c), validate_slice(d as *const u8, e)?).map(FileHandle::into),
|
||||
SYS_FEVENT => fevent(fd, c),
|
||||
SYS_FUNMAP => funmap(b),
|
||||
_ => file_op(a, fd, c, d)
|
||||
|
@ -103,10 +104,18 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
|
|||
}
|
||||
|
||||
let result = inner(a, b, c, d, e, f, stack);
|
||||
/*
|
||||
|
||||
/*
|
||||
if let Err(ref err) = result {
|
||||
println!("{}, {}, {}, {}: {}", a, b, c, d, err);
|
||||
let contexts = ::context::contexts();
|
||||
if let Some(context_lock) = contexts.current() {
|
||||
let context = context_lock.read();
|
||||
print!("{}: {}: ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into());
|
||||
}
|
||||
*/
|
||||
|
||||
println!("{:X}, {:X}, {:X}, {:X}: {}", a, b, c, d, err);
|
||||
}
|
||||
*/
|
||||
|
||||
Error::mux(result)
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ pub fn brk(address: usize) -> Result<usize> {
|
|||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
|
||||
//println!("{}: {}: BRK {:X}", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) },
|
||||
// context.id.into(), address);
|
||||
|
||||
let current = if let Some(ref heap_shared) = context.heap {
|
||||
heap_shared.with(|heap| {
|
||||
heap.start_address().get() + heap.size()
|
||||
|
@ -47,8 +50,10 @@ pub fn brk(address: usize) -> Result<usize> {
|
|||
panic!("user heap not initialized");
|
||||
}
|
||||
|
||||
//println!("Brk resize {:X}", address);
|
||||
Ok(address)
|
||||
} else {
|
||||
//println!("Brk no mem");
|
||||
Err(Error::new(ENOMEM))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,13 @@ fn validate(address: usize, size: usize, flags: entry::EntryFlags) -> Result<()>
|
|||
let start_page = Page::containing_address(VirtualAddress::new(address));
|
||||
let end_page = Page::containing_address(VirtualAddress::new(address + size - 1));
|
||||
for page in Page::range_inclusive(start_page, end_page) {
|
||||
let page_flags = active_table.translate_page_flags(page).ok_or(Error::new(EFAULT))?;
|
||||
if let Some(page_flags) = active_table.translate_page_flags(page) {
|
||||
if ! page_flags.contains(flags) {
|
||||
//println!("{:X}: Not {:?}", page.start_address().get(), flags);
|
||||
return Err(Error::new(EFAULT));
|
||||
}
|
||||
} else {
|
||||
//println!("{:X}: Not found", page.start_address().get());
|
||||
return Err(Error::new(EFAULT));
|
||||
}
|
||||
}
|
||||
|
|
2
syscall
2
syscall
|
@ -1 +1 @@
|
|||
Subproject commit 9b0c363b2711c64ad5be298bdf39c65b2a5d5e2f
|
||||
Subproject commit e79e54d2f5ad6492b4452f74e60c54325997823f
|
Loading…
Reference in a new issue