1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-23 00:16:17 +04:00

fix fork(dup)

This commit is contained in:
function2-llx 2020-05-08 22:24:42 +08:00
parent e44bc7e6d2
commit b946f8606d
9 changed files with 60 additions and 58 deletions

View File

@ -11,6 +11,7 @@ const F_LINUX_SPECIFIC_BASE: usize = 1024;
pub const F_DUPFD_CLOEXEC: usize = F_LINUX_SPECIFIC_BASE + 6; pub const F_DUPFD_CLOEXEC: usize = F_LINUX_SPECIFIC_BASE + 6;
pub const O_NONBLOCK: usize = 04000;
pub const O_CLOEXEC: usize = 02000000; /* set close_on_exec */ pub const O_CLOEXEC: usize = 02000000; /* set close_on_exec */
pub const AT_SYMLINK_NOFOLLOW: usize = 0x100; pub const AT_SYMLINK_NOFOLLOW: usize = 0x100;

View File

@ -13,6 +13,16 @@ use rcore_memory::memory_set::handler::File;
use crate::sync::SpinLock as Mutex; use crate::sync::SpinLock as Mutex;
/* Operations for the `flock' call. */
pub const LOCK_SH: usize = 1; /* Shared lock. */
pub const LOCK_EX: usize = 2; /* Exclusive lock. */
pub const LOCK_UN: usize = 8; /* Unlock. */
pub const __LOCK_ATOMIC: usize = 16; /* Atomic update. */
/* Can be OR'd in to one of the above. */
pub const LOCK_NB: usize = 4; /* Don't block when locking. */
#[derive(Clone)]
pub struct FileHandle { pub struct FileHandle {
inode: Arc<dyn INode>, inode: Arc<dyn INode>,
offset: Arc<Mutex<u64>>, offset: Arc<Mutex<u64>>,
@ -21,19 +31,6 @@ pub struct FileHandle {
pub fd_cloexec: bool, pub fd_cloexec: bool,
} }
impl Clone for FileHandle {
// do not share offset
fn clone(&self) -> Self {
FileHandle {
inode: self.inode.clone(),
offset: Arc::new(Mutex::new(*self.offset.lock())),
options: Arc::new(Mutex::new(*self.options.lock())),
path: self.path.clone(),
fd_cloexec: self.fd_cloexec,
}
}
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct OpenOptions { pub struct OpenOptions {
pub read: bool, pub read: bool,
@ -66,17 +63,7 @@ impl FileHandle {
}; };
} }
pub fn clone_shared(&self) -> Self { // do almost as default clone does, but with fd_cloexec specified
FileHandle {
inode: self.inode.clone(),
offset: self.offset.clone(),
options: self.options.clone(),
path: self.path.clone(),
fd_cloexec: self.fd_cloexec,
}
}
// do almost as default clone does, share the offset
pub fn dup(&self, fd_cloexec: bool) -> Self { pub fn dup(&self, fd_cloexec: bool) -> Self {
FileHandle { FileHandle {
inode: self.inode.clone(), inode: self.inode.clone(),

View File

@ -9,7 +9,6 @@ use alloc::boxed::Box;
use rcore_fs::vfs::{MMapArea, PollStatus}; use rcore_fs::vfs::{MMapArea, PollStatus};
// TODO: merge FileLike to FileHandle ? // TODO: merge FileLike to FileHandle ?
// TODO: fix dup and remove Clone
#[derive(Clone)] #[derive(Clone)]
pub enum FileLike { pub enum FileLike {
File(FileHandle), File(FileHandle),
@ -19,11 +18,11 @@ pub enum FileLike {
impl FileLike { impl FileLike {
pub fn dup(&self, fd_cloexec: bool) -> FileLike { pub fn dup(&self, fd_cloexec: bool) -> FileLike {
use FileLike::File; use FileLike::*;
if let File(file) = self { match self {
File(file.dup(fd_cloexec)) File(file) => File(file.dup(fd_cloexec)),
} else { Socket(s) => Socket(s.clone()),
self.clone() EpollInstance(e) => EpollInstance(e.clone()),
} }
} }

View File

@ -61,6 +61,7 @@ impl Pipe {
fn can_read(&self) -> bool { fn can_read(&self) -> bool {
if let PipeEnd::Read = self.direction { if let PipeEnd::Read = self.direction {
// true
let data = self.data.lock(); let data = self.data.lock();
data.buf.len() > 0 || data.end_cnt < 2 data.buf.len() > 0 || data.end_cnt < 2
} else { } else {

View File

@ -344,24 +344,9 @@ impl Thread {
let mut proc = self.proc.lock(); let mut proc = self.proc.lock();
let mut files = BTreeMap::new();
let mut offsets = BTreeSet::new();
for (fd, file_like) in proc.files.iter() {
if let FileLike::File(file) = file_like {
let addr = file.options.as_ref() as *const _ as usize;
if offsets.contains(&addr) {
files.insert(*fd, FileLike::File(file.clone_shared()));
} else {
files.insert(*fd, FileLike::File(file.clone()));
offsets.insert(addr);
}
} else {
files.insert(*fd, file_like.clone());
}
}
let new_proc = Process { let new_proc = Process {
vm: vm.clone(), vm: vm.clone(),
files, files: proc.files.clone(), // share open file descriptions
cwd: proc.cwd.clone(), cwd: proc.cwd.clone(),
exec_path: proc.exec_path.clone(), exec_path: proc.exec_path.clone(),
futexes: BTreeMap::default(), futexes: BTreeMap::default(),

View File

@ -22,6 +22,7 @@ use crate::fs::FileLike;
use crate::process::Process; use crate::process::Process;
use crate::syscall::SysError::EINVAL; use crate::syscall::SysError::EINVAL;
use rcore_fs::vfs::PollStatus; use rcore_fs::vfs::PollStatus;
use crate::fs::fcntl::{O_CLOEXEC, O_NONBLOCK};
impl Syscall<'_> { impl Syscall<'_> {
pub fn sys_read(&mut self, fd: usize, base: *mut u8, len: usize) -> SysResult { pub fn sys_read(&mut self, fd: usize, base: *mut u8, len: usize) -> SysResult {
@ -33,18 +34,24 @@ impl Syscall<'_> {
let slice = unsafe { self.vm().check_write_array(base, len)? }; let slice = unsafe { self.vm().check_write_array(base, len)? };
let file_like = proc.get_file_like(fd)?; let file_like = proc.get_file_like(fd)?;
let len = file_like.read(slice)?; let len = file_like.read(slice)?;
if len == 1 && !proc.pid.is_init(){
println!("write content: {}", slice[0] as char);
}
Ok(len) Ok(len)
} }
pub fn sys_write(&mut self, fd: usize, base: *const u8, len: usize) -> SysResult { pub fn sys_write(&mut self, fd: usize, base: *const u8, len: usize) -> SysResult {
let mut proc = self.process(); let mut proc = self.process();
// if !proc.pid.is_init() { if !proc.pid.is_init() {
// we trust pid 0 process //we trust pid 0 process
info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len); info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
// } }
let slice = unsafe { self.vm().check_read_array(base, len)? }; let slice = unsafe { self.vm().check_read_array(base, len)? };
let file_like = proc.get_file_like(fd)?; let file_like = proc.get_file_like(fd)?;
let len = file_like.write(slice)?; let len = file_like.write(slice)?;
if len == 1 && !proc.pid.is_init(){
println!("write content: {}", slice[0] as char);
}
Ok(len) Ok(len)
} }
@ -85,6 +92,9 @@ impl Syscall<'_> {
timeout: *const TimeSpec, timeout: *const TimeSpec,
) -> SysResult { ) -> SysResult {
let proc = self.process(); let proc = self.process();
if !proc.pid.is_init() {
info!("ppoll: ufds: {:#x}, nfds: {}, timeout: {:#x}", ufds as usize, nfds, timeout as usize);
}
let timeout_msecs = if timeout.is_null() { let timeout_msecs = if timeout.is_null() {
1 << 31 // infinity 1 << 31 // infinity
} else { } else {
@ -111,6 +121,12 @@ impl Syscall<'_> {
let polls = unsafe { self.vm().check_write_array(ufds, nfds)? }; let polls = unsafe { self.vm().check_write_array(ufds, nfds)? };
if !proc.pid.is_init() {
info!(
"poll: fds: {:?}", polls
);
}
drop(proc); drop(proc);
let begin_time_ms = crate::trap::uptime_msec(); let begin_time_ms = crate::trap::uptime_msec();
@ -736,6 +752,16 @@ impl Syscall<'_> {
Ok(0) Ok(0)
} }
pub fn sys_flock(&mut self, fd: usize, operation: usize) -> SysResult {
info!("flock: fd: {}, operation: {}", fd, operation);
let mut proc = self.process();
// let file_like = proc.get_file_like(fd)?;
let file = proc.get_file(fd)?;
Ok(0)
}
pub fn sys_fdatasync(&mut self, fd: usize) -> SysResult { pub fn sys_fdatasync(&mut self, fd: usize) -> SysResult {
info!("fdatasync: fd: {}", fd); info!("fdatasync: fd: {}", fd);
self.process().get_file(fd)?.sync_data()?; self.process().get_file(fd)?.sync_data()?;
@ -1021,8 +1047,10 @@ impl Syscall<'_> {
Ok(0) Ok(0)
} }
pub fn sys_pipe(&mut self, fds: *mut u32) -> SysResult { pub fn sys_pipe(&mut self, fds: *mut u32) -> SysResult { self.sys_pipe2(fds, 0) }
info!("pipe: fds: {:?}", fds);
pub fn sys_pipe2(&mut self, fds: *mut u32, flags: usize) -> SysResult {
info!("pipe2: fds: {:?}, flags: {:#x}", fds, flags);
let mut proc = self.process(); let mut proc = self.process();
let fds = unsafe { self.vm().check_write_array(fds, 2)? }; let fds = unsafe { self.vm().check_write_array(fds, 2)? };
@ -1034,10 +1062,10 @@ impl Syscall<'_> {
read: true, read: true,
write: false, write: false,
append: false, append: false,
nonblock: false, nonblock: (flags & O_NONBLOCK) != 0,
}, },
String::from("pipe_r:[]"), String::from("pipe_r:[]"),
false, (flags & O_CLOEXEC) != 0
))); )));
let write_fd = proc.add_file(FileLike::File(FileHandle::new( let write_fd = proc.add_file(FileLike::File(FileHandle::new(

View File

@ -185,7 +185,8 @@ impl Syscall<'_> {
let mut i = 0; let mut i = 0;
for elm in slice { for elm in slice {
unsafe { unsafe {
*elm = i + crate::trap::TICK as u8; // to prevent overflow
*elm = (i + crate::trap::TICK as u8 as u16) as u8;
} }
i += 1; i += 1;
} }

View File

@ -115,7 +115,7 @@ impl Syscall<'_> {
); );
self.sys_fcntl(args[0], args[1], args[2]) self.sys_fcntl(args[0], args[1], args[2])
} }
SYS_FLOCK => self.unimplemented("flock", Ok(0)), SYS_FLOCK => self.sys_flock(args[0], args[1]),
SYS_FSYNC => self.sys_fsync(args[0]), SYS_FSYNC => self.sys_fsync(args[0]),
SYS_FDATASYNC => self.sys_fdatasync(args[0]), SYS_FDATASYNC => self.sys_fdatasync(args[0]),
SYS_TRUNCATE => self.sys_truncate(args[0] as *const u8, args[1]), SYS_TRUNCATE => self.sys_truncate(args[0] as *const u8, args[1]),
@ -147,7 +147,7 @@ impl Syscall<'_> {
SYS_FCHOWNAT => self.unimplemented("fchownat", Ok(0)), SYS_FCHOWNAT => self.unimplemented("fchownat", Ok(0)),
SYS_FACCESSAT => self.sys_faccessat(args[0], args[1] as *const u8, args[2], args[3]), SYS_FACCESSAT => self.sys_faccessat(args[0], args[1] as *const u8, args[2], args[3]),
SYS_DUP3 => self.sys_dup3(args[0], args[1], args[2]), SYS_DUP3 => self.sys_dup3(args[0], args[1], args[2]),
SYS_PIPE2 => self.sys_pipe(args[0] as *mut u32), // TODO: handle `flags` SYS_PIPE2 => self.sys_pipe2(args[0] as *mut u32, args[1]), // TODO: handle `flags`
SYS_UTIMENSAT => self.sys_utimensat( SYS_UTIMENSAT => self.sys_utimensat(
args[0], args[0],
args[1] as *const u8, args[1] as *const u8,

2
user

@ -1 +1 @@
Subproject commit cde836c6d5e1f4260a8934984f21fe0df446f45c Subproject commit f395c36e49d841dd0b54e22b86891e8a87b612cf