mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 16:16:16 +04:00
impl pseudo INode '/proc/self/exe'
This commit is contained in:
parent
bd158e4e74
commit
c885ea6d77
4
kernel/Cargo.lock
generated
4
kernel/Cargo.lock
generated
@ -402,12 +402,12 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rcore-fs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/rcore-os/rcore-fs#64d399fe664927f14853c22943a4bdeb34095f99"
|
||||
source = "git+https://github.com/rcore-os/rcore-fs#6f282baf2fe928d2c9774e526e63125684855221"
|
||||
|
||||
[[package]]
|
||||
name = "rcore-fs-sfs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/rcore-os/rcore-fs#64d399fe664927f14853c22943a4bdeb34095f99"
|
||||
source = "git+https://github.com/rcore-os/rcore-fs#6f282baf2fe928d2c9774e526e63125684855221"
|
||||
dependencies = [
|
||||
"bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -10,12 +10,14 @@ pub use self::file::*;
|
||||
pub use self::file_like::*;
|
||||
pub use self::pipe::Pipe;
|
||||
pub use self::stdio::{STDIN, STDOUT};
|
||||
pub use self::pseudo::*;
|
||||
|
||||
mod device;
|
||||
mod file;
|
||||
mod file_like;
|
||||
mod pipe;
|
||||
mod stdio;
|
||||
mod pseudo;
|
||||
|
||||
/// Hard link user programs
|
||||
#[cfg(feature = "link_user")]
|
||||
|
78
kernel/src/fs/pseudo.rs
Normal file
78
kernel/src/fs/pseudo.rs
Normal file
@ -0,0 +1,78 @@
|
||||
//! Pseudo file system INode
|
||||
|
||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||
use core::any::Any;
|
||||
|
||||
use rcore_fs::vfs::*;
|
||||
|
||||
pub struct Pseudo {
|
||||
content: Vec<u8>,
|
||||
type_: FileType,
|
||||
}
|
||||
|
||||
impl Pseudo {
|
||||
pub fn new(s: &str, type_: FileType) -> Self {
|
||||
Pseudo {
|
||||
content: Vec::from(s.as_bytes()),
|
||||
type_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: better way to provide default impl?
|
||||
macro_rules! impl_inode {
|
||||
() => {
|
||||
fn set_metadata(&self, _metadata: &Metadata) -> Result<()> { Ok(()) }
|
||||
fn sync_all(&self) -> Result<()> { Ok(()) }
|
||||
fn sync_data(&self) -> Result<()> { Ok(()) }
|
||||
fn resize(&self, _len: usize) -> Result<()> { Err(FsError::NotSupported) }
|
||||
fn create(&self, _name: &str, _type_: FileType, _mode: u32) -> Result<Arc<INode>> { Err(FsError::NotDir) }
|
||||
fn unlink(&self, _name: &str) -> Result<()> { Err(FsError::NotDir) }
|
||||
fn link(&self, _name: &str, _other: &Arc<INode>) -> Result<()> { Err(FsError::NotDir) }
|
||||
fn move_(&self, _old_name: &str, _target: &Arc<INode>, _new_name: &str) -> Result<()> { Err(FsError::NotDir) }
|
||||
fn find(&self, _name: &str) -> Result<Arc<INode>> { Err(FsError::NotDir) }
|
||||
fn get_entry(&self, _id: usize) -> Result<String> { Err(FsError::NotDir) }
|
||||
fn io_control(&self, cmd: u32, data: usize) -> Result<()> { Err(FsError::NotSupported) }
|
||||
fn fs(&self) -> Arc<FileSystem> { unimplemented!() }
|
||||
fn as_any_ref(&self) -> &Any { self }
|
||||
};
|
||||
}
|
||||
|
||||
impl INode for Pseudo {
|
||||
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
if offset >= self.content.len() {
|
||||
return Ok(0);
|
||||
}
|
||||
let len = (self.content.len() - offset).min(buf.len());
|
||||
buf[..len].copy_from_slice(&self.content[offset..offset + len]);
|
||||
Ok(len)
|
||||
}
|
||||
fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result<usize> {
|
||||
Err(FsError::NotSupported)
|
||||
}
|
||||
fn poll(&self) -> Result<PollStatus> {
|
||||
Ok(PollStatus {
|
||||
read: true,
|
||||
write: false,
|
||||
error: false,
|
||||
})
|
||||
}
|
||||
fn metadata(&self) -> Result<Metadata> {
|
||||
Ok(Metadata {
|
||||
dev: 0,
|
||||
inode: 0,
|
||||
size: self.content.len(),
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: Timespec { sec: 0, nsec: 0 },
|
||||
mtime: Timespec { sec: 0, nsec: 0 },
|
||||
ctime: Timespec { sec: 0, nsec: 0 },
|
||||
type_: self.type_,
|
||||
mode: 0,
|
||||
nlinks: 0,
|
||||
uid: 0,
|
||||
gid: 0,
|
||||
})
|
||||
}
|
||||
impl_inode!();
|
||||
}
|
@ -59,6 +59,7 @@ pub struct Process {
|
||||
pub vm: MemorySet,
|
||||
pub files: BTreeMap<usize, FileLike>,
|
||||
pub cwd: String,
|
||||
pub exec_path: String,
|
||||
futexes: BTreeMap<usize, Arc<Condvar>>,
|
||||
|
||||
// relationship
|
||||
@ -116,6 +117,7 @@ impl Thread {
|
||||
vm,
|
||||
files: BTreeMap::default(),
|
||||
cwd: String::from("/"),
|
||||
exec_path: String::new(),
|
||||
futexes: BTreeMap::default(),
|
||||
pid: Pid(0),
|
||||
parent: None,
|
||||
@ -137,7 +139,6 @@ impl Thread {
|
||||
envs: Vec<String>,
|
||||
) -> Result<(MemorySet, usize, usize), &'static str> {
|
||||
// Read data
|
||||
use crate::fs::INodeExt;
|
||||
let data = inode
|
||||
.read_as_vec()
|
||||
.map_err(|_| "failed to read from INode")?;
|
||||
@ -286,6 +287,7 @@ impl Thread {
|
||||
vm,
|
||||
files,
|
||||
cwd: String::from("/"),
|
||||
exec_path: String::from(exec_path),
|
||||
futexes: BTreeMap::default(),
|
||||
pid: Pid(0),
|
||||
parent: None,
|
||||
@ -308,6 +310,7 @@ impl Thread {
|
||||
vm,
|
||||
files: proc.files.clone(),
|
||||
cwd: proc.cwd.clone(),
|
||||
exec_path: proc.exec_path.clone(),
|
||||
futexes: BTreeMap::default(),
|
||||
pid: Pid(0),
|
||||
parent: Some(self.proc.clone()),
|
||||
|
@ -361,7 +361,10 @@ pub fn sys_readlinkat(dirfd: usize, path: *const u8, base: *mut u8, len: usize)
|
||||
let proc = process();
|
||||
let path = unsafe { proc.vm.check_and_clone_cstr(path)? };
|
||||
let slice = unsafe { proc.vm.check_write_array(base, len)? };
|
||||
info!("readlink: path: {:?}, base: {:?}, len: {}", path, base, len);
|
||||
info!(
|
||||
"readlinkat: dirfd: {}, path: {:?}, base: {:?}, len: {}",
|
||||
dirfd as isize, path, base, len
|
||||
);
|
||||
|
||||
let inode = proc.lookup_inode_at(dirfd, &path, false)?;
|
||||
if inode.metadata()?.type_ == FileType::SymLink {
|
||||
@ -753,6 +756,14 @@ impl Process {
|
||||
"lookup_inode_at: dirfd: {:?}, cwd: {:?}, path: {:?}, follow: {:?}",
|
||||
dirfd as isize, self.cwd, path, follow
|
||||
);
|
||||
// hard code special path
|
||||
match path {
|
||||
"/proc/self/exe" => {
|
||||
return Ok(Arc::new(Pseudo::new(&self.exec_path, FileType::SymLink)));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let follow_max_depth = if follow { FOLLOW_MAX_DEPTH } else { 0 };
|
||||
if dirfd == AT_FDCWD {
|
||||
Ok(ROOT_INODE
|
||||
|
@ -252,10 +252,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
|
||||
};
|
||||
if !pid.is_init() {
|
||||
// we trust pid 0 process
|
||||
debug!(
|
||||
"{}:{}:{} syscall id {} ret with {:x?}",
|
||||
cid, pid, tid, id, ret
|
||||
);
|
||||
info!("=> {:x?}", ret);
|
||||
}
|
||||
match ret {
|
||||
Ok(code) => code as isize,
|
||||
|
@ -174,25 +174,23 @@ pub fn sys_exec(
|
||||
let inode = proc.lookup_inode(&path)?;
|
||||
|
||||
// Make new Thread
|
||||
match Thread::new_user_vm(&inode, &path, args, envs) {
|
||||
Ok((mut vm, entry_addr, ustack_top)) => {
|
||||
// Activate new page table
|
||||
core::mem::swap(&mut proc.vm, &mut vm);
|
||||
unsafe {
|
||||
proc.vm.activate();
|
||||
}
|
||||
let (mut vm, entry_addr, ustack_top) =
|
||||
Thread::new_user_vm(&inode, &path, args, envs).map_err(|_| SysError::EINVAL)?;
|
||||
|
||||
// Modify the TrapFrame
|
||||
*tf = TrapFrame::new_user_thread(entry_addr, ustack_top);
|
||||
|
||||
info!("exec:END: path: {:?}", path);
|
||||
Ok(0)
|
||||
}
|
||||
Err(err) => {
|
||||
info!("exec failed with {}", err);
|
||||
Err(SysError::EINVAL)
|
||||
}
|
||||
// Activate new page table
|
||||
core::mem::swap(&mut proc.vm, &mut vm);
|
||||
unsafe {
|
||||
proc.vm.activate();
|
||||
}
|
||||
|
||||
// Modify exec path
|
||||
proc.exec_path = path.clone();
|
||||
|
||||
// Modify the TrapFrame
|
||||
*tf = TrapFrame::new_user_thread(entry_addr, ustack_top);
|
||||
|
||||
info!("exec:END: path: {:?}", path);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn sys_yield() -> SysResult {
|
||||
|
Loading…
Reference in New Issue
Block a user