Add test for extracting hardlinks; Fix multiple bugs revealed in tests; TODO: fix possible io errors caused by tests running in parallel;
This commit is contained in:
parent
0ef17ca2ec
commit
71e0ba30d1
62
src/node.rs
62
src/node.rs
@ -247,19 +247,38 @@ impl Node {
|
||||
match self.filetype {
|
||||
FileType::Eof => {}
|
||||
FileType::Fifo => {
|
||||
nix::mkfifo(&path, self.mode.into())?;
|
||||
if n_path.exists() {
|
||||
fs::remove_file(&n_path)?;
|
||||
}
|
||||
nix::mkfifo(&n_path.to_str().ok_or(Error::BadPath)?, self.mode.into())?;
|
||||
if euid == 0 {
|
||||
nix::chown(&path, self.uid, self.gid)?;
|
||||
nix::chown(&n_path.to_str().ok_or(Error::BadPath)?, self.uid, self.gid)?;
|
||||
}
|
||||
}
|
||||
FileType::Block(ref b) => {
|
||||
if euid == 0 {
|
||||
nix::mknod(&path, self.mode.into(), b.major, b.minor)?;
|
||||
if n_path.exists() {
|
||||
fs::remove_file(&n_path)?;
|
||||
}
|
||||
nix::mknod(
|
||||
&n_path.to_str().ok_or(Error::BadPath)?,
|
||||
self.mode.into(),
|
||||
b.major,
|
||||
b.minor,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
FileType::Character(ref c) => {
|
||||
if euid == 0 {
|
||||
nix::mknod(&path, self.mode.into(), c.major, c.minor)?;
|
||||
if n_path.exists() {
|
||||
fs::remove_file(&n_path)?;
|
||||
}
|
||||
nix::mknod(
|
||||
&n_path.to_str().ok_or(Error::BadPath)?,
|
||||
self.mode.into(),
|
||||
c.major,
|
||||
c.minor,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
FileType::Normal(ref n) => {
|
||||
@ -273,9 +292,9 @@ impl Node {
|
||||
writer.write_all(&n.data)?;
|
||||
}
|
||||
if euid == 0 {
|
||||
nix::chown(&path, self.uid, self.gid)?;
|
||||
nix::chown(&n_path.to_str().ok_or(Error::BadPath)?, self.uid, self.gid)?;
|
||||
}
|
||||
nix::chmod(&path, self.mode.into())?;
|
||||
nix::chmod(&n_path.to_str().ok_or(Error::BadPath)?, self.mode.into())?;
|
||||
}
|
||||
FileType::HardLink(ref t) => {
|
||||
let target = if let Some(prefix) = prefix {
|
||||
@ -283,7 +302,13 @@ impl Node {
|
||||
} else {
|
||||
t.to_string()
|
||||
};
|
||||
fs::hard_link(target, &path)?;
|
||||
if !PathBuf::from(&target).exists() {
|
||||
let _f = fs::File::create(&target)?;
|
||||
}
|
||||
if PathBuf::from(&n_path).exists() {
|
||||
fs::remove_file(&n_path)?;
|
||||
}
|
||||
fs::hard_link(target, &n_path)?;
|
||||
}
|
||||
FileType::SoftLink(ref t) => {
|
||||
if n_path.exists() {
|
||||
@ -292,7 +317,7 @@ impl Node {
|
||||
symlink(t, &n_path)?;
|
||||
}
|
||||
FileType::Directory => {
|
||||
self.mkdir(&PathBuf::from(&path))?;
|
||||
self.mkdir(&n_path)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@ -542,4 +567,25 @@ mod tests {
|
||||
let tgt = fs::read_link("test/output/test/lilnk.txt").unwrap();
|
||||
assert_eq!(tgt, PathBuf::from("li.txt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_hardlink() {
|
||||
let links = Mutex::new(HashMap::new());
|
||||
if !PathBuf::from("test/lihlnk.txt").exists() {
|
||||
fs::hard_link("test/li.txt", "test/lihlnk.txt").unwrap();
|
||||
}
|
||||
let node0 = Node::from_path("test/li.txt", Algorithm::Sha256, &links).unwrap();
|
||||
let FileType::Normal(_) = node0.filetype else {
|
||||
eprintln!("Created wrong filetype for node0: {:?}", node0.filetype);
|
||||
panic!();
|
||||
};
|
||||
let node1 = Node::from_path("test/lihlnk.txt", Algorithm::Sha256, &links).unwrap();
|
||||
let FileType::HardLink(ref tgt) = node1.filetype else {
|
||||
eprintln!("Created wrong filetype for node1: {:?}", node1.filetype);
|
||||
panic!();
|
||||
};
|
||||
assert_eq!(tgt, "test/li.txt");
|
||||
node1.extract(Some("test/output")).unwrap();
|
||||
node0.extract(Some("test/output")).unwrap();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user