@@ -9,6 +9,7 @@ use rlimit::Resource;
99#[ cfg( unix) ]
1010use std:: fs:: File ;
1111use std:: fs:: OpenOptions ;
12+ use std:: fs:: read_to_string;
1213use std:: process:: Stdio ;
1314use uutests:: at_and_ucmd;
1415use uutests:: new_ucmd;
@@ -637,6 +638,57 @@ fn test_write_to_self() {
637638 ) ;
638639}
639640
641+ /// Test derived from the following GNU test in `tests/cat/cat-self.sh`:
642+ ///
643+ /// `cat fxy2 fy 1<>fxy2`
644+ // TODO: make this work on windows
645+ #[ test]
646+ #[ cfg( unix) ]
647+ fn test_successful_write_to_read_write_self ( ) {
648+ let ( at, mut ucmd) = at_and_ucmd ! ( ) ;
649+ at. write ( "fy" , "y" ) ;
650+ at. write ( "fxy2" , "x" ) ;
651+
652+ // Open `rw_file` as both stdin and stdout (read/write)
653+ let fxy2_file_path = at. plus ( "fxy2" ) ;
654+ let fxy2_file = OpenOptions :: new ( )
655+ . read ( true )
656+ . write ( true )
657+ . open ( & fxy2_file_path)
658+ . unwrap ( ) ;
659+ ucmd. args ( & [ "fxy2" , "fy" ] ) . set_stdout ( fxy2_file) . succeeds ( ) ;
660+
661+ // The contents of `fxy2` and `fy` files should be merged
662+ let fxy2_contents = read_to_string ( fxy2_file_path) . unwrap ( ) ;
663+ assert_eq ! ( fxy2_contents, "xy" ) ;
664+ }
665+
666+ /// Test derived from the following GNU test in `tests/cat/cat-self.sh`:
667+ ///
668+ /// `cat fx fx3 1<>fx3`
669+ #[ test]
670+ fn test_failed_write_to_read_write_self ( ) {
671+ let ( at, mut ucmd) = at_and_ucmd ! ( ) ;
672+ at. write ( "fx" , "g" ) ;
673+ at. write ( "fx3" , "bold" ) ;
674+
675+ // Open `rw_file` as both stdin and stdout (read/write)
676+ let fx3_file_path = at. plus ( "fx3" ) ;
677+ let fx3_file = OpenOptions :: new ( )
678+ . read ( true )
679+ . write ( true )
680+ . open ( & fx3_file_path)
681+ . unwrap ( ) ;
682+ ucmd. args ( & [ "fx" , "fx3" ] )
683+ . set_stdout ( fx3_file)
684+ . fails_with_code ( 1 )
685+ . stderr_only ( "cat: fx3: input file is output file\n " ) ;
686+
687+ // The contents of `fx` should have overwritten the beginning of `fx3`
688+ let fx3_contents = read_to_string ( fx3_file_path) . unwrap ( ) ;
689+ assert_eq ! ( fx3_contents, "gold" ) ;
690+ }
691+
640692#[ test]
641693#[ cfg( unix) ]
642694#[ cfg( not( target_os = "openbsd" ) ) ]
0 commit comments