1use super::*;
2use crate::{err, InodeNum};
3
4impl<R: Backend> Ufs<R> {
5 #[doc(alias = "readlink")]
7 pub fn symlink_read(&mut self, inr: InodeNum) -> IoResult<Vec<u8>> {
8 let ino = self.read_inode(inr)?;
9
10 if ino.kind() != InodeType::Symlink {
11 return Err(err!(EINVAL));
12 }
13
14 match &ino.data {
15 InodeData::Shortlink(link) => {
16 assert_eq!(ino.blocks, 0);
17 let len = ino.size as usize;
18 Ok(link[0..len].to_vec())
19 }
20 InodeData::Blocks { .. } => {
21 assert!(ino.blocks <= 8);
23
24 let len = ino.size as usize;
25 let mut buf = vec![0u8; self.superblock.bsize as usize];
26 self.inode_read_block(inr, &ino, 0, &mut buf)?;
27 buf.resize(len, 0u8);
28 Ok(buf)
29 }
30 }
31 }
32
33 fn symlink_set(&mut self, inr: InodeNum, link: &OsStr) -> IoResult<()> {
34 let mut ino = self.read_inode(inr)?;
35 if ino.kind() != InodeType::Symlink {
36 return Err(err!(EINVAL));
37 }
38
39 assert_eq!(ino.blocks, 0);
40
41 let len = link.len();
42 if len < UFS_SLLEN {
43 let mut data = [0u8; UFS_SLLEN];
44 data[0..len].copy_from_slice(link.as_bytes());
45 ino.data = InodeData::Shortlink(data);
46 } else {
47 todo!("creating long symlinks");
48 }
49 ino.size = len as u64;
50 self.write_inode(inr, &ino)?;
51 Ok(())
52 }
53
54 pub fn symlink(
55 &mut self,
56 dinr: InodeNum,
57 name: &OsStr,
58 link: &OsStr,
59 uid: u32,
60 gid: u32,
61 ) -> IoResult<InodeAttr> {
62 self.assert_rw()?;
63 let attr = self.mknod(dinr, name, InodeType::Symlink, 0o777, uid, gid)?;
64 self.symlink_set(attr.inr, link)?;
65 Ok(attr)
66 }
67}