diff --git a/src/drivers/fs/proc/task/mod.rs b/src/drivers/fs/proc/task/mod.rs index 97a6de7d..ba61d82e 100644 --- a/src/drivers/fs/proc/task/mod.rs +++ b/src/drivers/fs/proc/task/mod.rs @@ -132,12 +132,18 @@ impl Inode for ProcTaskInode { FileType::File, 8, )); + entries.push(Dirent::new( + "exe".to_string(), + InodeId::from_fsid_and_inodeid(PROCFS_ID, get_inode_id(&[&initial_str, "exe"])), + FileType::File, + 9, + )); if self.desc.tid().value() == self.desc.tgid().value() && !self.is_task_dir { entries.push(Dirent::new( "task".to_string(), InodeId::from_fsid_and_inodeid(PROCFS_ID, get_inode_id(&[&initial_str, "task"])), FileType::Directory, - 9, + 10, )); } diff --git a/src/drivers/fs/proc/task/task_file.rs b/src/drivers/fs/proc/task/task_file.rs index f7d76bf3..abfe3c12 100644 --- a/src/drivers/fs/proc/task/task_file.rs +++ b/src/drivers/fs/proc/task/task_file.rs @@ -18,6 +18,7 @@ pub enum TaskFileType { State, Stat, Maps, + Exe, } impl TryFrom<&str> for TaskFileType { @@ -32,6 +33,7 @@ impl TryFrom<&str> for TaskFileType { "cwd" => Ok(TaskFileType::Cwd), "root" => Ok(TaskFileType::Root), "maps" => Ok(TaskFileType::Maps), + "exe" => Ok(TaskFileType::Exe), _ => Err(()), } } @@ -56,7 +58,7 @@ impl ProcTaskFileInode { | TaskFileType::State | TaskFileType::Maps | TaskFileType::Stat => FileType::File, - TaskFileType::Cwd | TaskFileType::Root => FileType::Symlink, + TaskFileType::Cwd | TaskFileType::Root | TaskFileType::Exe => FileType::Symlink, }, permissions: FilePermissions::from_bits_retain(0o444), ..FileAttr::default() @@ -197,6 +199,14 @@ Threads:\t{tasks}\n", output } + TaskFileType::Exe => { + if let Some(exe) = task.process.executable.lock_save_irq().clone() { + // TODO: Check if exists + exe.as_str().to_string() + } else { + "(deleted)".to_string() + } + } } } else { "State:\tGone\n".to_string() @@ -243,6 +253,28 @@ Threads:\t{tasks}\n", } else { Err(FsError::NotFound.into()) }; + } else if let TaskFileType::Exe = self.file_type { + let tid = self.tid; + let task_list = TASK_LIST.lock_save_irq(); + let id = task_list + .iter() + .find(|(desc, _)| desc.tid() == tid) + .map(|(desc, _)| *desc); + drop(task_list); + let task_details = if let Some(desc) = id { + find_task_by_descriptor(&desc) + } else { + None + }; + return if let Some(task) = task_details { + if let Some(exe) = task.process.executable.lock_save_irq().clone() { + Ok(exe.as_str().to_string().into()) + } else { + Err(FsError::NotFound.into()) + } + } else { + Err(FsError::NotFound.into()) + }; } Err(KernelError::NotSupported) } diff --git a/src/process/exec.rs b/src/process/exec.rs index 8d2bb8d6..54683257 100644 --- a/src/process/exec.rs +++ b/src/process/exec.rs @@ -12,6 +12,7 @@ use crate::{ process::{ctx::Context, thread_group::signal::SignalActionState}, sched::current::current_task, }; +use alloc::borrow::ToOwned; use alloc::{string::String, vec}; use alloc::{string::ToString, sync::Arc, vec::Vec}; use auxv::{AT_BASE, AT_ENTRY, AT_NULL, AT_PAGESZ, AT_PHDR, AT_PHENT, AT_PHNUM, AT_RANDOM}; @@ -212,6 +213,7 @@ async fn exec_elf( let mut fd_table = current_task().fd_table.lock_save_irq().clone(); fd_table.close_cloexec_entries().await; *current_task().fd_table.lock_save_irq() = fd_table; + *current_task().process.executable.lock_save_irq() = Some(path.to_owned()); Ok(()) } diff --git a/src/process/thread_group.rs b/src/process/thread_group.rs index 56edf9cb..621eec2d 100644 --- a/src/process/thread_group.rs +++ b/src/process/thread_group.rs @@ -10,6 +10,7 @@ use core::{ fmt::Display, sync::atomic::{AtomicU32, Ordering}, }; +use libkernel::fs::pathbuf::PathBuf; use pid::PidT; use rsrc_lim::ResourceLimits; use signal::{SigId, SigSet, SignalActionState}; @@ -104,6 +105,7 @@ pub struct ThreadGroup { pub utime: AtomicUsize, pub stime: AtomicUsize, pub last_account: AtomicUsize, + pub executable: SpinLock>, next_tid: AtomicU32, } diff --git a/src/process/thread_group/builder.rs b/src/process/thread_group/builder.rs index d177c6f7..ad2de0f9 100644 --- a/src/process/thread_group/builder.rs +++ b/src/process/thread_group/builder.rs @@ -90,6 +90,7 @@ impl ThreadGroupBuilder { next_tid: AtomicU32::new(1), state: SpinLock::new(ProcessState::Running), tasks: SpinLock::new(BTreeMap::new()), + executable: SpinLock::new(None), }); TG_LIST