Project

General

Profile

Actions

Backport #2560

closed

IO.read not always closes the file

Added by vvs (Vladimir Sizikov) almost 15 years ago. Updated over 5 years ago.

Status:
Closed
[ruby-core:27429]

Description

=begin
Consider the following:

File.open('test_file', 'wb') { |f| f.write 'abc' }
IO.read('test_file', 0, -1) rescue nil
File.unlink('test_file')

On Windows the unlink call fails with:
`unlink': Permission denied - test_file (Errno::EACCES)

This is due to fact that IO.read, invoked with invalid offset parameter does not close the opened file. But the documentation clearly states that:
"read ensures the file is closed before returning."

This causes two RubySpec failures for IO.read:

mspec -t r core\io\read_spec.rb
ruby 1.9.2dev (2009-11-12 trunk 25723) [i386-mingw32]
..........E..E..................E.

An exception occurred during: after :each
IO.read raises an Errno::EINVAL when not passed a valid offset ERROR
Errno::EACCES: Permission denied - D:/work/jruby-dev/rubyspec.git/rubyspec_temp/io_read.txt
D:/work/jruby-dev/rubyspec.git/core/io/read_spec.rb:13:in block (2 levels) in <top (required)>' D:/work/jruby-dev/rubyspec.git/core/io/read_spec.rb:5:in <top (required)>'
D:/work/jruby-dev/mspec.git/bin/mspec-run:8:in `'

An exception occurred during: after :each
IO#read can be read from consecutively ERROR
Errno::EACCES: Permission denied - D:/work/jruby-dev/rubyspec.git/rubyspec_temp/io_read.txt
D:/work/jruby-dev/rubyspec.git/core/io/read_spec.rb:100:in block (2 levels) in <top (required)>' D:/work/jruby-dev/rubyspec.git/core/io/read_spec.rb:88:in <top (required)>'
D:/work/jruby-dev/mspec.git/bin/mspec-run:8:in `'
=end

Actions #1

Updated by usa (Usaku NAKAMURA) almost 15 years ago

=begin
Hello,

In message "[ruby-core:27429] [Bug #2560] IO.read not always closes the file"
on Jan.06,2010 02:31:39, wrote:

This is due to fact that IO.read, invoked with invalid offset parameter does not close the opened file. But the documentation clearly states that:
"read ensures the file is closed before returning."

1.8 has same problem, too.

This patch is for trunk.

Index: io.c

--- io.c (revision 26249)
+++ io.c (working copy)
@@ -7816,6 +7816,19 @@ io_s_read(struct foreach_arg *arg)
return io_read(arg->argc, arg->argv, arg->io);
}

+struct seek_arg {

  • VALUE io;
  • VALUE offset;
  • int mode;
    +};

+static VALUE
+seek_before_read(struct seek_arg *arg)
+{

  • rb_io_binmode(arg->io);
  • return rb_io_seek(arg->io, arg->offset, arg->mode);
    +}

/*

  • call-seq:
  • IO.read(name, [length [, offset]] )   => string
    

@@ -7858,8 +7871,16 @@ rb_io_s_read(int argc, VALUE *argv, VALU
open_key_args(argc, argv, &arg);
if (NIL_P(arg.io)) return Qnil;
if (!NIL_P(offset)) {

  • rb_io_binmode(arg.io);
  • rb_io_seek(arg.io, offset, SEEK_SET);
  • struct seek_arg sarg;
  • int state = 0;
  • sarg.io = arg.io;
  • sarg.offset = offset;
  • sarg.mode = SEEK_SET;
  • rb_protect((VALUE (*)(VALUE))seek_before_read, (VALUE)&sarg, &state);
  • if (state) {
  •  rb_io_close(arg.io);
    
  •  rb_jump_tag(state);
    
  • }
    if (arg.argc == 2) arg.argc = 1;
    }
    return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);

    Regards,
    --
    U.Nakamura

=end

Actions #2

Updated by matz (Yukihiro Matsumoto) almost 15 years ago

=begin
Hi,

In message "Re: [ruby-core:27483] Re: [Bug #2560] IO.read not always closes the file"
on Fri, 8 Jan 2010 14:29:53 +0900, "U.Nakamura" writes:

|In message "[ruby-core:27429] [Bug #2560] IO.read not always closes the file"
| on Jan.06,2010 02:31:39, wrote:
|> This is due to fact that IO.read, invoked with invalid offset parameter does not close the opened file. But the documentation clearly states that:
|> "read ensures the file is closed before returning."
|
|1.8 has same problem, too.
|
|This patch is for trunk.

Could you check in?

						matz.

=end

Actions #3

Updated by usa (Usaku NAKAMURA) almost 15 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

=begin
This issue was solved with changeset r26250.
Vladimir, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

=end

Actions #4

Updated by usa (Usaku NAKAMURA) almost 15 years ago

  • Status changed from Closed to Assigned
  • Assignee set to yugui (Yuki Sonoda)

=begin

=end

Actions #5

Updated by jeremyevans0 (Jeremy Evans) over 5 years ago

  • Description updated (diff)
  • Status changed from Assigned to Closed
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0