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:
parent
e44bc7e6d2
commit
b946f8606d
@ -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;
|
||||
|
@ -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(),
|
||||
|
@ -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()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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(),
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
2
user
@ -1 +1 @@
|
||||
Subproject commit cde836c6d5e1f4260a8934984f21fe0df446f45c
|
||||
Subproject commit f395c36e49d841dd0b54e22b86891e8a87b612cf
|
Loading…
Reference in New Issue
Block a user