diff --git a/CHANGELOG.md b/CHANGELOG.md index a653681..15ca615 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This project follows [semantic versioning](http://semver.org). * [added] Added `copy` subcommand * [added] Added support for xattrs in fuse mount * [added] Added support for block/char devices +* [added] Added support for fifo files * [modified] Also documenting common flags in subcommands * [modified] Using repository aliases (**conversion needed**) * [modified] Remote path must be absolute diff --git a/docs/repository_readme.md b/docs/repository_readme.md index 8953d51..f65950e 100644 --- a/docs/repository_readme.md +++ b/docs/repository_readme.md @@ -307,14 +307,16 @@ The `FileType` describes the type of an inode. children - `Symlink` means a symlink that points to a target - `BlockDevice` means a block device -- `CharDevice` mean a character device +- `CharDevice` means a character device +- `NamedPipe` means a named pipe/fifo FileType { File => 0, Directory => 1, Symlink => 2, BlockDevice => 3, - CharDevice => 4 + CharDevice => 4, + NamedPipe => 5 } diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 592b1ff..37ce4eb 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -156,7 +156,8 @@ pub fn format_inode_one_line(inode: &Inode) -> String { FileType::BlockDevice | FileType::CharDevice => { let device = inode.device.unwrap_or((0, 0)); format!("{:25}\t{:12}\t{}:{}", inode.name, inode.file_type, device.0, device.1) - } + }, + FileType::NamedPipe => format!("{:25}\t fifo", inode.name) } } diff --git a/src/mount.rs b/src/mount.rs index f016164..2ef5072 100644 --- a/src/mount.rs +++ b/src/mount.rs @@ -70,7 +70,8 @@ fn convert_file_type(kind: FileType) -> fuse::FileType { FileType::File => fuse::FileType::RegularFile, FileType::Symlink => fuse::FileType::Symlink, FileType::BlockDevice => fuse::FileType::BlockDevice, - FileType::CharDevice => fuse::FileType::CharDevice + FileType::CharDevice => fuse::FileType::CharDevice, + FileType::NamedPipe => fuse::FileType::NamedPipe } } diff --git a/src/repository/metadata.rs b/src/repository/metadata.rs index c85560a..5f23556 100644 --- a/src/repository/metadata.rs +++ b/src/repository/metadata.rs @@ -68,14 +68,16 @@ pub enum FileType { Directory, Symlink, BlockDevice, - CharDevice + CharDevice, + NamedPipe } serde_impl!(FileType(u8) { File => 0, Directory => 1, Symlink => 2, BlockDevice => 3, - CharDevice => 4 + CharDevice => 4, + NamedPipe => 5 }); impl fmt::Display for FileType { fn fmt(&self, format: &mut fmt::Formatter) -> Result<(), fmt::Error> { @@ -84,7 +86,8 @@ impl fmt::Display for FileType { FileType::Directory => write!(format, "directory"), FileType::Symlink => write!(format, "symlink"), FileType::BlockDevice => write!(format, "block device"), - FileType::CharDevice => write!(format, "char device") + FileType::CharDevice => write!(format, "char device"), + FileType::NamedPipe => write!(format, "named pipe") } } } @@ -181,6 +184,8 @@ impl Inode { FileType::BlockDevice } else if meta.file_type().is_char_device() { FileType::CharDevice + } else if meta.file_type().is_fifo() { + FileType::NamedPipe } else { return Err(InodeError::UnsupportedFiletype(path.to_owned())); }; @@ -225,6 +230,13 @@ impl Inode { return Err(InodeError::Integrity("Symlink without target")) } }, + FileType::NamedPipe => { + let name = try!(ffi::CString::new(full_path.as_os_str().as_bytes()).map_err(|_| InodeError::Integrity("Name contains nulls"))); + let mode = self.mode | libc::S_IFIFO; + if unsafe { libc::mkfifo(name.as_ptr(), mode) } != 0 { + return Err(InodeError::Create(io::Error::last_os_error(), full_path.clone())); + } + }, FileType::BlockDevice | FileType::CharDevice => { let name = try!(ffi::CString::new(full_path.as_os_str().as_bytes()).map_err(|_| InodeError::Integrity("Name contains nulls"))); let mode = self.mode | match self.file_type { diff --git a/src/repository/tarfile.rs b/src/repository/tarfile.rs index 0ca8f56..7db832d 100644 --- a/src/repository/tarfile.rs +++ b/src/repository/tarfile.rs @@ -87,6 +87,7 @@ fn inode_from_entry(entry: &mut tar::Entry) -> Result FileType::Directory, tar::EntryType::Block => FileType::BlockDevice, tar::EntryType::Char => FileType::CharDevice, + tar::EntryType::Fifo => FileType::NamedPipe, _ => return Err(InodeError::UnsupportedFiletype(path.to_path_buf()).into()) }; Inode { @@ -330,7 +331,8 @@ impl Repository { FileType::Symlink => tar::EntryType::Symlink, FileType::Directory => tar::EntryType::Directory, FileType::BlockDevice => tar::EntryType::Block, - FileType::CharDevice => tar::EntryType::Char + FileType::CharDevice => tar::EntryType::Char, + FileType::NamedPipe => tar::EntryType::Fifo }); header.set_cksum(); match inode.data {