]> git.proxmox.com Git - proxmox-backup.git/blame_incremental - src/client/pxar_decode_writer.rs
switch from failure to anyhow
[proxmox-backup.git] / src / client / pxar_decode_writer.rs
... / ...
CommitLineData
1use anyhow::{Error};
2
3use std::thread;
4use std::os::unix::io::FromRawFd;
5use std::path::{Path, PathBuf};
6use std::io::Write;
7
8use crate::pxar;
9
10/// Writer implementation to deccode a .pxar archive (download).
11
12pub struct PxarDecodeWriter {
13 pipe: Option<std::fs::File>,
14 child: Option<thread::JoinHandle<()>>,
15}
16
17impl Drop for PxarDecodeWriter {
18
19 fn drop(&mut self) {
20 drop(self.pipe.take());
21 self.child.take().unwrap().join().unwrap();
22 }
23}
24
25impl PxarDecodeWriter {
26
27 pub fn new(base: &Path, verbose: bool) -> Result<Self, Error> {
28 let (rx, tx) = nix::unistd::pipe()?;
29
30 let base = PathBuf::from(base);
31
32 let child = thread::spawn(move|| {
33 let mut reader = unsafe { std::fs::File::from_raw_fd(rx) };
34 let mut decoder = pxar::SequentialDecoder::new(&mut reader, pxar::flags::DEFAULT);
35 decoder.set_callback(move |path| {
36 if verbose {
37 println!("{:?}", path);
38 }
39 Ok(())
40 });
41
42 if let Err(err) = decoder.restore(&base, &Vec::new()) {
43 eprintln!("pxar decode failed - {}", err);
44 }
45 });
46
47 let pipe = unsafe { std::fs::File::from_raw_fd(tx) };
48
49 Ok(Self { pipe: Some(pipe), child: Some(child) })
50 }
51}
52
53impl Write for PxarDecodeWriter {
54
55 fn write(&mut self, buffer: &[u8]) -> Result<usize, std::io::Error> {
56 let pipe = match self.pipe {
57 Some(ref mut pipe) => pipe,
58 None => unreachable!(),
59 };
60 pipe.write(buffer)
61 }
62
63 fn flush(&mut self) -> Result<(), std::io::Error> {
64 let pipe = match self.pipe {
65 Some(ref mut pipe) => pipe,
66 None => unreachable!(),
67 };
68 pipe.flush()
69 }
70}