]> git.proxmox.com Git - proxmox-backup.git/blame - src/client/pxar_decode_writer.rs
switch from failure to anyhow
[proxmox-backup.git] / src / client / pxar_decode_writer.rs
CommitLineData
f7d4e4b5 1use anyhow::{Error};
e9c9409a
DM
2
3use std::thread;
4use std::os::unix::io::FromRawFd;
5use std::path::{Path, PathBuf};
6use std::io::Write;
e9c9409a 7
3dbfe5b1 8use crate::pxar;
e9c9409a 9
8968258b 10/// Writer implementation to deccode a .pxar archive (download).
e9c9409a 11
5defa71b 12pub struct PxarDecodeWriter {
e9c9409a
DM
13 pipe: Option<std::fs::File>,
14 child: Option<thread::JoinHandle<()>>,
15}
16
5defa71b 17impl Drop for PxarDecodeWriter {
e9c9409a
DM
18
19 fn drop(&mut self) {
20 drop(self.pipe.take());
21 self.child.take().unwrap().join().unwrap();
22 }
23}
24
5defa71b 25impl PxarDecodeWriter {
e9c9409a 26
5defa71b 27 pub fn new(base: &Path, verbose: bool) -> Result<Self, Error> {
e9c9409a
DM
28 let (rx, tx) = nix::unistd::pipe()?;
29
d5c34d98 30 let base = PathBuf::from(base);
e9c9409a
DM
31
32 let child = thread::spawn(move|| {
33 let mut reader = unsafe { std::fs::File::from_raw_fd(rx) };
f701d033
DM
34 let mut decoder = pxar::SequentialDecoder::new(&mut reader, pxar::flags::DEFAULT);
35 decoder.set_callback(move |path| {
5defa71b 36 if verbose {
02c93163 37 println!("{:?}", path);
5defa71b 38 }
e9c9409a 39 Ok(())
7dcbe051
CE
40 });
41
fa7e957c 42 if let Err(err) = decoder.restore(&base, &Vec::new()) {
8968258b 43 eprintln!("pxar decode failed - {}", err);
e9c9409a
DM
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
5defa71b 53impl Write for PxarDecodeWriter {
e9c9409a
DM
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}