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: 79e4f128d4f9
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 30f875df1c0a
Choose a head ref
  • 13 commits
  • 6 files changed
  • 1 contributor

Commits on Oct 7, 2015

  1. Copy the full SHA
    8ebb83d View commit details
  2. Copy the full SHA
    ac51ceb View commit details
  3. Copy the full SHA
    c23c9a5 View commit details
  4. Copy the full SHA
    d44ead8 View commit details
  5. Copy the full SHA
    e279dfe View commit details
  6. Copy the full SHA
    d576700 View commit details
  7. Copy the full SHA
    f7782fb View commit details
  8. Copy the full SHA
    4b501cd View commit details
  9. Copy the full SHA
    35760bd View commit details
  10. Copy the full SHA
    6ce9c58 View commit details
  11. Copy the full SHA
    66373b2 View commit details
  12. Copy the full SHA
    e4006fc View commit details
  13. Copy the full SHA
    30f875d View commit details
85 changes: 58 additions & 27 deletions kernel/common/io.rb
Original file line number Diff line number Diff line change
@@ -230,15 +230,7 @@ def read(length, output_string=nil)
raise IOError, "read(2) failed to malloc a buffer for read length #{length}" if storage.null?
bytes_read = read_into_storage(length, storage)

if FFI.call_failed?(bytes_read)
if Errno.eql?(Errno::EAGAIN::Errno) || Errno.eql?(Errno::EINTR::Errno)
redo
else
Errno.handle "read(2) failed"
end

return nil
elsif bytes_read == 0
if bytes_read == 0
@eof = true if length > 0
return nil
else
@@ -278,6 +270,9 @@ def read_into_storage(count, storage)
end
end

# before returning verify file hasn't been closed in another thread
ensure_open

return bytes_read
end
private :read_into_storage
@@ -1701,27 +1696,27 @@ def super_inspect
# alias_method :prim_read, :read

def descriptor
@fd.descriptor
@fd.descriptor if @fd
end

def descriptor=(value)
@fd.descriptor = value
@fd.descriptor = value if @fd
end

def mode
@fd.mode
@fd.mode if @fd
end

def mode=(value)
@fd.mode = value
@fd.mode = value if @fd
end

def sync
@fd.sync
@fd.sync if @fd
end

def sync=(value)
@fd.sync = value
@fd.sync = value if @fd
end

def advise(advice, offset = 0, len = 0)
@@ -1733,7 +1728,7 @@ def advise(advice, offset = 0, len = 0)
end

unless [:normal, :sequential, :random, :noreuse, :dontneed, :willneed].include? advice
raise NotImplementedError, "Unsupported advice: #{advice}"
raise NotImplementedError, advice.inspect
end

advice = case advice
@@ -1814,10 +1809,13 @@ def <<(obj)
# prog.rb:3:in `readlines': not opened for reading (IOError)
# from prog.rb:3
def close_read
return if invalid_descriptor?

if @fd.write_only? || @fd.read_write?
raise IOError, 'closing non-duplex IO for reading'
end
close

@fd.close unless closed?
end

##
@@ -1834,10 +1832,13 @@ def close_read
# from prog.rb:3:in `print'
# from prog.rb:3
def close_write
return if invalid_descriptor?

if @fd.read_only? || @fd.read_write?
raise IOError, 'closing non-duplex IO for writing'
end
close

@fd.close unless closed?
end

##
@@ -1853,7 +1854,7 @@ def close_write
# f.close_read #=> nil
# f.closed? #=> true
def closed?
@fd.descriptor == -1
invalid_descriptor?
end

def dup
@@ -2098,10 +2099,14 @@ def increment_lineno
##
# Return a string describing this IO object.
def inspect
if @fd.descriptor != -1
"#<#{self.class}:fd #{@fd.descriptor}>"
if @fd
if @fd.descriptor != -1
"#<#{self.class}:fd #{@fd.descriptor}>"
else
"#<#{self.class}:(closed)>"
end
else
"#<#{self.class}:(closed)"
"#<#{self.class}:fd nil>"
end
end

@@ -2142,7 +2147,28 @@ def each(sep_or_limit=$/, limit=nil, &block)
self
end

