mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2026-04-17 21:58:54 -04:00
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.
79 lines
2.5 KiB
Rust
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)))
|
|
}
|
|
}
|