Project

General

Profile

Backport #2560

IO.read not always closes the file

Added by vvs (Vladimir Sizikov) almost 10 years ago. Updated 3 months ago.

Status:
Closed
Priority:
Normal
[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.

1)
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
'
D:/work/jruby-dev/mspec.git/bin/mspec-run:8:in `'

2)
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
'
D:/work/jruby-dev/mspec.git/bin/mspec-run:8:in `'
=end

History

#1

Updated by usa (Usaku NAKAMURA) almost 10 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, redmine@ruby-lang.org 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 usa@garbagecollect.jp

=end

#2

Updated by matz (Yukihiro Matsumoto) almost 10 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" usa@garbagecollect.jp writes:

|In message "[ruby-core:27429] [Bug #2560] IO.read not always closes the file"
| on Jan.06,2010 02:31:39, redmine@ruby-lang.org 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

#3

Updated by usa (Usaku NAKAMURA) almost 10 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

#4

Updated by usa (Usaku NAKAMURA) almost 10 years ago

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

=begin

=end

#5

Updated by jeremyevans0 (Jeremy Evans) 3 months ago

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

Also available in: Atom PDF