[all (rust)] Fix errors in testing input option
- Fix file mode bits checking - Return error reason from stat
This commit is contained in:
parent
4ed2348b36
commit
2f22a8c55d
@ -4,9 +4,11 @@ extern crate thinp;
|
||||
use atty::Stream;
|
||||
use clap::{App, Arg};
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use std::sync::Arc;
|
||||
|
||||
use thinp::cache::check::{check, CacheCheckOptions};
|
||||
use thinp::file_utils;
|
||||
use thinp::report::*;
|
||||
|
||||
//------------------------------------------
|
||||
@ -68,6 +70,11 @@ fn main() {
|
||||
let matches = parser.get_matches();
|
||||
let input_file = Path::new(matches.value_of("INPUT").unwrap());
|
||||
|
||||
if let Err(e) = file_utils::is_file_or_blk(input_file) {
|
||||
eprintln!("Invalid input file '{}': {}.", input_file.display(), e);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let report;
|
||||
if matches.is_present("QUIET") {
|
||||
report = std::sync::Arc::new(mk_quiet_report());
|
||||
@ -91,7 +98,7 @@ fn main() {
|
||||
|
||||
if let Err(reason) = check(opts) {
|
||||
eprintln!("{}", reason);
|
||||
std::process::exit(1);
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,9 @@ extern crate thinp;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use thinp::cache::dump::{dump, CacheDumpOptions};
|
||||
use thinp::file_utils;
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
@ -48,6 +50,11 @@ fn main() {
|
||||
None
|
||||
};
|
||||
|
||||
if let Err(e) = file_utils::is_file_or_blk(input_file) {
|
||||
eprintln!("Invalid input file '{}': {}.", input_file.display(), e);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let opts = CacheDumpOptions {
|
||||
input: input_file,
|
||||
output: output_file,
|
||||
@ -57,7 +64,7 @@ fn main() {
|
||||
|
||||
if let Err(reason) = dump(opts) {
|
||||
eprintln!("{}", reason);
|
||||
std::process::exit(1);
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ use atty::Stream;
|
||||
use clap::{App, Arg};
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use thinp::cache::repair::{repair, CacheRepairOptions};
|
||||
use thinp::file_utils;
|
||||
@ -50,9 +49,9 @@ fn main() {
|
||||
let input_file = Path::new(matches.value_of("INPUT").unwrap());
|
||||
let output_file = Path::new(matches.value_of("OUTPUT").unwrap());
|
||||
|
||||
if !file_utils::file_exists(input_file) {
|
||||
eprintln!("Couldn't find input file '{:?}'.", &input_file);
|
||||
exit(1);
|
||||
if let Err(e) = file_utils::is_file_or_blk(input_file) {
|
||||
eprintln!("Invalid input file '{}': {}.", input_file.display(), e);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let report;
|
||||
|
@ -5,7 +5,6 @@ use atty::Stream;
|
||||
use clap::{App, Arg};
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use thinp::cache::restore::{restore, CacheRestoreOptions};
|
||||
use thinp::file_utils;
|
||||
@ -50,14 +49,14 @@ fn main() {
|
||||
let input_file = Path::new(matches.value_of("INPUT").unwrap());
|
||||
let output_file = Path::new(matches.value_of("OUTPUT").unwrap());
|
||||
|
||||
if !file_utils::file_exists(input_file) {
|
||||
eprintln!("Couldn't find input file '{:?}'.", &input_file);
|
||||
exit(1);
|
||||
if let Err(e) = file_utils::is_file(input_file) {
|
||||
eprintln!("Invalid input file '{}': {}.", input_file.display(), e);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
if let Err(e) = file_utils::check_output_file_requirements(output_file) {
|
||||
eprintln!("{}", e);
|
||||
exit(1);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let report;
|
||||
|
@ -5,7 +5,6 @@ use atty::Stream;
|
||||
use clap::{App, Arg};
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use thinp::file_utils;
|
||||
use thinp::io_engine::*;
|
||||
@ -80,9 +79,9 @@ fn main() {
|
||||
let matches = parser.get_matches();
|
||||
let input_file = Path::new(matches.value_of("INPUT").unwrap());
|
||||
|
||||
if !file_utils::file_exists(input_file) {
|
||||
eprintln!("Couldn't find input file '{:?}'.", &input_file);
|
||||
exit(1);
|
||||
if let Err(e) = file_utils::is_file_or_blk(input_file) {
|
||||
eprintln!("Invalid input file '{}': {}.", input_file.display(), e);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let report;
|
||||
|
@ -5,7 +5,6 @@ use atty::Stream;
|
||||
use clap::{App, Arg};
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use thinp::file_utils;
|
||||
use thinp::report::*;
|
||||
@ -89,29 +88,29 @@ fn main() {
|
||||
None
|
||||
};
|
||||
|
||||
if !file_utils::file_exists(input_file) {
|
||||
eprintln!("Couldn't find input file '{:?}'.", &input_file);
|
||||
exit(1);
|
||||
if let Err(e) = file_utils::is_file_or_blk(input_file) {
|
||||
eprintln!("Invalid input file '{}': {}.", input_file.display(), e);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let transaction_id = matches.value_of("TRANSACTION_ID").map(|s| {
|
||||
s.parse::<u64>().unwrap_or_else(|_| {
|
||||
eprintln!("Couldn't parse transaction_id");
|
||||
exit(1);
|
||||
process::exit(1);
|
||||
})
|
||||
});
|
||||
|
||||
let data_block_size = matches.value_of("DATA_BLOCK_SIZE").map(|s| {
|
||||
s.parse::<u32>().unwrap_or_else(|_| {
|
||||
eprintln!("Couldn't parse data_block_size");
|
||||
exit(1);
|
||||
process::exit(1);
|
||||
})
|
||||
});
|
||||
|
||||
let nr_data_blocks = matches.value_of("NR_DATA_BLOCKS").map(|s| {
|
||||
s.parse::<u64>().unwrap_or_else(|_| {
|
||||
eprintln!("Couldn't parse nr_data_blocks");
|
||||
exit(1);
|
||||
process::exit(1);
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -27,8 +27,8 @@ fn main() {
|
||||
let input_file = Path::new(matches.value_of("INPUT").unwrap());
|
||||
let output_file = Path::new(matches.value_of("OUTPUT").unwrap());
|
||||
|
||||
if !file_utils::file_exists(&input_file) {
|
||||
eprintln!("Couldn't find input file '{}'.", &input_file.display());
|
||||
if let Err(e) = file_utils::is_file_or_blk(input_file) {
|
||||
eprintln!("Invalid input file '{}': {}.", input_file.display(), e);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,8 @@ fn main() {
|
||||
let input_file = Path::new(matches.value_of("INPUT").unwrap());
|
||||
let output_file = Path::new(matches.value_of("OUTPUT").unwrap());
|
||||
|
||||
if !file_utils::file_exists(input_file) {
|
||||
eprintln!("Couldn't find input file '{}'.", &input_file.display());
|
||||
if let Err(e) = file_utils::is_file(input_file) {
|
||||
eprintln!("Invalid input file '{}': {}.", input_file.display(), e);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ use atty::Stream;
|
||||
use clap::{App, Arg};
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use thinp::file_utils;
|
||||
use thinp::report::*;
|
||||
@ -69,29 +68,29 @@ fn main() {
|
||||
let input_file = Path::new(matches.value_of("INPUT").unwrap());
|
||||
let output_file = Path::new(matches.value_of("OUTPUT").unwrap());
|
||||
|
||||
if !file_utils::file_exists(input_file) {
|
||||
eprintln!("Couldn't find input file '{:?}'.", &input_file);
|
||||
exit(1);
|
||||
if let Err(e) = file_utils::is_file_or_blk(input_file) {
|
||||
eprintln!("Invalid input file '{}': {}.", input_file.display(), e);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let transaction_id = matches.value_of("TRANSACTION_ID").map(|s| {
|
||||
s.parse::<u64>().unwrap_or_else(|_| {
|
||||
eprintln!("Couldn't parse transaction_id");
|
||||
exit(1);
|
||||
process::exit(1);
|
||||
})
|
||||
});
|
||||
|
||||
let data_block_size = matches.value_of("DATA_BLOCK_SIZE").map(|s| {
|
||||
s.parse::<u32>().unwrap_or_else(|_| {
|
||||
eprintln!("Couldn't parse data_block_size");
|
||||
exit(1);
|
||||
process::exit(1);
|
||||
})
|
||||
});
|
||||
|
||||
let nr_data_blocks = matches.value_of("NR_DATA_BLOCKS").map(|s| {
|
||||
s.parse::<u64>().unwrap_or_else(|_| {
|
||||
eprintln!("Couldn't parse nr_data_blocks");
|
||||
exit(1);
|
||||
process::exit(1);
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -5,7 +5,6 @@ use atty::Stream;
|
||||
use clap::{App, Arg};
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use thinp::file_utils;
|
||||
use thinp::report::*;
|
||||
@ -57,14 +56,14 @@ fn main() {
|
||||
let input_file = Path::new(matches.value_of("INPUT").unwrap());
|
||||
let output_file = Path::new(matches.value_of("OUTPUT").unwrap());
|
||||
|
||||
if !file_utils::file_exists(input_file) {
|
||||
eprintln!("Couldn't find input file '{:?}'.", &input_file);
|
||||
exit(1);
|
||||
if let Err(e) = file_utils::is_file(input_file) {
|
||||
eprintln!("Invalid input file '{}': {}.", input_file.display(), e);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
if let Err(e) = file_utils::check_output_file_requirements(output_file) {
|
||||
eprintln!("{}", e);
|
||||
exit(1);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let report;
|
||||
|
@ -66,8 +66,8 @@ fn main() {
|
||||
let data_file = Path::new(matches.value_of("DATA").unwrap());
|
||||
let do_copy = !matches.is_present("NOCOPY");
|
||||
|
||||
if !file_utils::file_exists(input_file) {
|
||||
eprintln!("Couldn't find input file '{}'.", input_file.display());
|
||||
if let Err(e) = file_utils::is_file_or_blk(input_file) {
|
||||
eprintln!("Invalid input file '{}': {}.", input_file.display(), e);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nix::sys::stat;
|
||||
use nix::sys::stat::{FileStat, SFlag};
|
||||
use nix::sys::stat::FileStat;
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::io;
|
||||
use std::io::{Seek, Write};
|
||||
@ -9,22 +9,46 @@ use tempfile::tempfile;
|
||||
|
||||
//---------------------------------------
|
||||
|
||||
fn check_bits(mode: u32, flag: &SFlag) -> bool {
|
||||
(mode & flag.bits()) != 0
|
||||
#[inline(always)]
|
||||
pub fn s_isreg(info: &FileStat) -> bool {
|
||||
(info.st_mode & stat::SFlag::S_IFMT.bits()) == stat::SFlag::S_IFREG.bits()
|
||||
}
|
||||
|
||||
pub fn is_file_or_blk(info: FileStat) -> bool {
|
||||
check_bits(info.st_mode, &stat::SFlag::S_IFBLK)
|
||||
|| check_bits(info.st_mode, &stat::SFlag::S_IFREG)
|
||||
#[inline(always)]
|
||||
pub fn s_isblk(info: &FileStat) -> bool {
|
||||
(info.st_mode & stat::SFlag::S_IFMT.bits()) == stat::SFlag::S_IFBLK.bits()
|
||||
}
|
||||
|
||||
pub fn file_exists(path: &Path) -> bool {
|
||||
pub fn is_file(path: &Path) -> io::Result<()> {
|
||||
match stat::stat(path) {
|
||||
Ok(info) => is_file_or_blk(info),
|
||||
Ok(info) => {
|
||||
if s_isreg(&info) {
|
||||
Ok(())
|
||||
} else {
|
||||
fail("Not a regular file")
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// FIXME: assuming all errors indicate the file doesn't
|
||||
// exist.
|
||||
false
|
||||
fail("No such file or directory")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_file_or_blk(path: &Path) -> io::Result<()> {
|
||||
match stat::stat(path) {
|
||||
Ok(info) => {
|
||||
if s_isreg(&info) || s_isblk(&info) {
|
||||
Ok(())
|
||||
} else {
|
||||
fail("Not a block device or regular file")
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// FIXME: assuming all errors indicate the file doesn't
|
||||
// exist.
|
||||
fail("No such file or directory")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -55,12 +79,12 @@ fn get_device_size(path: &Path) -> io::Result<u64> {
|
||||
pub fn file_size(path: &Path) -> io::Result<u64> {
|
||||
match stat::stat(path) {
|
||||
Ok(info) => {
|
||||
if check_bits(info.st_mode, &SFlag::S_IFREG) {
|
||||
if s_isreg(&info) {
|
||||
Ok(info.st_size as u64)
|
||||
} else if check_bits(info.st_mode, &SFlag::S_IFBLK) {
|
||||
} else if s_isblk(&info) {
|
||||
get_device_size(path)
|
||||
} else {
|
||||
fail("not a regular file or block device")
|
||||
fail("Not a block device or regular file")
|
||||
}
|
||||
}
|
||||
_ => fail("stat failed"),
|
||||
|
@ -62,7 +62,7 @@ pub mod cpp_msg {
|
||||
}
|
||||
|
||||
pub mod rust_msg {
|
||||
pub const FILE_NOT_FOUND: &str = "Couldn't find input file";
|
||||
pub const FILE_NOT_FOUND: &str = "No such file or directory";
|
||||
pub const MISSING_INPUT_ARG: &str = "The following required arguments were not provided"; // TODO: be specific
|
||||
pub const MISSING_OUTPUT_ARG: &str = "The following required arguments were not provided"; // TODO: be specific
|
||||
pub const BAD_SUPERBLOCK: &str = "bad checksum in superblock";
|
||||
|
Loading…
x
Reference in New Issue
Block a user