From b946f8606d7c9d0138e7172de5a93e1ca53be6ee Mon Sep 17 00:00:00 2001 From: function2-llx Date: Fri, 8 May 2020 22:24:42 +0800 Subject: [PATCH] fix fork(dup) --- kernel/src/fs/fcntl.rs | 1 + kernel/src/fs/file.rs | 35 +++++++++------------------- kernel/src/fs/file_like.rs | 11 ++++----- kernel/src/fs/pipe.rs | 1 + kernel/src/process/structs.rs | 17 +------------- kernel/src/syscall/fs.rs | 44 ++++++++++++++++++++++++++++------- kernel/src/syscall/misc.rs | 3 ++- kernel/src/syscall/mod.rs | 4 ++-- user | 2 +- 9 files changed, 60 insertions(+), 58 deletions(-) diff --git a/kernel/src/fs/fcntl.rs b/kernel/src/fs/fcntl.rs index 8ece2a1b..86132ddb 100644 --- a/kernel/src/fs/fcntl.rs +++ b/kernel/src/fs/fcntl.rs @@ -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; diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index 95bdf8ab..29dcbd44 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -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, offset: Arc>, @@ -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(), diff --git a/kernel/src/fs/file_like.rs b/kernel/src/fs/file_like.rs index 7ed78232..cec9c761 100644 --- a/kernel/src/fs/file_like.rs +++ b/kernel/src/fs/file_like.rs @@ -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()), } } diff --git a/kernel/src/fs/pipe.rs b/kernel/src/fs/pipe.rs index a4ae920f..fcb7697b 100644 --- a/kernel/src/fs/pipe.rs +++ b/kernel/src/fs/pipe.rs @@ -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 { diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index d2c48e75..d3018fe2 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -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(), diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 6fcddffe..0e29e750 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -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( diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index 71ec2b87..b9bf0c89 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -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; } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index d4e490b5..758625af 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -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, diff --git a/user b/user index cde836c6..f395c36e 160000 --- a/user +++ b/user @@ -1 +1 @@ -Subproject commit cde836c6d5e1f4260a8934984f21fe0df446f45c +Subproject commit f395c36e49d841dd0b54e22b86891e8a87b612cf