mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
cat: Fix reporting "input file is output file" error when outputting to an input file (#8025)
* cat: Check if a file can be overwritten safely in Unix * cat: Check if a file can be overwritten safely in Windows * cat: Test writing read-write file that is input and output * cat: Unit test `is_appending` function * cat: Unit test `is_unsafe_overwrite` function * cat: Comment why a few function calls could return Err * cat: Remove obvious comments from test
This commit is contained in:
parent
9e21259e2d
commit
4d40671d79
7 changed files with 253 additions and 43 deletions
|
@ -9,6 +9,7 @@ use rlimit::Resource;
|
|||
#[cfg(unix)]
|
||||
use std::fs::File;
|
||||
use std::fs::OpenOptions;
|
||||
use std::fs::read_to_string;
|
||||
use std::process::Stdio;
|
||||
use uutests::at_and_ucmd;
|
||||
use uutests::new_ucmd;
|
||||
|
@ -637,6 +638,57 @@ fn test_write_to_self() {
|
|||
);
|
||||
}
|
||||
|
||||
/// Test derived from the following GNU test in `tests/cat/cat-self.sh`:
|
||||
///
|
||||
/// `cat fxy2 fy 1<>fxy2`
|
||||
// TODO: make this work on windows
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_successful_write_to_read_write_self() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.write("fy", "y");
|
||||
at.write("fxy2", "x");
|
||||
|
||||
// Open `rw_file` as both stdin and stdout (read/write)
|
||||
let fxy2_file_path = at.plus("fxy2");
|
||||
let fxy2_file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open(&fxy2_file_path)
|
||||
.unwrap();
|
||||
ucmd.args(&["fxy2", "fy"]).set_stdout(fxy2_file).succeeds();
|
||||
|
||||
// The contents of `fxy2` and `fy` files should be merged
|
||||
let fxy2_contents = read_to_string(fxy2_file_path).unwrap();
|
||||
assert_eq!(fxy2_contents, "xy");
|
||||
}
|
||||
|
||||
/// Test derived from the following GNU test in `tests/cat/cat-self.sh`:
|
||||
///
|
||||
/// `cat fx fx3 1<>fx3`
|
||||
#[test]
|
||||
fn test_failed_write_to_read_write_self() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.write("fx", "g");
|
||||
at.write("fx3", "bold");
|
||||
|
||||
// Open `rw_file` as both stdin and stdout (read/write)
|
||||
let fx3_file_path = at.plus("fx3");
|
||||
let fx3_file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open(&fx3_file_path)
|
||||
.unwrap();
|
||||
ucmd.args(&["fx", "fx3"])
|
||||
.set_stdout(fx3_file)
|
||||
.fails_with_code(1)
|
||||
.stderr_only("cat: fx3: input file is output file\n");
|
||||
|
||||
// The contents of `fx` should have overwritten the beginning of `fx3`
|
||||
let fx3_contents = read_to_string(fx3_file_path).unwrap();
|
||||
assert_eq!(fx3_contents, "gold");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
#[cfg(not(target_os = "openbsd"))]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue