From e2a460aeb6bb32d1e7060350c265904dd5ac7140 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Thu, 21 Feb 2019 12:15:06 -0300 Subject: [PATCH] IO: remove `flush_on_newline` and only `sync` on TTY devices --- spec/std/io/buffered_spec.cr | 22 ---------------------- src/http/server/response.cr | 1 - src/io/buffered.cr | 26 -------------------------- src/io/file_descriptor.cr | 6 +++++- src/kernel.cr | 19 ++++++++----------- src/process.cr | 4 ++-- 6 files changed, 15 insertions(+), 63 deletions(-) diff --git a/spec/std/io/buffered_spec.cr b/spec/std/io/buffered_spec.cr index 068749d6875a..62637302c695 100644 --- a/spec/std/io/buffered_spec.cr +++ b/spec/std/io/buffered_spec.cr @@ -262,28 +262,6 @@ describe "IO::Buffered" do str.to_s.should eq("hello" * 10_000) end - it "flushes on \n" do - str = IO::Memory.new - io = BufferedWrapper.new(str) - io.flush_on_newline = true - - io << "hello\nworld" - str.to_s.should eq("hello\n") - io.flush - str.to_s.should eq("hello\nworld") - end - - it "doesn't write past count" do - str = IO::Memory.new - io = BufferedWrapper.new(str) - io.flush_on_newline = true - - slice = Slice.new(10) { |i| i == 9 ? '\n'.ord.to_u8 : ('a'.ord + i).to_u8 } - io.write slice[0, 4] - io.flush - str.to_s.should eq("abcd") - end - describe "sync" do it "syncs (write)" do str = IO::Memory.new diff --git a/src/http/server/response.cr b/src/http/server/response.cr index 615bec1dcaf5..8151aa142d1e 100644 --- a/src/http/server/response.cr +++ b/src/http/server/response.cr @@ -158,7 +158,6 @@ class HTTP::Server @in_buffer_rem = Bytes.empty @out_count = 0 @sync = false - @flush_on_newline = false @chunked = false @closed = false end diff --git a/src/io/buffered.cr b/src/io/buffered.cr index 3950c4b7a8db..006b90b0d76a 100644 --- a/src/io/buffered.cr +++ b/src/io/buffered.cr @@ -12,7 +12,6 @@ module IO::Buffered @out_count = 0 @sync = false @read_buffering = true - @flush_on_newline = false # Reads at most *slice.size* bytes from the wrapped `IO` into *slice*. # Returns the number of bytes read. @@ -123,17 +122,6 @@ module IO::Buffered return unbuffered_write(slice) end - if flush_on_newline? - index = slice[0, count.to_i32].rindex('\n'.ord.to_u8) - if index - flush - index += 1 - unbuffered_write slice[0, index] - slice += index - count -= index - end - end - if count >= BUFFER_SIZE flush return unbuffered_write slice[0, count] @@ -161,20 +149,6 @@ module IO::Buffered end out_buffer[@out_count] = byte @out_count += 1 - - if flush_on_newline? && byte === '\n' - flush - end - end - - # Turns on/off flushing the underlying `IO` when a newline is written. - def flush_on_newline=(flush_on_newline) - @flush_on_newline = !!flush_on_newline - end - - # Determines if this `IO` flushes automatically when a newline is written. - def flush_on_newline? - @flush_on_newline end # Turns on/off `IO` **write** buffering. When *sync* is set to `true`, no buffering diff --git a/src/io/file_descriptor.cr b/src/io/file_descriptor.cr index 04a4658686e6..c1a33fb0da1d 100644 --- a/src/io/file_descriptor.cr +++ b/src/io/file_descriptor.cr @@ -31,7 +31,11 @@ class IO::FileDescriptor < IO clone_fd = LibC.open(path, LibC::O_RDWR) return new(fd, blocking: true) if clone_fd == -1 - new(clone_fd).tap(&.close_on_exec = true) + # We don't buffer output for TTY devices to see their output right away + io = new(clone_fd) + io.close_on_exec = true + io.sync = true + io end def blocking diff --git a/src/kernel.cr b/src/kernel.cr index 173f368d6876..a9c1661fa975 100644 --- a/src/kernel.cr +++ b/src/kernel.cr @@ -5,16 +5,12 @@ # The standard output file descriptor. # # Typically used to output data and information. - # - # NOTE: Gets flushed when a newline is written. - STDOUT = IO::FileDescriptor.new(1).tap { |f| f.flush_on_newline = true } + STDOUT = IO::FileDescriptor.new(1) # The standard error file descriptor. # # Typically used to output error messages and diagnostics. - # - # NOTE: Gets flushed when a newline is written. - STDERR = IO::FileDescriptor.new(2).tap { |f| f.flush_on_newline = true } + STDERR = IO::FileDescriptor.new(2) {% else %} require "c/unistd" @@ -25,15 +21,17 @@ # # Typically used to output data and information. # - # NOTE: Gets flushed when a newline is written. - STDOUT = IO::FileDescriptor.from_stdio(1).tap { |f| f.flush_on_newline = true } + # When this is a TTY device, `sync` will be true for it + # at the start of the program. + STDOUT = IO::FileDescriptor.from_stdio(1) # The standard error file descriptor. # # Typically used to output error messages and diagnostics. # - # NOTE: Gets flushed when a newline is written. - STDERR = IO::FileDescriptor.from_stdio(2).tap { |f| f.flush_on_newline = true } + # When this is a TTY device, `sync` will be true for it + # at the start of the program. + STDERR = IO::FileDescriptor.from_stdio(2) {% end %} # The name, the program was called with. @@ -118,7 +116,6 @@ end # See also: `IO#print`. def print(*objects : _) : Nil STDOUT.print *objects - STDOUT.flush end # Prints a formatted string to `STDOUT`. diff --git a/src/process.cr b/src/process.cr index b537817752d3..40927859d61f 100644 --- a/src/process.cr +++ b/src/process.cr @@ -430,8 +430,8 @@ class Process end ORIGINAL_STDIN = IO::FileDescriptor.new(0, blocking: true) - ORIGINAL_STDOUT = IO::FileDescriptor.new(1, blocking: true).tap { |f| f.flush_on_newline = true } - ORIGINAL_STDERR = IO::FileDescriptor.new(2, blocking: true).tap { |f| f.flush_on_newline = true } + ORIGINAL_STDOUT = IO::FileDescriptor.new(1, blocking: true) + ORIGINAL_STDERR = IO::FileDescriptor.new(2, blocking: true) # :nodoc: protected def self.exec_internal(command, args, env, clear_env, input, output, error, chdir) : NoReturn