[all (rust)] Fix errors in testing input option

- Fix file mode bits checking
- Return error reason from stat
This commit is contained in:
Ming-Hung Tsai 2021-09-07 00:01:37 +08:00
parent 4ed2348b36
commit 2f22a8c55d
13 changed files with 85 additions and 53 deletions

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);
})
});

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
})
});

View File

@ -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;

View File

@ -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);
}

View File

@ -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"),

View File

@ -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";