alias_method :each_line, :each
def each_line(sep_or_limit=$/, limit=nil, &block)
if limit
limit = Rubinius::Type.coerce_to limit, Integer, :to_int
sep = sep_or_limit ? StringValue(sep_or_limit) : nil
raise ArgumentError, "invalid limit: 0 for each_line" if limit.zero?
else
case sep_or_limit
when String
sep = sep_or_limit
when nil
sep = nil
else
unless sep = Rubinius::Type.check_convert_type(sep_or_limit, String, :to_str)
sep = $/
limit = Rubinius::Type.coerce_to sep_or_limit, Integer, :to_int
raise ArgumentError, "invalid limit: 0 for each_line" if limit.zero?
end
end
end

each(sep_or_limit, limit, &block)
end

def each_byte
return to_enum(:each_byte) unless block_given?
@@ -3227,6 +3253,7 @@ def write_nonblock(data)
end

def close
return if closed?
begin
flush
ensure
@@ -3246,6 +3273,7 @@ def close
end

def ensure_open(fd=nil)
raise IOError, "uninitialized stream" unless @fd
@fd.ensure_open(fd)
end

@@ -3258,6 +3286,11 @@ def ensure_open_and_writable
ensure_open
raise IOError, "not opened for writing" if @fd.read_only?
end

def invalid_descriptor?
descriptor == -1 || descriptor.nil?
end
private :invalid_descriptor?
end

##
@@ -3292,13 +3325,11 @@ def closed?
end

def close_read
raise IOError, 'closed stream' if closed?

close
super
end

def close_write
raise IOError, 'closed stream' if @write.closed?
return if @write.closed?

@write.close
end
12 changes: 4 additions & 8 deletions spec/ruby/core/io/close_read_spec.rb
Original file line number Diff line number Diff line change
@@ -19,10 +19,8 @@
lambda { @io.read }.should raise_error(IOError)
end

it "raises an IOError on subsequent invocations" do
@io.close_read

lambda { @io.close_read }.should raise_error(IOError)
it "does nothing on subsequent invocations" do
@io.close_read.should be_nil
end

it "allows subsequent invocation of close" do
@@ -52,10 +50,8 @@
io.closed?.should == true
end

it "raises IOError on closed stream" do
@io.close

lambda { @io.close_read }.should raise_error(IOError)
it "does nothing on closed stream" do
@io.close.should be_nil
end

end
2 changes: 1 addition & 1 deletion spec/ruby/core/io/close_spec.rb
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@
lambda { @io.write "data" }.should raise_error(IOError)
end

it "raises an IOError if closed" do
it "does nothing if closed" do
@io.close
lambda { @io.close }.should raise_error(IOError)
end
12 changes: 4 additions & 8 deletions spec/ruby/core/io/close_write_spec.rb
Original file line number Diff line number Diff line change
@@ -18,10 +18,8 @@
lambda { @io.write "attempt to write" }.should raise_error(IOError)
end

it "raises an IOError on subsequent invocations" do
@io.close_write

lambda { @io.close_write }.should raise_error(IOError)
it "does nothing on subsequent invocations" do
@io.close_write.should be_nil
end

it "allows subsequent invocation of close" do
@@ -56,9 +54,7 @@
@io.read.should == "12345\n"
end

it "raises IOError on closed stream" do
@io.close

lambda { @io.close_write }.should raise_error(IOError)
it "does nothing on closed stream" do
@io.close.should be_nil
end
end
14 changes: 14 additions & 0 deletions spec/ruby/core/io/each_line_spec.rb
Original file line number Diff line number Diff line change
@@ -9,3 +9,17 @@
describe "IO#each_line" do
it_behaves_like :io_each_default_separator, :each_line
end

describe "IO#each_line" do
before :each do
@io = IOSpecs.io_fixture "lines.txt"
end

after :each do
@io.close
end

it "raises ArgumentError when given a limit of 0" do
lambda { @io.each_line(0) }.should raise_error(ArgumentError)
end
end
17 changes: 17 additions & 0 deletions spec/ruby/core/io/read_spec.rb
Original file line number Diff line number Diff line change
@@ -278,6 +278,23 @@
it "raises IOError on closed stream" do
lambda { IOSpecs.closed_io.read }.should raise_error(IOError)
end

it "raises IOError when stream is closed by another thread" do
r, w = IO.pipe
t = Thread.new do
begin
r.read(1)
rescue => e
e
end
end

sleep(0.1) until t.stop?
r.close
t.join
t.value.should be_kind_of(IOError)
w.close
end
end

platform_is :windows do