mirror of
git://git.proxmox.com/git/pxar.git
synced 2025-02-03 21:47:00 +03:00
decoder: handle fifos and sockets properly
These are the only items which don't get "finalized" by a dedicated packet (like a PAYLOAD or DEVICE), so for these we need to check at the next FILENAME or GOODBYE entry. Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
af35697966
commit
2287d8b26c
@ -158,7 +158,13 @@ pub(crate) struct DecoderImpl<T> {
|
||||
enum State {
|
||||
Begin,
|
||||
Default,
|
||||
InPayload { offset: u64 },
|
||||
InPayload {
|
||||
offset: u64,
|
||||
},
|
||||
|
||||
/// file entries with no data (fifo, socket)
|
||||
InSpecialFile,
|
||||
|
||||
InGoodbyeTable,
|
||||
InDirectory,
|
||||
Eof,
|
||||
@ -242,6 +248,11 @@ impl<I: SeqRead> DecoderImpl<I> {
|
||||
self.state = State::Default;
|
||||
continue;
|
||||
}
|
||||
State::InSpecialFile => {
|
||||
self.entry.clear_data();
|
||||
self.state = State::InDirectory;
|
||||
self.entry.kind = EntryKind::Directory;
|
||||
}
|
||||
State::InDirectory => {
|
||||
// We're at the next FILENAME or GOODBYE item.
|
||||
}
|
||||
@ -469,9 +480,21 @@ impl<I: SeqRead> DecoderImpl<I> {
|
||||
return Ok(ItemResult::Entry);
|
||||
}
|
||||
format::PXAR_FILENAME | format::PXAR_GOODBYE => {
|
||||
self.state = State::InDirectory;
|
||||
self.entry.kind = EntryKind::Directory;
|
||||
return Ok(ItemResult::Entry);
|
||||
if self.entry.metadata.is_fifo() {
|
||||
self.state = State::InSpecialFile;
|
||||
self.entry.kind = EntryKind::Fifo;
|
||||
return Ok(ItemResult::Entry);
|
||||
} else if self.entry.metadata.is_socket() {
|
||||
self.state = State::InSpecialFile;
|
||||
self.entry.kind = EntryKind::Socket;
|
||||
return Ok(ItemResult::Entry);
|
||||
} else {
|
||||
// As a shortcut this is copy-pasted to `next_do`'s `InSpecialFile` case.
|
||||
// Keep in mind when editing this!
|
||||
self.state = State::InDirectory;
|
||||
self.entry.kind = EntryKind::Directory;
|
||||
return Ok(ItemResult::Entry);
|
||||
}
|
||||
}
|
||||
_ => io_bail!("unexpected entry type: {:x}", self.current_header.htype),
|
||||
}
|
||||
|
@ -198,6 +198,16 @@ impl Entry {
|
||||
pub fn is_regular_file(&self) -> bool {
|
||||
(self.mode & mode::IFMT) == mode::IFREG
|
||||
}
|
||||
|
||||
/// Check whether this is a named pipe (FIFO).
|
||||
pub fn is_fifo(&self) -> bool {
|
||||
(self.mode & mode::IFMT) == mode::IFIFO
|
||||
}
|
||||
|
||||
/// Check whether this is a named socket.
|
||||
pub fn is_socket(&self) -> bool {
|
||||
(self.mode & mode::IFMT) == mode::IFSOCK
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&std::fs::Metadata> for Entry {
|
||||
|
18
src/lib.rs
18
src/lib.rs
@ -101,6 +101,18 @@ impl Metadata {
|
||||
self.stat.is_regular_file()
|
||||
}
|
||||
|
||||
/// Check whether this is a named pipe (FIFO).
|
||||
#[inline]
|
||||
pub fn is_fifo(&self) -> bool {
|
||||
self.stat.is_fifo()
|
||||
}
|
||||
|
||||
/// Check whether this is a named socket.
|
||||
#[inline]
|
||||
pub fn is_socket(&self) -> bool {
|
||||
self.stat.is_socket()
|
||||
}
|
||||
|
||||
/// Get the mtime as duration since the epoch.
|
||||
pub fn mtime_as_duration(&self) -> std::time::Duration {
|
||||
self.stat.mtime_as_duration()
|
||||
@ -156,6 +168,12 @@ pub enum EntryKind {
|
||||
/// Device node.
|
||||
Device(format::Device),
|
||||
|
||||
/// Named unix socket.
|
||||
Socket,
|
||||
|
||||
/// Named pipe.
|
||||
Fifo,
|
||||
|
||||
/// Regular file.
|
||||
File { size: u64, offset: Option<u64> },
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user