diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 6c771d352..b1c6b5630 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -310,6 +310,15 @@ impl<'a> Input<'a> { }; #[cfg(unix)] let mut src = Source::stdin_as_file(); + #[cfg(unix)] + if let Source::StdinFile(f) = &src { + // GNU compatibility: + // this will check whether stdin points to a folder or not + if f.metadata()?.is_file() && settings.iflags.directory { + show_error!("standard input: not a directory"); + return Err(1.into()); + } + }; if settings.skip > 0 { src.skip(settings.skip)?; } diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index c909527c0..213ab5138 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -1715,6 +1715,20 @@ fn test_reading_partial_blocks_from_fifo_unbuffered() { assert!(output.stderr.starts_with(expected)); } +#[test] +#[cfg(any(target_os = "linux", target_os = "android"))] +fn test_iflag_directory_fails_when_file_is_passed_via_std_in() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + at.make_file("input"); + let filename = at.plus_as_string("input"); + new_ucmd!() + .args(&["iflag=directory", "count=0"]) + .set_stdin(std::process::Stdio::from(File::open(filename).unwrap())) + .fails() + .stderr_contains("standard input: not a directory"); +} + #[test] fn test_stdin_stdout_not_rewound_even_when_connected_to_seekable_file() { use std::process::Stdio;