Backport #2560
closedIO.read not always closes the file
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
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, 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
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" 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
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
Updated by usa (Usaku NAKAMURA) almost 15 years ago
- Status changed from Closed to Assigned
- Assignee set to yugui (Yuki Sonoda)
=begin
=end
Updated by jeremyevans0 (Jeremy Evans) over 5 years ago
- Description updated (diff)
- Status changed from Assigned to Closed