diff --git a/src/sed/fast_io.rs b/src/sed/fast_io.rs index 5ea8bf3d..838965e4 100644 --- a/src/sed/fast_io.rs +++ b/src/sed/fast_io.rs @@ -678,6 +678,15 @@ impl OutputBuffer { ))) } + /// Schedule the specified text for output unchanged, after any + /// deferred newline. + pub fn write_raw(&mut self, bytes: &[u8]) -> io::Result<()> { + self.flush_pending_newline()?; + #[cfg(unix)] + self.flush_mmap(WriteRange::Complete)?; + self.out.write_all(bytes) + } + /// Copy the specified file to the output. pub fn copy_file(&mut self, path: &PathBuf) -> io::Result<()> { // Flush mmap writes, if any. diff --git a/src/sed/processor.rs b/src/sed/processor.rs index 3f0ebb8b..948b3ed2 100644 --- a/src/sed/processor.rs +++ b/src/sed/processor.rs @@ -467,7 +467,7 @@ fn flush_appends(output: &mut OutputBuffer, context: &mut ProcessingContext) -> for elem in &context.append_elements { match elem { AppendElement::Text(text) => { - output.write_bytes(text.as_ref())?; + output.write_raw(text.as_ref())?; } AppendElement::Path(path) => { output.copy_file(path)?; @@ -567,9 +567,7 @@ fn list( ) -> UResult<()> { // Special case for an empty pattern space if line.is_empty() { - if line.is_newline_terminated() { - output.write_str("$\n")?; - } + output.write_str("$\n")?; return Ok(()); } @@ -737,7 +735,7 @@ fn process_file( } CommandData::Text(cmd_bytes) => { let shell_out = shell_stdout(cmd_bytes.to_vec(), &command, context)?; - output.write_bytes(&shell_out)?; + output.write_raw(&shell_out)?; } _ => panic!("invalid 'e' command data"), }, diff --git a/tests/by-util/test_sed.rs b/tests/by-util/test_sed.rs index add24b83..62a90f1c 100644 --- a/tests/by-util/test_sed.rs +++ b/tests/by-util/test_sed.rs @@ -3090,3 +3090,45 @@ fn test_posix_reject_flags() { .code_is(1) .stderr_is("sed: