Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rubinius/rubinius
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2a0371346d5f
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: eb30604a10d1
Choose a head ref
  • 6 commits
  • 7 files changed
  • 1 contributor

Commits on Jan 21, 2016

  1. Copy the full SHA
    28c05a0 View commit details
  2. Copy the full SHA
    b027c31 View commit details
  3. Copy the full SHA
    dc92d38 View commit details

Commits on Jan 22, 2016

  1. Copy the full SHA
    573adbb View commit details
  2. Copy the full SHA
    b8f3c88 View commit details
  3. Copy the full SHA
    eb30604 View commit details
22 changes: 22 additions & 0 deletions kernel/common/argf.rb
Original file line number Diff line number Diff line change
@@ -330,6 +330,7 @@ def readbyte
def read(bytes=nil, output=nil)
# The user might try to pass in nil, so we have to check here
output ||= default_value
output.clear

if bytes
bytes_left = bytes
@@ -401,6 +402,27 @@ def readlines(sep=$/)

alias_method :to_a, :readlines

def readpartial(maxlen, output=nil)
output ||= default_value

unless advance!
output.clear
raise EOFError, "ARGF at end"
end

begin
@stream.readpartial(maxlen, output)
rescue EOFError => e
raise e if @use_stdin_only

@stream.close
@advance = true
advance! or raise e
end

return output
end

#
# Rewind the stream to its beginning.
#
25 changes: 21 additions & 4 deletions kernel/common/io.rb
Original file line number Diff line number Diff line change
@@ -1895,21 +1895,34 @@ def read_all
#
# If the read buffer is not empty, read_nonblock reads from the
# buffer like readpartial. In this case, read(2) is not called.
def read_nonblock(size, buffer=nil)
def read_nonblock(size, buffer=nil, opts={})
raise ArgumentError, "illegal read size" if size < 0
ensure_open

if buffer.is_a?(Hash)
opts = buffer
buffer = nil
end

buffer = StringValue buffer if buffer

if @ibuffer.size > 0
return @ibuffer.shift(size)
end

if str = read_if_available(size)
begin
str = read_if_available(size)
rescue EAGAINWaitReadable => exc
raise exc unless opts[:exception] == false

return :wait_readable
end

if str
buffer.replace(str) if buffer
return str
else
raise EOFError, "stream closed"
raise EOFError, "stream closed" unless opts[:exception] == false
end
end

@@ -2438,7 +2451,7 @@ def write(data)
data.bytesize
end

def write_nonblock(data)
def write_nonblock(data, opts={})
ensure_open_and_writable

data = String data
@@ -2447,6 +2460,10 @@ def write_nonblock(data)
@ibuffer.unseek!(self) unless @sync

raw_write(data)
rescue EAGAINWaitWritable => exc
raise exc unless opts[:exception] == false

return :wait_writable
end

def close
44 changes: 3 additions & 41 deletions spec/ruby/core/argf/read_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/read', __FILE__)

describe "ARGF.read" do
it_behaves_like :argf_read, :read

before :each do

@file1_name = fixture __FILE__, "file1.txt"
@@ -28,34 +31,6 @@
end
end

it "treats second nil argument as no output buffer" do
argv [@file1_name] do
ARGF.read(nil, nil).should == @file1
end
end

it "treats second argument as an output buffer" do
argv [@file1_name] do
buffer = ""
ARGF.read(nil, buffer)
buffer.should == @file1
end
end

it "reads a number of bytes from the first file" do
argv [@file1_name] do
ARGF.read(5).should == @file1[0,5]
end
end

it "reads from a single file consecutively" do
argv [@file1_name] do
ARGF.read(1).should == @file1[0,1]
ARGF.read(2).should == @file1[1,2]
ARGF.read(3).should == @file1[3,3]
end
end

it "reads the contents of two files" do
argv [@file1_name, @file2_name] do
ARGF.read.should == @file1 + @file2
@@ -81,11 +56,6 @@
stdin.should == @stdin
end

it "reads a number of bytes from stdin" do
stdin = ruby_exe("print ARGF.read(10)", :args => "< #{@stdin_name}")
stdin.should == @stdin[0,10]
end

it "reads the contents of one file and stdin" do
stdin = ruby_exe("print ARGF.read", :args => "#{@file1_name} - < #{@stdin_name}")
stdin.should == @file1 + @stdin
@@ -97,14 +67,6 @@
end
end

platform_is_not :windows do
it "reads the contents of a special device file" do
argv ['/dev/zero'] do
ARGF.read(100).should == "\000" * 100
end
end
end

with_feature :encoding do

before :each do
75 changes: 75 additions & 0 deletions spec/ruby/core/argf/readpartial_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/read', __FILE__)

describe "ARGF.readpartial" do
it_behaves_like :argf_read, :readpartial

before :each do
@file1_name = fixture __FILE__, "file1.txt"
@file2_name = fixture __FILE__, "file2.txt"
@stdin_name = fixture __FILE__, "stdin.txt"

@file1 = File.read @file1_name
@file2 = File.read @file2_name
@stdin = File.read @stdin_name
end

it "raises an ArgumentError if called without a maximum read length" do
argv [@file1_name] do
lambda { ARGF.readpartial }.should raise_error(ArgumentError)
end
end

it "reads maximum number of bytes from one file at a time" do
argv [@file1_name, @file2_name] do
len = @file1.size + @file2.size
ARGF.readpartial(len).should == @file1
end
end

it "clears output buffer even if EOFError is raised because ARGF is at end" do
begin
output = "to be cleared"

argv [@file1_name] do
ARGF.read
ARGF.readpartial(1, output)
end
rescue EOFError
output.should == ""
end
end

