1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

Addresses build errors

- Adds words to cspell exceptions
- Converts test macros to use Default trait.
- Converts parser to use Default trait.
- Adds Windows-friendly test files for block/unblock when nl is present
  in test/spec file.
This commit is contained in:
Tyler 2021-07-22 15:49:17 -07:00
parent 989849eca7
commit 885a875552
17 changed files with 272 additions and 257 deletions

7
Cargo.lock generated
View file

@ -543,12 +543,6 @@ version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" checksum = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97"
[[package]]
name = "debug_print"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f215f9b7224f49fb73256115331f677d868b34d18b65dbe4db392e6021eea90"
[[package]] [[package]]
name = "diff" name = "diff"
version = "0.1.12" version = "0.1.12"
@ -1917,7 +1911,6 @@ version = "0.0.7"
dependencies = [ dependencies = [
"byte-unit", "byte-unit",
"clap", "clap",
"debug_print",
"gcd", "gcd",
"libc", "libc",
"signal-hook", "signal-hook",

View file

@ -17,7 +17,6 @@ path = "src/dd.rs"
[dependencies] [dependencies]
byte-unit = "4.0" byte-unit = "4.0"
clap = { version = "2.33", features = [ "wrap_help" ] } clap = { version = "2.33", features = [ "wrap_help" ] }
debug_print = "1.0"
gcd = "2.0" gcd = "2.0"
libc = "0.2" libc = "0.2"
signal-hook = "0.3.9" signal-hook = "0.3.9"

View file

@ -17,7 +17,9 @@
"fullblock", "fullblock",
"noxfer", "noxfer",
"iflag", "iflag",
"iflags",
"oflag", "oflag",
"oflags",
"infile", "infile",
"outfile", "outfile",
"fileio", "fileio",
@ -33,9 +35,30 @@
"datastructures", "datastructures",
"creat", "creat",
"mult", "mult",
"unfailed",
"behaviour", "behaviour",
"ctty", "ctty",
"noatime",
"fname",
"fileout",
"ofile",
"doesnt",
"parseargs",
"rlen",
"wlen",
"rstat",
"wstat",
"rposition",
"btotal",
"sigval",
"sigusr",
"rmax",
"rsofar",
"rremain",
"bremain",
"oconvflags",
"fpath",
"testfile",
"specfile"
], ],
"ignorePaths": [ "ignorePaths": [
"**/test-resources/*.test", "**/test-resources/*.test",

View file

@ -24,6 +24,7 @@ use conversion_tables::*;
use byte_unit::Byte; use byte_unit::Byte;
use clap::{self, crate_version}; use clap::{self, crate_version};
use gcd::Gcd; use gcd::Gcd;
#[cfg(target_os = "linux")]
use signal_hook::consts::signal; use signal_hook::consts::signal;
use std::cmp; use std::cmp;
use std::convert::TryInto; use std::convert::TryInto;
@ -34,7 +35,9 @@ use std::io::{self, Read, Seek, Write};
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
use std::os::unix::fs::OpenOptionsExt; use std::os::unix::fs::OpenOptionsExt;
use std::path::Path; use std::path::Path;
use std::sync::{atomic::AtomicUsize, atomic::Ordering, mpsc, Arc}; #[cfg(target_os = "linux")]
use std::sync::atomic::Ordering;
use std::sync::{atomic::AtomicUsize, mpsc, Arc};
use std::thread; use std::thread;
use std::time; use std::time;
@ -168,15 +171,15 @@ impl Input<File> {
impl<R: Read> Read for Input<R> { impl<R: Read> Read for Input<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let mut base_idx = 0; let mut base_idx = 0;
let tlen = buf.len(); let target_len = buf.len();
loop { loop {
match self.src.read(&mut buf[base_idx..]) { match self.src.read(&mut buf[base_idx..]) {
Ok(0) => return Ok(base_idx), Ok(0) => return Ok(base_idx),
Ok(rlen) if self.iflags.fullblock => { Ok(rlen) if self.iflags.fullblock => {
base_idx += rlen; base_idx += rlen;
if base_idx >= tlen { if base_idx >= target_len {
return Ok(tlen); return Ok(target_len);
} }
} }
Ok(len) => return Ok(len), Ok(len) => return Ok(len),
@ -707,6 +710,7 @@ fn gen_prog_updater(rx: mpsc::Receiver<ProgUpdate>, print_level: Option<StatusLe
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
const SIGUSR1_USIZE: usize = signal::SIGUSR1 as usize; const SIGUSR1_USIZE: usize = signal::SIGUSR1 as usize;
// -------------------------------------------------------------- // --------------------------------------------------------------
#[cfg(target_os = "linux")]
fn posixly_correct() -> bool { fn posixly_correct() -> bool {
env::var("POSIXLY_CORRECT").is_ok() env::var("POSIXLY_CORRECT").is_ok()
} }
@ -731,21 +735,11 @@ fn gen_prog_updater(rx: mpsc::Receiver<ProgUpdate>, print_level: Option<StatusLe
} }
}); });
loop { while let Ok(update) = rx.recv() {
// Wait for update // (Re)print status line if progress is requested.
let update = match (rx.recv(), print_level) { if Some(StatusLevel::Progress) == print_level {
(Ok(update), Some(StatusLevel::Progress)) => {
reprint_prog_line(&update); reprint_prog_line(&update);
update
} }
(Ok(update), _) => update,
(Err(_), _) => {
// recv only fails permanently, so we break here to
// avoid recv'ing on a broken pipe
break;
}
};
// Handle signals // Handle signals
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
if let SIGUSR1_USIZE = sigval.load(Ordering::Relaxed) { if let SIGUSR1_USIZE = sigval.load(Ordering::Relaxed) {

View file

@ -15,19 +15,15 @@ macro_rules! make_block_test (
print_level: None, print_level: None,
count: None, count: None,
cflags: IConvFlags { cflags: IConvFlags {
ctable: None,
block: $block, block: $block,
unblock: None, ..IConvFlags::default()
swab: false,
sync: None,
noerror: false,
}, },
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(), dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: 512, obs: 512,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
$spec, $spec,
format!("./test-resources/FAILED-{}.test", $test_name) format!("./test-resources/FAILED-{}.test", $test_name)
@ -47,19 +43,15 @@ macro_rules! make_unblock_test (
print_level: None, print_level: None,
count: None, count: None,
cflags: IConvFlags { cflags: IConvFlags {
ctable: None,
block: None,
unblock: $unblock, unblock: $unblock,
swab: false, ..IConvFlags::default()
sync: None,
noerror: false,
}, },
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(), dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: 512, obs: 512,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
$spec, $spec,
format!("./test-resources/FAILED-{}.test", $test_name) format!("./test-resources/FAILED-{}.test", $test_name)
@ -247,7 +239,11 @@ fn block_test_double_surrounded_nl_double_trunc() {
make_block_test!( make_block_test!(
block_cbs16, block_cbs16,
"block-cbs-16", "block-cbs-16",
File::open("./test-resources/dd-block-cbs16.test").unwrap(), if cfg!(unix) {
File::open("./test-resources/dd-block-cbs16.test").unwrap()
} else {
File::open("./test-resources/dd-block-cbs16-win.test").unwrap()
},
Some(16), Some(16),
File::open("./test-resources/dd-block-cbs16.spec").unwrap() File::open("./test-resources/dd-block-cbs16.spec").unwrap()
); );
@ -255,7 +251,11 @@ make_block_test!(
make_block_test!( make_block_test!(
block_cbs16_as_cbs8, block_cbs16_as_cbs8,
"block-cbs-16-as-cbs8", "block-cbs-16-as-cbs8",
File::open("./test-resources/dd-block-cbs16.test").unwrap(), if cfg!(unix) {
File::open("./test-resources/dd-block-cbs16.test").unwrap()
} else {
File::open("./test-resources/dd-block-cbs16-win.test").unwrap()
},
Some(8), Some(8),
File::open("./test-resources/dd-block-cbs8.spec").unwrap() File::open("./test-resources/dd-block-cbs8.spec").unwrap()
); );
@ -263,7 +263,11 @@ make_block_test!(
make_block_test!( make_block_test!(
block_consecutive_nl, block_consecutive_nl,
"block-consecutive-nl", "block-consecutive-nl",
File::open("./test-resources/dd-block-consecutive-nl.test").unwrap(), if cfg!(unix) {
File::open("./test-resources/dd-block-consecutive-nl.test").unwrap()
} else {
File::open("./test-resources/dd-block-consecutive-nl-win.test").unwrap()
},
Some(16), Some(16),
File::open("./test-resources/dd-block-consecutive-nl-cbs16.spec").unwrap() File::open("./test-resources/dd-block-consecutive-nl-cbs16.spec").unwrap()
); );
@ -335,7 +339,11 @@ make_unblock_test!(
"unblock-multi-16", "unblock-multi-16",
File::open("./test-resources/dd-unblock-cbs16.test").unwrap(), File::open("./test-resources/dd-unblock-cbs16.test").unwrap(),
Some(16), Some(16),
if cfg!(unix) {
File::open("./test-resources/dd-unblock-cbs16.spec").unwrap() File::open("./test-resources/dd-unblock-cbs16.spec").unwrap()
} else {
File::open("./test-resources/dd-unblock-cbs16-win.spec").unwrap()
}
); );
make_unblock_test!( make_unblock_test!(
@ -343,5 +351,9 @@ make_unblock_test!(
"unblock-multi-16-as-8", "unblock-multi-16-as-8",
File::open("./test-resources/dd-unblock-cbs16.test").unwrap(), File::open("./test-resources/dd-unblock-cbs16.test").unwrap(),
Some(8), Some(8),
if cfg!(unix) {
File::open("./test-resources/dd-unblock-cbs8.spec").unwrap() File::open("./test-resources/dd-unblock-cbs8.spec").unwrap()
} else {
File::open("./test-resources/dd-unblock-cbs8-win.spec").unwrap()
}
); );

View file

@ -12,19 +12,15 @@ macro_rules! make_sync_test (
print_level: None, print_level: None,
count: None, count: None,
cflags: IConvFlags { cflags: IConvFlags {
ctable: None,
block: None,
unblock: None,
swab: false,
sync: $sync, sync: $sync,
noerror: false, ..IConvFlags::default()
}, },
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(), dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: $obs, obs: $obs,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
$spec, $spec,
format!("./test-resources/FAILED-{}.test", $test_name) format!("./test-resources/FAILED-{}.test", $test_name)

View file

@ -12,12 +12,12 @@ macro_rules! make_conv_test (
print_level: None, print_level: None,
count: None, count: None,
cflags: icf!($ctable), cflags: icf!($ctable),
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(), dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: 512, obs: 512,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
$spec, $spec,
format!("./test-resources/FAILED-{}.test", $test_name) format!("./test-resources/FAILED-{}.test", $test_name)
@ -37,12 +37,12 @@ macro_rules! make_icf_test (
print_level: None, print_level: None,
count: None, count: None,
cflags: $icf, cflags: $icf,
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(), dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: 512, obs: 512,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
$spec, $spec,
format!("./test-resources/FAILED-{}.test", $test_name) format!("./test-resources/FAILED-{}.test", $test_name)
@ -142,13 +142,13 @@ fn all_valid_ascii_ebcdic_ascii_roundtrip_conv_test() {
print_level: None, print_level: None,
count: None, count: None,
cflags: icf!(Some(&ASCII_TO_EBCDIC)), cflags: icf!(Some(&ASCII_TO_EBCDIC)),
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}; };
let o = Output { let o = Output {
dst: File::create(&tmp_fname_ae).unwrap(), dst: File::create(&tmp_fname_ae).unwrap(),
obs: 1024, obs: 1024,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}; };
dd_fileout(i, o).unwrap(); dd_fileout(i, o).unwrap();
@ -164,13 +164,13 @@ fn all_valid_ascii_ebcdic_ascii_roundtrip_conv_test() {
print_level: None, print_level: None,
count: None, count: None,
cflags: icf!(Some(&EBCDIC_TO_ASCII)), cflags: icf!(Some(&EBCDIC_TO_ASCII)),
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}; };
let o = Output { let o = Output {
dst: File::create(&tmp_fname_ea).unwrap(), dst: File::create(&tmp_fname_ea).unwrap(),
obs: 1024, obs: 1024,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}; };
dd_fileout(i, o).unwrap(); dd_fileout(i, o).unwrap();

View file

@ -9,34 +9,6 @@ use std::fs;
use std::io::prelude::*; use std::io::prelude::*;
use std::io::BufReader; use std::io::BufReader;
const DEFAULT_CFO: OConvFlags = OConvFlags {
sparse: false,
excl: false,
nocreat: false,
notrunc: false,
fdatasync: false,
fsync: false,
};
const DEFAULT_IFLAGS: IFlags = IFlags {
cio: false,
direct: false,
directory: false,
dsync: false,
sync: false,
nocache: false,
nonblock: false,
noatime: false,
noctty: false,
nofollow: false,
nolinks: false,
binary: false,
text: false,
fullblock: false,
count_bytes: false,
skip_bytes: false,
};
struct LazyReader<R: Read> { struct LazyReader<R: Read> {
src: R, src: R,
} }
@ -50,19 +22,11 @@ impl<R: Read> Read for LazyReader<R> {
#[macro_export] #[macro_export]
macro_rules! icf ( macro_rules! icf (
() =>
{
icf!(None)
};
( $ctable:expr ) => ( $ctable:expr ) =>
{ {
IConvFlags { IConvFlags {
ctable: $ctable, ctable: $ctable,
block: None, ..IConvFlags::default()
unblock: None,
swab: false,
sync: None,
noerror: false,
} }
}; };
); );
@ -84,13 +48,13 @@ macro_rules! make_spec_test (
ibs: 512, ibs: 512,
print_level: None, print_level: None,
count: None, count: None,
cflags: icf!(), cflags: IConvFlags::default(),
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(), dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: 512, obs: 512,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
$spec, $spec,
format!("./test-resources/FAILED-{}.test", $test_name) format!("./test-resources/FAILED-{}.test", $test_name)

View file

@ -52,13 +52,13 @@ make_io_test!(
ibs: 521, ibs: 521,
print_level: None, print_level: None,
count: None, count: None,
cflags: icf!(), cflags: IConvFlags::default(),
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: DST_PLACEHOLDER, dst: DST_PLACEHOLDER,
obs: 1031, obs: 1031,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap() File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap()
); );
@ -72,13 +72,13 @@ make_io_test!(
ibs: 1031, ibs: 1031,
print_level: None, print_level: None,
count: None, count: None,
cflags: icf!(), cflags: IConvFlags::default(),
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: DST_PLACEHOLDER, dst: DST_PLACEHOLDER,
obs: 521, obs: 521,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap() File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap()
); );
@ -92,13 +92,13 @@ make_io_test!(
ibs: 1024, ibs: 1024,
print_level: None, print_level: None,
count: Some(CountType::Reads(32)), count: Some(CountType::Reads(32)),
cflags: icf!(), cflags: IConvFlags::default(),
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: DST_PLACEHOLDER, dst: DST_PLACEHOLDER,
obs: 1024, obs: 1024,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap() File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap()
); );
@ -112,13 +112,13 @@ make_io_test!(
ibs: 531, ibs: 531,
print_level: None, print_level: None,
count: Some(CountType::Bytes(32 * 1024)), count: Some(CountType::Bytes(32 * 1024)),
cflags: icf!(), cflags: IConvFlags::default(),
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: DST_PLACEHOLDER, dst: DST_PLACEHOLDER,
obs: 1031, obs: 1031,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap() File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap()
); );
@ -132,13 +132,13 @@ make_io_test!(
ibs: 1024, ibs: 1024,
print_level: None, print_level: None,
count: Some(CountType::Reads(16)), count: Some(CountType::Reads(16)),
cflags: icf!(), cflags: IConvFlags::default(),
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: DST_PLACEHOLDER, dst: DST_PLACEHOLDER,
obs: 1031, obs: 1031,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
File::open("./test-resources/gnudd-deadbeef-first-16k.spec").unwrap() File::open("./test-resources/gnudd-deadbeef-first-16k.spec").unwrap()
); );
@ -152,13 +152,13 @@ make_io_test!(
ibs: 531, ibs: 531,
print_level: None, print_level: None,
count: Some(CountType::Bytes(12345)), count: Some(CountType::Bytes(12345)),
cflags: icf!(), cflags: IConvFlags::default(),
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: DST_PLACEHOLDER, dst: DST_PLACEHOLDER,
obs: 1031, obs: 1031,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
File::open("./test-resources/gnudd-deadbeef-first-12345.spec").unwrap() File::open("./test-resources/gnudd-deadbeef-first-12345.spec").unwrap()
); );
@ -172,13 +172,13 @@ make_io_test!(
ibs: 1024, ibs: 1024,
print_level: None, print_level: None,
count: Some(CountType::Reads(32)), count: Some(CountType::Reads(32)),
cflags: icf!(), cflags: IConvFlags::default(),
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: DST_PLACEHOLDER, dst: DST_PLACEHOLDER,
obs: 1024, obs: 1024,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
File::open("./test-resources/gnudd-random-first-32k.spec").unwrap() File::open("./test-resources/gnudd-random-first-32k.spec").unwrap()
); );
@ -192,13 +192,13 @@ make_io_test!(
ibs: 521, ibs: 521,
print_level: None, print_level: None,
count: Some(CountType::Bytes(32 * 1024)), count: Some(CountType::Bytes(32 * 1024)),
cflags: icf!(), cflags: IConvFlags::default(),
iflags: DEFAULT_IFLAGS, iflags: IFlags::default(),
}, },
Output { Output {
dst: DST_PLACEHOLDER, dst: DST_PLACEHOLDER,
obs: 1031, obs: 1031,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
File::open("./test-resources/gnudd-random-first-32k.spec").unwrap() File::open("./test-resources/gnudd-random-first-32k.spec").unwrap()
); );
@ -215,30 +215,16 @@ make_io_test!(
ibs: 521, ibs: 521,
print_level: None, print_level: None,
count: None, count: None,
cflags: icf!(), cflags: IConvFlags::default(),
iflags: IFlags { iflags: IFlags {
fullblock: true, fullblock: true,
cio: false, ..IFlags::default()
direct: false,
directory: false,
dsync: false,
sync: false,
nocache: false,
nonblock: false,
noatime: false,
noctty: false,
nofollow: false,
nolinks: false,
binary: false,
text: false,
count_bytes: false,
skip_bytes: false,
}, },
}, },
Output { Output {
dst: DST_PLACEHOLDER, dst: DST_PLACEHOLDER,
obs: 1031, obs: 1031,
cflags: DEFAULT_CFO, cflags: OConvFlags::default(),
}, },
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap() File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap()
); );
@ -316,7 +302,7 @@ fn bsize_test_bs_eq() {
#[test] #[test]
#[should_panic] #[should_panic]
fn test_nocreate_causes_failure_when_ofile_doesnt_exist() { fn test_nocreat_causes_failure_when_ofile_doesnt_exist() {
let args = vec![ let args = vec![
String::from("dd"), String::from("dd"),
String::from("--conv=nocreat"), String::from("--conv=nocreat"),

View file

@ -186,7 +186,7 @@ impl std::str::FromStr for Flag {
"direct" => "direct" =>
// Ok(Self::Direct), // Ok(Self::Direct),
{ {
if cfg!(unix) { if cfg!(target_os = "linux") {
Ok(Self::Direct) Ok(Self::Direct)
} else { } else {
Err(ParseError::Unimplemented(s.to_string())) Err(ParseError::Unimplemented(s.to_string()))
@ -195,7 +195,7 @@ impl std::str::FromStr for Flag {
"directory" => "directory" =>
// Ok(Self::Directory), // Ok(Self::Directory),
{ {
if cfg!(unix) { if cfg!(target_os = "linux") {
Ok(Self::Directory) Ok(Self::Directory)
} else { } else {
Err(ParseError::Unimplemented(s.to_string())) Err(ParseError::Unimplemented(s.to_string()))
@ -204,7 +204,7 @@ impl std::str::FromStr for Flag {
"dsync" => "dsync" =>
// Ok(Self::Dsync), // Ok(Self::Dsync),
{ {
if cfg!(unix) { if cfg!(target_os = "linux") {
Ok(Self::Dsync) Ok(Self::Dsync)
} else { } else {
Err(ParseError::Unimplemented(s.to_string())) Err(ParseError::Unimplemented(s.to_string()))
@ -213,7 +213,7 @@ impl std::str::FromStr for Flag {
"sync" => "sync" =>
// Ok(Self::Sync), // Ok(Self::Sync),
{ {
if cfg!(unix) { if cfg!(target_os = "linux") {
Ok(Self::Sync) Ok(Self::Sync)
} else { } else {
Err(ParseError::Unimplemented(s.to_string())) Err(ParseError::Unimplemented(s.to_string()))
@ -227,7 +227,7 @@ impl std::str::FromStr for Flag {
"nonblock" => "nonblock" =>
// Ok(Self::NonBlock), // Ok(Self::NonBlock),
{ {
if cfg!(unix) { if cfg!(target_os = "linux") {
Ok(Self::NonBlock) Ok(Self::NonBlock)
} else { } else {
Err(ParseError::Unimplemented(s.to_string())) Err(ParseError::Unimplemented(s.to_string()))
@ -236,7 +236,7 @@ impl std::str::FromStr for Flag {
"noatime" => "noatime" =>
// Ok(Self::NoATime), // Ok(Self::NoATime),
{ {
if cfg!(unix) { if cfg!(target_os = "linux") {
Ok(Self::NoATime) Ok(Self::NoATime)
} else { } else {
Err(ParseError::Unimplemented(s.to_string())) Err(ParseError::Unimplemented(s.to_string()))
@ -245,7 +245,7 @@ impl std::str::FromStr for Flag {
"noctty" => "noctty" =>
// Ok(Self::NoCtty), // Ok(Self::NoCtty),
{ {
if cfg!(unix) { if cfg!(target_os = "linux") {
Ok(Self::NoCtty) Ok(Self::NoCtty)
} else { } else {
Err(ParseError::Unimplemented(s.to_string())) Err(ParseError::Unimplemented(s.to_string()))
@ -254,7 +254,7 @@ impl std::str::FromStr for Flag {
"nofollow" => "nofollow" =>
// Ok(Self::NoFollow), // Ok(Self::NoFollow),
{ {
if cfg!(unix) { if cfg!(target_os = "linux") {
Ok(Self::NoFollow) Ok(Self::NoFollow)
} else { } else {
Err(ParseError::Unimplemented(s.to_string())) Err(ParseError::Unimplemented(s.to_string()))
@ -421,16 +421,13 @@ fn parse_flag_list<T: std::str::FromStr<Err = ParseError>>(
/// Parse Conversion Options (Input Variety) /// Parse Conversion Options (Input Variety)
/// Construct and validate a IConvFlags /// Construct and validate a IConvFlags
pub fn parse_conv_flag_input(matches: &Matches) -> Result<IConvFlags, ParseError> { pub fn parse_conv_flag_input(matches: &Matches) -> Result<IConvFlags, ParseError> {
let flags = parse_flag_list("conv", matches)?; let mut iconvflags = IConvFlags::default();
let cbs = parse_cbs(matches)?;
let mut fmt = None; let mut fmt = None;
let mut case = None; let mut case = None;
let mut block = None; let mut is_sync = false;
let mut unblock = None;
let mut swab = false; let flags = parse_flag_list(options::CONV, matches)?;
let mut sync = false; let cbs = parse_cbs(matches)?;
let mut noerror = false;
for flag in flags { for flag in flags {
match flag { match flag {
@ -469,27 +466,36 @@ pub fn parse_conv_flag_input(matches: &Matches) -> Result<IConvFlags, ParseError
case = Some(flag) case = Some(flag)
} }
} }
ConvFlag::Block => match (cbs, unblock) { ConvFlag::Block => match (cbs, iconvflags.unblock) {
(Some(cbs), None) => block = Some(cbs), (Some(cbs), None) => iconvflags.block = Some(cbs),
(None, _) => return Err(ParseError::BlockUnblockWithoutCBS), (None, _) => return Err(ParseError::BlockUnblockWithoutCBS),
(_, Some(_)) => return Err(ParseError::MultipleBlockUnblock), (_, Some(_)) => return Err(ParseError::MultipleBlockUnblock),
}, },
ConvFlag::Unblock => match (cbs, block) { ConvFlag::Unblock => match (cbs, iconvflags.block) {
(Some(cbs), None) => unblock = Some(cbs), (Some(cbs), None) => iconvflags.unblock = Some(cbs),
(None, _) => return Err(ParseError::BlockUnblockWithoutCBS), (None, _) => return Err(ParseError::BlockUnblockWithoutCBS),
(_, Some(_)) => return Err(ParseError::MultipleBlockUnblock), (_, Some(_)) => return Err(ParseError::MultipleBlockUnblock),
}, },
ConvFlag::Swab => swab = true, ConvFlag::Swab => iconvflags.swab = true,
ConvFlag::Sync => sync = true, ConvFlag::Sync => is_sync = true,
ConvFlag::NoError => noerror = true, ConvFlag::NoError => iconvflags.noerror = true,
_ => {} _ => {}
} }
} }
// The final conversion table depends on both
// fmt (eg. ASCII -> EBCDIC)
// case (eg. UCASE -> LCASE)
// So the final value can't be set until all flags are parsed.
let ctable = parse_ctable(fmt, case); let ctable = parse_ctable(fmt, case);
let sync = if sync && (block.is_some() || unblock.is_some()) {
// The final value of sync depends on block/unblock
// block implies sync with ' '
// unblock implies sync with 0
// So the final value can't be set until all flags are parsed.
let sync = if is_sync && (iconvflags.block.is_some() || iconvflags.unblock.is_some()) {
Some(b' ') Some(b' ')
} else if sync { } else if is_sync {
Some(0u8) Some(0u8)
} else { } else {
None None
@ -497,27 +503,17 @@ pub fn parse_conv_flag_input(matches: &Matches) -> Result<IConvFlags, ParseError
Ok(IConvFlags { Ok(IConvFlags {
ctable, ctable,
block,
unblock,
swab,
sync, sync,
noerror, ..iconvflags
}) })
} }
/// Parse Conversion Options (Output Variety) /// Parse Conversion Options (Output Variety)
/// Construct and validate a OConvFlags /// Construct and validate a OConvFlags
pub fn parse_conv_flag_output(matches: &Matches) -> Result<OConvFlags, ParseError> { pub fn parse_conv_flag_output(matches: &Matches) -> Result<OConvFlags, ParseError> {
let flags = parse_flag_list(options::CONV, matches)?; let mut oconvflags = OConvFlags::default();
let mut oconvflags = OConvFlags { let flags = parse_flag_list(options::CONV, matches)?;
sparse: false,
excl: false,
nocreat: false,
notrunc: false,
fdatasync: false,
fsync: false,
};
for flag in flags { for flag in flags {
match flag { match flag {
@ -548,24 +544,7 @@ pub fn parse_conv_flag_output(matches: &Matches) -> Result<OConvFlags, ParseErro
/// Parse IFlags struct from CL-input /// Parse IFlags struct from CL-input
pub fn parse_iflags(matches: &Matches) -> Result<IFlags, ParseError> { pub fn parse_iflags(matches: &Matches) -> Result<IFlags, ParseError> {
let mut iflags = IFlags { let mut iflags = IFlags::default();
cio: false,
direct: false,
directory: false,
dsync: false,
sync: false,
nocache: false,
nonblock: false,
noatime: false,
noctty: false,
nofollow: false,
nolinks: false,
binary: false,
text: false,
fullblock: false,
count_bytes: false,
skip_bytes: false,
};
let flags = parse_flag_list(options::IFLAG, matches)?; let flags = parse_flag_list(options::IFLAG, matches)?;
@ -596,23 +575,7 @@ pub fn parse_iflags(matches: &Matches) -> Result<IFlags, ParseError> {
/// Parse OFlags struct from CL-input /// Parse OFlags struct from CL-input
pub fn parse_oflags(matches: &Matches) -> Result<OFlags, ParseError> { pub fn parse_oflags(matches: &Matches) -> Result<OFlags, ParseError> {
let mut oflags = OFlags { let mut oflags = OFlags::default();
append: false,
cio: false,
direct: false,
directory: false,
dsync: false,
sync: false,
nocache: false,
nonblock: false,
noatime: false,
noctty: false,
nofollow: false,
nolinks: false,
binary: false,
text: false,
seek_bytes: false,
};
let flags = parse_flag_list(options::OFLAG, matches)?; let flags = parse_flag_list(options::OFLAG, matches)?;

View file

@ -4,7 +4,7 @@ use crate::StatusLevel;
#[cfg(not(target_os = "linux"))] #[cfg(not(target_os = "linux"))]
#[test] #[test]
fn unimplemented_flags_should_error_non_unix() { fn unimplemented_flags_should_error_non_linux() {
let mut succeeded = Vec::new(); let mut succeeded = Vec::new();
// The following flags are only implemented in linux // The following flags are only implemented in linux
@ -518,29 +518,35 @@ test_byte_parser!(test_bytes_GB, "3GB", 3 * 1000 * 1000 * 1000);
test_byte_parser!(test_bytes_G, "3G", 3 * 1024 * 1024 * 1024); test_byte_parser!(test_bytes_G, "3G", 3 * 1024 * 1024 * 1024);
test_byte_parser!(test_bytes_Gi, "3GiB", 3 * 1024 * 1024 * 1024); test_byte_parser!(test_bytes_Gi, "3GiB", 3 * 1024 * 1024 * 1024);
test_byte_parser!(test_bytes_TB, "4TB", 4 * 1000 * 1000 * 1000 * 1000); #[cfg(target_pointer_width = "64")]
test_byte_parser!(test_bytes_T, "4T", 4 * 1024 * 1024 * 1024 * 1024); #[cfg(test)]
test_byte_parser!(test_bytes_Ti, "4TiB", 4 * 1024 * 1024 * 1024 * 1024); mod test_64bit_arch {
use super::*;
test_byte_parser!(test_bytes_PB, "5PB", 5 * 1000 * 1000 * 1000 * 1000 * 1000); test_byte_parser!(test_bytes_TB, "4TB", 4 * 1000 * 1000 * 1000 * 1000);
test_byte_parser!(test_bytes_P, "5P", 5 * 1024 * 1024 * 1024 * 1024 * 1024); test_byte_parser!(test_bytes_T, "4T", 4 * 1024 * 1024 * 1024 * 1024);
test_byte_parser!(test_bytes_Pi, "5PiB", 5 * 1024 * 1024 * 1024 * 1024 * 1024); test_byte_parser!(test_bytes_Ti, "4TiB", 4 * 1024 * 1024 * 1024 * 1024);
test_byte_parser!( test_byte_parser!(test_bytes_PB, "5PB", 5 * 1000 * 1000 * 1000 * 1000 * 1000);
test_byte_parser!(test_bytes_P, "5P", 5 * 1024 * 1024 * 1024 * 1024 * 1024);
test_byte_parser!(test_bytes_Pi, "5PiB", 5 * 1024 * 1024 * 1024 * 1024 * 1024);
test_byte_parser!(
test_bytes_EB, test_bytes_EB,
"6EB", "6EB",
6 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 6 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000
); );
test_byte_parser!( test_byte_parser!(
test_bytes_E, test_bytes_E,
"6E", "6E",
6 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 6 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024
); );
test_byte_parser!( test_byte_parser!(
test_bytes_Ei, test_bytes_Ei,
"6EiB", "6EiB",
6 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 6 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024
); );
}
#[test] #[test]
#[should_panic] #[should_panic]

View file

@ -0,0 +1,16 @@
0
01
012
0123
01234
012345
0123456
01234567
012345678
0123456789
0123456789a
0123456789ab
0123456789abc
0123456789abcd
0123456789abcde
0123456789abcdef

View file

@ -0,0 +1,4 @@
pre
post

View file

@ -0,0 +1,16 @@
0
01
012
0123
01234
012345
0123456
01234567
012345678
0123456789
0123456789a
0123456789ab
0123456789abc
0123456789abcd
0123456789abcde
0123456789abcdef

View file

@ -0,0 +1,32 @@
0
01
012
0123
01234
012345
0123456
01234567
01234567
8
01234567
89
01234567
89a
01234567
89ab
01234567
89abc
01234567
89abcd
01234567
89abcde
01234567
89abcdef

View file

@ -213,27 +213,12 @@ fn test_excl_causes_failure_when_present() {
.fails(); .fails();
} }
#[cfg(target_os = "linux")]
#[test]
fn test_atime_updated() {
let fname = "this-file-exists-no-noatime.txt";
assert_fixture_exists!(&fname);
let (fix, mut ucmd) = at_and_ucmd!();
ucmd.args(&["status=none", inf!(fname)]);
let pre_atime = fix.metadata(fname).accessed().unwrap();
ucmd.pipe_in("").run().no_stderr().success();
std::thread::sleep(std::time::Duration::from_millis(10));
let post_atime = fix.metadata(fname).accessed().unwrap();
assert!(pre_atime != post_atime);
}
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[test] #[test]
fn test_noatime_does_not_update_infile_atime() { fn test_noatime_does_not_update_infile_atime() {
// NOTE: Not all environments support tracking access time. If this
// test fails on some systems and passes on others, assume the functionality
// is not working and the systems that pass it simply don't update file access time.
let fname = "this-ifile-exists-noatime.txt"; let fname = "this-ifile-exists-noatime.txt";
assert_fixture_exists!(&fname); assert_fixture_exists!(&fname);
@ -251,6 +236,9 @@ fn test_noatime_does_not_update_infile_atime() {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[test] #[test]
fn test_noatime_does_not_update_ofile_atime() { fn test_noatime_does_not_update_ofile_atime() {
// NOTE: Not all environments support tracking access time. If this
// test fails on some systems and passes on others, assume the functionality
// is not working and the systems that pass it simply don't update file access time.
let fname = "this-ofile-exists-noatime.txt"; let fname = "this-ofile-exists-noatime.txt";
assert_fixture_exists!(&fname); assert_fixture_exists!(&fname);

View file

@ -1,6 +1,29 @@
{ {
"version": "0.1", "version": "0.1",
"language": "en", "language": "en",
"words": [
"fname",
"fpath",
"specfile",
"testfile",
"iflag",
"iflags",
"oflag",
"oflags",
"noxfer",
"nocreat",
"noatime",
"infile",
"outfile",
"unspec",
"fullblock",
"urand",
"tname",
"fileio",
"gibi",
"ucase",
"lcase"
],
"ignorePaths": [ "ignorePaths": [
"*.txt", "*.txt",
"*.spec" "*.spec"