use alloc::{borrow::Cow, boxed::Box, format, sync::Arc};
use axfs_ng_vfs::{Filesystem, NodePermission, VfsError, VfsResult};
use crate::{
ipc::mqueue::{lookup_by_short_name, registry_names},
pseudofs::{NodeOpsMux, SimpleDir, SimpleDirOps, SimpleFile, SimpleFs},
};
const MQUEUE_MAGIC: u32 = 0x1980_0202;
struct MqueueDir {
fs: Arc<SimpleFs>,
}
impl SimpleDirOps for MqueueDir {
fn child_names<'a>(&'a self) -> Box<dyn Iterator<Item = Cow<'a, str>> + 'a> {
Box::new(registry_names().into_iter().map(Cow::Owned))
}
fn lookup_child(&self, name: &str) -> VfsResult<NodeOpsMux> {
let queue = lookup_by_short_name(name).ok_or(VfsError::NotFound)?;
let file = {
let queue = queue.clone();
SimpleFile::new_regular(self.fs.clone(), move || {
let (qsize, notify, signo, notify_pid) = queue.report();
Ok(format!(
"QSIZE:{qsize} NOTIFY:{notify} SIGNO:{signo} NOTIFY_PID:{notify_pid}\n"
))
})
};
let (atime, ctime, mtime) = queue.times();
file.set_attrs(
NodePermission::from_bits_truncate(queue.mode()),
queue.uid(),
queue.gid(),
atime,
mtime,
ctime,
);
file.set_fixed_size(queue.inode_size());
Ok(NodeOpsMux::File(file))
}
fn is_cacheable(&self) -> bool {
false
}
}
pub fn new_mqueuefs() -> Filesystem {
SimpleFs::new_with("mqueue".into(), MQUEUE_MAGIC, |fs| {
SimpleDir::new_maker(fs.clone(), Arc::new(MqueueDir { fs }))
})
}