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