implement fcntl & ioctl for socket. fix lighttpd performance
This commit is contained in:
parent
1326924dbb
commit
26189dddaa
@ -3,7 +3,6 @@ use std;
|
|||||||
use std::borrow::BorrowMut;
|
use std::borrow::BorrowMut;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
use std::any::Any;
|
|
||||||
|
|
||||||
pub trait File: Debug + Sync + Send + Any {
|
pub trait File: Debug + Sync + Send + Any {
|
||||||
fn read(&self, buf: &mut [u8]) -> Result<usize, Error>;
|
fn read(&self, buf: &mut [u8]) -> Result<usize, Error>;
|
||||||
@ -18,7 +17,7 @@ pub trait File: Debug + Sync + Send + Any {
|
|||||||
fn sync_all(&self) -> Result<(), Error>;
|
fn sync_all(&self) -> Result<(), Error>;
|
||||||
fn sync_data(&self) -> Result<(), Error>;
|
fn sync_data(&self) -> Result<(), Error>;
|
||||||
fn read_entry(&self) -> Result<String, Error>;
|
fn read_entry(&self) -> Result<String, Error>;
|
||||||
fn as_any(&self) -> &Any { unimplemented!() }
|
fn as_any(&self) -> &Any;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type FileRef = Arc<Box<File>>;
|
pub type FileRef = Arc<Box<File>>;
|
||||||
@ -116,6 +115,10 @@ impl File for SgxFile {
|
|||||||
fn read_entry(&self) -> Result<String, Error> {
|
fn read_entry(&self) -> Result<String, Error> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -379,6 +382,10 @@ impl File for StdoutFile {
|
|||||||
fn read_entry(&self) -> Result<String, Error> {
|
fn read_entry(&self) -> Result<String, Error> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for StdoutFile {
|
impl Debug for StdoutFile {
|
||||||
@ -476,6 +483,10 @@ impl File for StdinFile {
|
|||||||
fn read_entry(&self) -> Result<String, Error> {
|
fn read_entry(&self) -> Result<String, Error> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for StdinFile {
|
impl Debug for StdinFile {
|
||||||
|
@ -154,6 +154,10 @@ impl File for INodeFile {
|
|||||||
*offset += 1;
|
*offset += 1;
|
||||||
Ok(name)
|
Ok(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl INodeFile {
|
impl INodeFile {
|
||||||
|
@ -16,6 +16,7 @@ pub use self::io_multiplexing::*;
|
|||||||
pub use self::access::{AccessModes, AccessFlags, AT_FDCWD, do_access, do_faccessat};
|
pub use self::access::{AccessModes, AccessFlags, AT_FDCWD, do_access, do_faccessat};
|
||||||
use self::null::NullFile;
|
use self::null::NullFile;
|
||||||
use std::mem::uninitialized;
|
use std::mem::uninitialized;
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
mod file;
|
mod file;
|
||||||
mod file_table;
|
mod file_table;
|
||||||
@ -468,6 +469,8 @@ bitflags! {
|
|||||||
const TRUNCATE = 1 << 9;
|
const TRUNCATE = 1 << 9;
|
||||||
/// append on each write
|
/// append on each write
|
||||||
const APPEND = 1 << 10;
|
const APPEND = 1 << 10;
|
||||||
|
/// non block
|
||||||
|
const NONBLOCK = 1 << 11;
|
||||||
/// close on exec
|
/// close on exec
|
||||||
const CLOEXEC = 1 << 19;
|
const CLOEXEC = 1 << 19;
|
||||||
}
|
}
|
||||||
@ -694,28 +697,19 @@ pub enum FcntlCmd {
|
|||||||
/// Get the file status flags
|
/// Get the file status flags
|
||||||
GetFl(),
|
GetFl(),
|
||||||
/// Set the file status flags
|
/// Set the file status flags
|
||||||
SetFl(OpenFlags),
|
SetFl(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const F_DUPFD : u32 = 0;
|
|
||||||
pub const F_GETFD : u32 = 1;
|
|
||||||
pub const F_SETFD : u32 = 2;
|
|
||||||
pub const F_GETFL : u32 = 3;
|
|
||||||
pub const F_SETFL : u32 = 4;
|
|
||||||
pub const F_DUPFD_CLOEXEC : u32 = 1030;
|
|
||||||
|
|
||||||
pub const FD_CLOEXEC : u32 = 1;
|
|
||||||
|
|
||||||
impl FcntlCmd {
|
impl FcntlCmd {
|
||||||
#[deny(unreachable_patterns)]
|
#[deny(unreachable_patterns)]
|
||||||
pub fn from_raw(cmd: u32, arg: u64) -> Result<FcntlCmd, Error> {
|
pub fn from_raw(cmd: u32, arg: u64) -> Result<FcntlCmd, Error> {
|
||||||
Ok(match cmd {
|
Ok(match cmd as c_int {
|
||||||
F_DUPFD => FcntlCmd::DupFd(arg as FileDesc),
|
libc::F_DUPFD => FcntlCmd::DupFd(arg as FileDesc),
|
||||||
F_DUPFD_CLOEXEC => FcntlCmd::DupFdCloexec(arg as FileDesc),
|
libc::F_DUPFD_CLOEXEC => FcntlCmd::DupFdCloexec(arg as FileDesc),
|
||||||
F_GETFD => FcntlCmd::GetFd(),
|
libc::F_GETFD => FcntlCmd::GetFd(),
|
||||||
F_SETFD => FcntlCmd::SetFd(arg as u32),
|
libc::F_SETFD => FcntlCmd::SetFd(arg as u32),
|
||||||
F_GETFL => FcntlCmd::GetFl(),
|
libc::F_GETFL => FcntlCmd::GetFl(),
|
||||||
F_SETFL => FcntlCmd::SetFl(OpenFlags::from_bits_truncate(arg as u32)),
|
libc::F_SETFL => FcntlCmd::SetFl(arg as u32),
|
||||||
_ => return errno!(EINVAL, "invalid command"),
|
_ => return errno!(EINVAL, "invalid command"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -739,7 +733,7 @@ pub fn do_fcntl(fd: FileDesc, cmd: &FcntlCmd) -> Result<isize, Error> {
|
|||||||
FcntlCmd::GetFd() => {
|
FcntlCmd::GetFd() => {
|
||||||
let entry = files.get_entry(fd)?;
|
let entry = files.get_entry(fd)?;
|
||||||
let fd_flags = if entry.is_close_on_spawn() {
|
let fd_flags = if entry.is_close_on_spawn() {
|
||||||
FD_CLOEXEC
|
libc::FD_CLOEXEC
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
@ -747,19 +741,33 @@ pub fn do_fcntl(fd: FileDesc, cmd: &FcntlCmd) -> Result<isize, Error> {
|
|||||||
},
|
},
|
||||||
FcntlCmd::SetFd(fd_flags) => {
|
FcntlCmd::SetFd(fd_flags) => {
|
||||||
let entry = files.get_entry_mut(fd)?;
|
let entry = files.get_entry_mut(fd)?;
|
||||||
entry.set_close_on_spawn((fd_flags & FD_CLOEXEC) != 0);
|
entry.set_close_on_spawn((fd_flags & libc::FD_CLOEXEC as u32) != 0);
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
FcntlCmd::GetFl() => {
|
FcntlCmd::GetFl() => {
|
||||||
let _ = files.get_entry_mut(fd)?;
|
let file = files.get(fd)?;
|
||||||
warn!("fcntl.getfl is unimplemented");
|
if let Ok(socket) = file.as_socket() {
|
||||||
0
|
let ret = try_libc!(libc::ocall::fcntl_arg0(socket.fd(), libc::F_GETFL));
|
||||||
},
|
ret as isize
|
||||||
|
} else {
|
||||||
|
warn!("fcntl.getfl is unimplemented");
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
FcntlCmd::SetFl(flags) => {
|
FcntlCmd::SetFl(flags) => {
|
||||||
let _ = files.get_entry_mut(fd)?;
|
let file = files.get(fd)?;
|
||||||
warn!("fcntl.setfl is unimplemented");
|
if let Ok(socket) = file.as_socket() {
|
||||||
0
|
let ret = try_libc!(libc::ocall::fcntl_arg1(
|
||||||
},
|
socket.fd(),
|
||||||
|
libc::F_SETFL,
|
||||||
|
*flags as c_int
|
||||||
|
));
|
||||||
|
ret as isize
|
||||||
|
} else {
|
||||||
|
warn!("fcntl.setfl is unimplemented");
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,4 +51,8 @@ impl File for NullFile {
|
|||||||
fn read_entry(&self) -> Result<String, Error> {
|
fn read_entry(&self) -> Result<String, Error> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,10 @@ impl File for PipeReader {
|
|||||||
fn read_entry(&self) -> Result<String, Error> {
|
fn read_entry(&self) -> Result<String, Error> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for PipeReader {}
|
unsafe impl Send for PipeReader {}
|
||||||
@ -177,6 +181,10 @@ impl File for PipeWriter {
|
|||||||
fn read_entry(&self) -> Result<String, Error> {
|
fn read_entry(&self) -> Result<String, Error> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for PipeWriter {}
|
unsafe impl Send for PipeWriter {}
|
||||||
|
@ -5,7 +5,7 @@ use xmas_elf::{header, program, sections, ElfFile};
|
|||||||
|
|
||||||
pub const DEFAULT_STACK_SIZE: usize = 1 * 1024 * 1024;
|
pub const DEFAULT_STACK_SIZE: usize = 1 * 1024 * 1024;
|
||||||
pub const DEFAULT_HEAP_SIZE: usize = 2 * 1024 * 1024;
|
pub const DEFAULT_HEAP_SIZE: usize = 2 * 1024 * 1024;
|
||||||
pub const DEFAULT_MMAP_SIZE: usize = 2 * 1024 * 1024;
|
pub const DEFAULT_MMAP_SIZE: usize = 8 * 1024 * 1024;
|
||||||
|
|
||||||
pub fn do_init(elf_file: &ElfFile, elf_buf: &[u8]) -> Result<ProcessVM, Error> {
|
pub fn do_init(elf_file: &ElfFile, elf_buf: &[u8]) -> Result<ProcessVM, Error> {
|
||||||
let mut code_seg = get_code_segment(elf_file)?;
|
let mut code_seg = get_code_segment(elf_file)?;
|
||||||
|
@ -101,6 +101,7 @@ pub extern "C" fn dispatch_syscall(
|
|||||||
arg3 as usize,
|
arg3 as usize,
|
||||||
),
|
),
|
||||||
SYS_FCNTL => do_fcntl(arg0 as FileDesc, arg1 as u32, arg2 as u64),
|
SYS_FCNTL => do_fcntl(arg0 as FileDesc, arg1 as u32, arg2 as u64),
|
||||||
|
SYS_IOCTL => do_ioctl(arg0 as FileDesc, arg1 as c_int, arg2 as *mut c_int),
|
||||||
|
|
||||||
// IO multiplexing
|
// IO multiplexing
|
||||||
SYS_SELECT => do_select(
|
SYS_SELECT => do_select(
|
||||||
@ -280,6 +281,7 @@ pub extern "C" fn dispatch_syscall(
|
|||||||
|
|
||||||
match ret {
|
match ret {
|
||||||
Ok(code) => code as isize,
|
Ok(code) => code as isize,
|
||||||
|
Err(e) if e.errno.as_retval() == 0 => panic!("undefined errno"),
|
||||||
Err(e) => e.errno.as_retval() as isize,
|
Err(e) => e.errno.as_retval() as isize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -900,6 +902,23 @@ fn do_fcntl(fd: FileDesc, cmd: u32, arg: u64) -> Result<isize, Error> {
|
|||||||
fs::do_fcntl(fd, &cmd)
|
fs::do_fcntl(fd, &cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn do_ioctl(fd: FileDesc, cmd: c_int, argp: *mut c_int) -> Result<isize, Error> {
|
||||||
|
info!(
|
||||||
|
"ioctl: fd: {}, cmd: {}, argp: {:?}",
|
||||||
|
fd, cmd, argp
|
||||||
|
);
|
||||||
|
let current_ref = process::get_current();
|
||||||
|
let mut proc = current_ref.lock().unwrap();
|
||||||
|
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||||
|
if let Ok(socket) = file_ref.as_socket() {
|
||||||
|
let ret = try_libc!(libc::ocall::ioctl_arg1(socket.fd(), cmd, argp));
|
||||||
|
Ok(ret as isize)
|
||||||
|
} else {
|
||||||
|
warn!("ioctl is unimplemented");
|
||||||
|
errno!(ENOSYS, "ioctl is unimplemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn do_arch_prctl(code: u32, addr: *mut usize) -> Result<isize, Error> {
|
fn do_arch_prctl(code: u32, addr: *mut usize) -> Result<isize, Error> {
|
||||||
let code = process::ArchPrctlCode::from_u32(code)?;
|
let code = process::ArchPrctlCode::from_u32(code)?;
|
||||||
check_mut_ptr(addr)?;
|
check_mut_ptr(addr)?;
|
||||||
|
@ -16,6 +16,7 @@ pub use self::process_vm::ProcessVM;
|
|||||||
// TODO: separate proc and flags
|
// TODO: separate proc and flags
|
||||||
// TODO: accept fd and offset
|
// TODO: accept fd and offset
|
||||||
pub fn do_mmap(addr: usize, size: usize, flags: VMAreaFlags) -> Result<usize, Error> {
|
pub fn do_mmap(addr: usize, size: usize, flags: VMAreaFlags) -> Result<usize, Error> {
|
||||||
|
info!("mmap: addr: {:#x}, size: {:#x}, flags: {:?}", addr, size, flags);
|
||||||
let current_ref = get_current();
|
let current_ref = get_current();
|
||||||
let current_process = current_ref.lock().unwrap();
|
let current_process = current_ref.lock().unwrap();
|
||||||
let current_vm_ref = current_process.get_vm();
|
let current_vm_ref = current_process.get_vm();
|
||||||
@ -24,6 +25,7 @@ pub fn do_mmap(addr: usize, size: usize, flags: VMAreaFlags) -> Result<usize, Er
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_munmap(addr: usize, size: usize) -> Result<(), Error> {
|
pub fn do_munmap(addr: usize, size: usize) -> Result<(), Error> {
|
||||||
|
info!("munmap: addr: {:#x}, size: {:#x}", addr, size);
|
||||||
let current_ref = get_current();
|
let current_ref = get_current();
|
||||||
let current_process = current_ref.lock().unwrap();
|
let current_process = current_ref.lock().unwrap();
|
||||||
let current_vm_ref = current_process.get_vm();
|
let current_vm_ref = current_process.get_vm();
|
||||||
@ -37,6 +39,10 @@ pub fn do_mremap(
|
|||||||
old_size: usize,
|
old_size: usize,
|
||||||
options: &VMResizeOptions,
|
options: &VMResizeOptions,
|
||||||
) -> Result<usize, Error> {
|
) -> Result<usize, Error> {
|
||||||
|
info!(
|
||||||
|
"mremap: oldaddr: {:#x}, oldsize: {:#x}, options: {:?}",
|
||||||
|
old_addr, old_size, options
|
||||||
|
);
|
||||||
let current_ref = get_current();
|
let current_ref = get_current();
|
||||||
let current_process = current_ref.lock().unwrap();
|
let current_process = current_ref.lock().unwrap();
|
||||||
let current_vm_ref = current_process.get_vm();
|
let current_vm_ref = current_process.get_vm();
|
||||||
@ -45,6 +51,7 @@ pub fn do_mremap(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_brk(addr: usize) -> Result<usize, Error> {
|
pub fn do_brk(addr: usize) -> Result<usize, Error> {
|
||||||
|
info!("brk: addr: {:#x}", addr);
|
||||||
let current_ref = get_current();
|
let current_ref = get_current();
|
||||||
let current_process = current_ref.lock().unwrap();
|
let current_process = current_ref.lock().unwrap();
|
||||||
let current_vm_ref = current_process.get_vm();
|
let current_vm_ref = current_process.get_vm();
|
||||||
|
Loading…
Reference in New Issue
Block a user