Files
moss-kernel/src/drivers/fs/proc/task/task.rs
Matthew Leach bf4d1dbac4 process: make Tid globally unique
Make the `Tid` globally unique, rather than `Tgid` creating a new number
space. This allows ptrace to differentiate between threads when using
`-f` on a program which spawns threads.
2026-03-23 06:08:21 +00:00

79 lines
2.5 KiB
Rust

use crate::drivers::fs::proc::task::ProcTaskInode;
use crate::drivers::fs::proc::{get_inode_id, procfs};
use crate::process::{Tid, find_task_by_tid};
use alloc::boxed::Box;
use alloc::string::ToString;
use alloc::sync::Arc;
use alloc::vec::Vec;
use async_trait::async_trait;
use libkernel::error::FsError;
use libkernel::fs::attr::FileAttr;
use libkernel::fs::{DirStream, Dirent, FileType, Filesystem, Inode, InodeId, SimpleDirStream};
pub struct ProcTaskDirInode {
id: InodeId,
attr: FileAttr,
tid: Tid,
}
impl ProcTaskDirInode {
pub fn new(tid: Tid, inode_id: InodeId) -> Self {
Self {
id: inode_id,
attr: FileAttr {
file_type: FileType::Directory,
// Define appropriate file attributes for fdinfo.
..FileAttr::default()
},
tid,
}
}
}
#[async_trait]
impl Inode for ProcTaskDirInode {
fn id(&self) -> InodeId {
self.id
}
async fn getattr(&self) -> libkernel::error::Result<FileAttr> {
Ok(self.attr.clone())
}
async fn lookup(&self, name: &str) -> libkernel::error::Result<Arc<dyn Inode>> {
let tid = match name.parse::<u32>() {
Ok(tid) => Tid(tid),
Err(_) => return Err(FsError::NotFound.into()),
};
let fs = procfs();
let inode_id = InodeId::from_fsid_and_inodeid(
fs.id(),
get_inode_id(&[&self.tid.value().to_string(), &tid.value().to_string()]),
);
find_task_by_tid(self.tid).ok_or(FsError::NotFound)?;
Ok(Arc::new(ProcTaskInode::new(self.tid, true, inode_id)))
}
async fn readdir(&self, start_offset: u64) -> libkernel::error::Result<Box<dyn DirStream>> {
let process = &find_task_by_tid(self.tid).ok_or(FsError::NotFound)?.process;
let tasks = process.tasks.lock_save_irq();
let mut entries = Vec::new();
for (i, (_tid, task)) in tasks.iter().enumerate().skip(start_offset as usize) {
let Some(task) = task.upgrade() else {
continue;
};
let id = InodeId::from_fsid_and_inodeid(
procfs().id(),
get_inode_id(&[&self.tid.value().to_string(), &task.tid.value().to_string()]),
);
entries.push(Dirent {
id,
offset: (i + 1) as u64,
file_type: FileType::Directory,
name: task.tid.value().to_string(),
});
}
Ok(Box::new(SimpleDirStream::new(entries, start_offset)))
}
}