it "reads maximum number of bytes from one file at a time" do
argv [@file1_name, @file2_name] do
len = @file1.size + @file2.size
ARGF.readpartial(len).should == @file1
end
end

it "returns an empty string if EOFError is raised while reading any but the last file" do
argv [@file1_name, @file2_name] do
ARGF.readpartial(@file1.size)
ARGF.readpartial(1).should == ""
end
end

it "raises an EOFError if the exception was raised while reading the last file" do
argv [@file1_name, @file2_name] do
ARGF.readpartial(@file1.size)
ARGF.readpartial(1)
ARGF.readpartial(@file2.size)
lambda { ARGF.readpartial(1) }.should raise_error(EOFError)
lambda { ARGF.readpartial(1) }.should raise_error(EOFError)
end
end

it "raises an EOFError if the exception was raised while reading STDIN" do
ruby_str = <<-STR
print ARGF.readpartial(#{@stdin.size})
ARGF.readpartial(1) rescue print $!.class
STR
stdin = ruby_exe(ruby_str, args: "< #{@stdin_name}", escape: true)
stdin.should == @stdin + "EOFError"
end
end
62 changes: 62 additions & 0 deletions spec/ruby/core/argf/shared/read.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
describe :argf_read, shared: true do
before :each do
@file1_name = fixture __FILE__, "file1.txt"
@stdin_name = fixture __FILE__, "stdin.txt"

@file1 = File.read @file1_name
@stdin = File.read @stdin_name
end

after :each do
ARGF.close unless ARGF.closed?
end

it "treats second nil argument as no output buffer" do
argv [@file1_name] do
ARGF.send(@method, @file1.size, nil).should == @file1
end
end

it "treats second argument as an output buffer" do
argv [@file1_name] do
buffer = ""
ARGF.send(@method, @file1.size, buffer)
buffer.should == @file1
end
end

it "clears output buffer before appending to it" do
argv [@file1_name] do
buffer = "to be cleared"
ARGF.send(@method, @file1.size, buffer)
buffer.should == @file1
end
end

it "reads a number of bytes from the first file" do
argv [@file1_name] do
ARGF.send(@method, 5).should == @file1[0, 5]
end
end

it "reads from a single file consecutively" do
argv [@file1_name] do
ARGF.send(@method, 1).should == @file1[0, 1]
ARGF.send(@method, 2).should == @file1[1, 2]
ARGF.send(@method, 3).should == @file1[3, 3]
end
end

it "reads a number of bytes from stdin" do
stdin = ruby_exe("print ARGF.#{@method}(10)", :args => "< #{@stdin_name}")
stdin.should == @stdin[0, 10]
end

platform_is_not :windows do
it "reads the contents of a special device file" do
argv ['/dev/zero'] do
ARGF.send(@method, 100).should == "\000" * 100
end
end
end
end
54 changes: 43 additions & 11 deletions spec/ruby/core/io/read_nonblock_spec.rb
Original file line number Diff line number Diff line change
@@ -11,8 +11,42 @@
@write.close rescue nil
end

it "raises IO::EAGAINWaitReadable when there is no data" do
lambda { @read.read_nonblock(5) }.should raise_error(IO::EAGAINWaitReadable)
context "when exception option is not passed" do
context "when there is no data" do
it "raises IO::EAGAINWaitReadable" do
lambda { @read.read_nonblock(5) }.should raise_error(IO::EAGAINWaitReadable)
end
end

context "when the end is reached" do
it "raises EOFError" do
@write << "hello"
@write.close

@read.read_nonblock(5)

lambda { @read.read_nonblock(5) }.should raise_error(EOFError)
end
end
end

context "when exception option is set to false" do
context "when there is no data" do
it "returns :wait_readable" do
@read.read_nonblock(5, exception: false).should == :wait_readable
end
end

context "when the end is reached" do
it "returns nil" do
@write << "hello"
@write.close

@read.read_nonblock(5)

@read.read_nonblock(5, exception: false).should be_nil
end
end
end

it "returns at most the number of bytes requested" do
@@ -35,6 +69,13 @@
@read.read_nonblock(1).should == "1"
end

it "reads into the passed buffer" do
buffer = ""
@write.write("1")
@read.read_nonblock(1, buffer)
buffer.should == "1"
end

not_compliant_on :rubinius, :jruby do
# TODO: Fix this.
#
@@ -46,13 +87,4 @@
it "raises IOError on closed stream" do
lambda { IOSpecs.closed_io.read_nonblock(5) }.should raise_error(IOError)
end

it "raises EOFError when the end is reached" do
@write << "hello"
@write.close

@read.read_nonblock(5)

lambda { @read.read_nonblock(5) }.should raise_error(EOFError)
end
end
16 changes: 13 additions & 3 deletions spec/ruby/core/io/write_nonblock_spec.rb
Original file line number Diff line number Diff line change
@@ -44,9 +44,19 @@
@write.close
end

it 'raises IO::EAGAINWaitWritable when the operation would block' do
proc { loop { @write.write_nonblock('a' * 10_000) } }
.should raise_error(IO::EAGAINWaitWritable)
context "when the operation would block" do
context "when exception option is not passed" do
it "raises IO::EAGAINWaitWritable" do
lambda { loop { @write.write_nonblock("a" * 10_000) } }.should raise_error(IO::EAGAINWaitWritable)
end
end

context "when exception option is set to false" do
it "returns :wait_writable" do
loop { break if @write.write_nonblock("a" * 10_000, exception: false) == :wait_writable }
1.should == 1
end
end
end
end