starnix_core/vfs/
symlink_node.rs1use crate::task::CurrentTask;
6use crate::vfs::{
7 FsNode, FsNodeInfo, FsNodeOps, FsStr, FsString, MemoryXattrStorage, SymlinkTarget,
8 XattrStorage as _, fs_node_impl_symlink, fs_node_impl_xattr_delegate,
9};
10use starnix_sync::{FileOpsCore, Locked};
11use starnix_uapi::auth::FsCred;
12use starnix_uapi::errors::Errno;
13use starnix_uapi::file_mode::mode;
14
15pub struct SymlinkNode {
17 target: FsString,
19 xattrs: MemoryXattrStorage,
20}
21
22impl SymlinkNode {
23 pub fn new(target: &FsStr, owner: FsCred) -> (Self, FsNodeInfo) {
24 let size = target.len();
25 let mut info = FsNodeInfo::new(mode!(IFLNK, 0o777), owner);
26 info.size = size;
27 (Self { target: target.to_owned(), xattrs: Default::default() }, info)
28 }
29}
30
31impl FsNodeOps for SymlinkNode {
32 fs_node_impl_symlink!();
33 fs_node_impl_xattr_delegate!(self, self.xattrs);
34
35 fn readlink(
36 &self,
37 _locked: &mut Locked<FileOpsCore>,
38 _node: &FsNode,
39 _current_task: &CurrentTask,
40 ) -> Result<SymlinkTarget, Errno> {
41 Ok(SymlinkTarget::Path(self.target.clone()))
42 }
43}
44
45pub struct CallbackSymlinkNode<F>
47where
48 F: Fn() -> Result<SymlinkTarget, Errno> + Send + Sync + 'static,
49{
50 callback: F,
51 xattrs: MemoryXattrStorage,
52}
53
54impl<F> CallbackSymlinkNode<F>
55where
56 F: Fn() -> Result<SymlinkTarget, Errno> + Send + Sync + 'static,
57{
58 pub fn new(callback: F) -> CallbackSymlinkNode<F> {
59 CallbackSymlinkNode { callback, xattrs: Default::default() }
60 }
61}
62
63impl<F> FsNodeOps for CallbackSymlinkNode<F>
64where
65 F: Fn() -> Result<SymlinkTarget, Errno> + Send + Sync + 'static,
66{
67 fs_node_impl_symlink!();
68 fs_node_impl_xattr_delegate!(self, self.xattrs);
69
70 fn readlink(
71 &self,
72 _locked: &mut Locked<FileOpsCore>,
73 _node: &FsNode,
74 _current_task: &CurrentTask,
75 ) -> Result<SymlinkTarget, Errno> {
76 (self.callback)()
77 }
78}