1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 08:06: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 O_NONBLOCK: usize = 04000;
pub const O_CLOEXEC: usize = 02000000; /* set close_on_exec */
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;
/* 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 {
inode: Arc<dyn INode>,
offset: Arc<Mutex<u64>>,
@ -21,19 +31,6 @@ pub struct FileHandle {
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)]
pub struct OpenOptions {
pub read: bool,
@ -66,17 +63,7 @@ impl FileHandle {
};
}
pub fn clone_shared(&self) -> Self {
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
// do almost as default clone does, but with fd_cloexec specified
pub fn dup(&self, fd_cloexec: bool) -> Self {
FileHandle {
inode: self.inode.clone(),

View File

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

View File

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

View File

@ -344,24 +344,9 @@ impl Thread {
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 {
vm: vm.clone(),
files,
files: proc.files.clone(), // share open file descriptions
cwd: proc.cwd.clone(),
exec_path: proc.exec_path.clone(),
futexes: BTreeMap::default(),

View File

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

View File

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

View File

@ -115,7 +115,7 @@ impl Syscall<'_> {
);
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_FDATASYNC => self.sys_fdatasync(args[0]),
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_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_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(
args[0],
args[1] as *const u8,

2
user

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