Bug #1582
closedIO.new Raises Other Errors between 1.8 and 1.9
Added by ujihisa (Tatsuhiro Ujihisa) over 15 years ago. Updated over 13 years ago.
Description
=begin
IO.newで引数に与えたファイル記述子のファイルモードと互換性のないファイルモードを与えたとき、ruby 1.8系ではErrno::EINVALを投げるのに対し、ruby 1.9系では例外を投げず、実際に互換性のない行為を実行したときにErrno::EBADFを投げます。
io = File.open('aaa.txt', 'w')
io2 = IO.new(io.fileno, 'r') # 1.8ではこの時点でErrno::EINVAL
io.syswrite '111'
puts io2.read # 1.9ではこの時点でErrno::EBADF
私にはruby 1.8系の挙動の方が心優しい気がするのですが、どうでしょう。添付のパッチを適用すると、1.9でもIO.newの時点でErrno::EINVALを投げるようになります。
=end
Files
io-new-raises-einval.patch (334 Bytes) io-new-raises-einval.patch | ujihisa (Tatsuhiro Ujihisa), 06/06/2009 06:05 AM |
Updated by akr (Akira Tanaka) over 15 years ago
=begin
32bit Solaris の FILE 構造体は fd が 1byte で表現されているため、rb_fdopen で FILE構造体を生成すると、256以上の fd を扱えなくなります。
=end
Updated by ujihisa (Tatsuhiro Ujihisa) over 15 years ago
=begin
とするとこのパッチの参考元の、ruby1.8系のio.cのrb_io_initialize()でrb_fdopen()を呼び出している部分が気になります。
ruby_1_8_7/io.c r23641 line4366
fp->f = rb_fdopen(fd, rb_io_modenum_mode(flags));
ほかにも多数。
いっぽうruby1.9系ですとrb_io_stdio_file()で同様に
trunk/io.c r23641 line5993
fptr->stdio_file = rb_fdopen(fptr->fd, rb_io_oflags_modestr(oflags));
とrb_fdopen()が呼ばれているものの、ここではstdin, stdout, stderrしか与えられないと仮定しているためSolarisでも大丈夫、とそんな風に見えます。
手元に32bit Solarisがなくて試すことができず心もとないですが、報告までに。
=end
Updated by akr (Akira Tanaka) over 15 years ago
=begin
そのとおりで、1.8 では動きません。
1.9 では動くようにしたので、それを動かないようにするのは受け入れられません。
=end
Updated by yugui (Yuki Sonoda) over 15 years ago
- Status changed from Open to Rejected
=begin
本件はrejectということで良いでしょうか?
=end
Updated by nobu (Nobuyoshi Nakada) over 15 years ago
- Status changed from Rejected to Open
=begin
=end
Updated by nobu (Nobuyoshi Nakada) over 15 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
Applied in changeset r24102.
=end
Updated by mame (Yusuke Endoh) almost 15 years ago
- Status changed from Closed to Open
=begin
遠藤です。
なかださんの修正に regression があるみたいです。
いまから kosaki さんが詳細を書いてくれます。
--
Yusuke Endoh mame@tsg.ne.jp
=end
Updated by kosaki (Motohiro KOSAKI) almost 15 years ago
=begin
すいません、regressionは言い過ぎというか間違っていて修正不十分ぐらいが適当でした。
まず、Linuxでは以下の結果になります。
% ./ruby -e 'f1 = File.open("foo.txt", "w"); f1.puts "foo"; f2 = IO.new(f1.fileno); p f2.gets'
-e:1:in gets': not opened for reading (IOError) from -e:1:in
'
% ./ruby -e 'f1 = File.open("foo.txt", "w"); f1.puts "foo"; f2 = IO.new(f1.fi
leno, "r"); p f2.gets'
-e:1:in initialize': Invalid argument (Errno::EINVAL) from -e:1:in
new'
from -e:1:in `'
http://doc.okkez.net/static/191/class/IO.html をみると
new(fd, mode = "r") -> IO
と書いてあるので、IO.new()のmode引数のデフォルトは"r"のはずで、これは変です。
そのカラクリですが、
rb_io_initialize で
#if defined(HAVE_FCNTL) && defined(F_GETFL)
oflags = fcntl(fd, F_GETFL);
(snip)
ofmode = rb_io_oflags_fmode(oflags);
if (NIL_P(vmode)) {
fmode = ofmode;
}
というコードがあるために、引数なしの時はfd引数のアクセス権を継承する仕様に変わってしまっています。
リファレンスが正しいなら、mode引数を省略したときも単に"r"と解釈してEINVALになるべきに見えます。
これは意図的でしょうか?意図したものである場合、ドキュメントの修正をご検討くださいませ
=end
Updated by nobu (Nobuyoshi Nakada) almost 15 years ago
=begin
なかだです。
At Sat, 27 Feb 2010 01:45:54 +0900,
Motohiro KOSAKI wrote in [ruby-dev:40509]:
すいません、regressionは言い過ぎというか間違っていて修正不十分ぐらいが適当でした。
まず、Linuxでは以下の結果になります。% ./ruby -e 'f1 = File.open("foo.txt", "w"); f1.puts "foo"; f2 = IO.new(f1.fileno); p f2.gets'
-e:1:ingets': not opened for reading (IOError) from -e:1:in
'% ./ruby -e 'f1 = File.open("foo.txt", "w"); f1.puts "foo"; f2 = IO.new(f1.fileno, "r"); p f2.gets'
-e:1:ininitialize': Invalid argument (Errno::EINVAL) from -e:1:in
new'
from -e:1:in `'
1.8までと動作を合わせてあります。
http://doc.okkez.net/static/191/class/IO.html をみると
new(fd, mode = "r") -> IO
1.9のrdocではmodeのデフォルト値についての記述は削られています。
これは意図的でしょうか?意図したものである場合、ドキュメントの修正をご検討くださいませ
1.8までのドキュメントのバグだと思います。
--
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
中田 伸悦
=end
Updated by kosaki (Motohiro KOSAKI) almost 15 years ago
=begin
2010年2月27日9:43 Nobuyoshi Nakada nobu@ruby-lang.org:
なかだです。
At Sat, 27 Feb 2010 01:45:54 +0900,
Motohiro KOSAKI wrote in [ruby-dev:40509]:すいません、regressionは言い過ぎというか間違っていて修正不十分ぐらいが適当でした。
まず、Linuxでは以下の結果になります。% ./ruby -e 'f1 = File.open("foo.txt", "w"); f1.puts "foo"; f2 = IO.new(f1.fileno); p f2.gets'
-e:1:ingets': not opened for reading (IOError) from -e:1:in
'% ./ruby -e 'f1 = File.open("foo.txt", "w"); f1.puts "foo"; f2 = IO.new(f1.fileno, "r"); p f2.gets'
-e:1:ininitialize': Invalid argument (Errno::EINVAL) from -e:1:in
new'
from -e:1:in `'1.8までと動作を合わせてあります。
http://doc.okkez.net/static/191/class/IO.html をみると
new(fd, mode = "r") -> IO
1.9のrdocではmodeのデフォルト値についての記述は削られています。
上記URLはいちおう1.9.1用のはずなんですが、誰が修正担当なんでしょう??
あのURLを見るのが間違い? ruby-lang.org からリンクが貼ってあるから、ほとんどの人は
そこから誘導されていると思いますが
これは意図的でしょうか?意図したものである場合、ドキュメントの修正をご検討くださいませ
1.8までのドキュメントのバグだと思います。
動作としては現在の挙動が望ましいことには同意します。ただ、windowsのようにfcntl(GETFL)できない環境ではmode継承がされてないので挙動が変わってしまうのですがどこにも文書化されてません。これはこれで問題だと思います。
この問題の発端は [ruby-dev:40506] の (2) 課題提起でした。
とりあえず、このチケット自体は再度クローズしてよくて、[ruby-dev:40506]
で継続議論すればいいと思うのですが、私には閉じる権限がないので親切なコミッターさんが閉じてくれるのを期待します。
=end
Updated by no6v (Nobuhiro IMAI) almost 15 years ago
=begin
いまいです。
From: KOSAKI Motohiro <kosaki.motohiro_at_gmail.com>
Date: Sat, 27 Feb 2010 12:07:11 +0900
http://doc.okkez.net/static/191/class/IO.html をみると
new(fd, mode = "r") -> IO
1.9のrdocではmodeのデフォルト値についての記述は削られています。
上記URLはいちおう1.9.1用のはずなんですが、誰が修正担当なんでしょう??
あのURLを見るのが間違い? ruby-lang.org からリンクが貼ってあるから、ほとんどの人は
そこから誘導されていると思いますが
私にはどう修正してよいのかまだ理解できていないのですが、リファレンスの
問題ということは認識できたので、以下に記録してしておきました。
題名が不適切かもしれません。¶
http://redmine.ruby-lang.org/issues/show/2800
これは意図的でしょうか?意図したものである場合、ドキュメントの修正をご検討くださいませ
1.8までのドキュメントのバグだと思います。
動作としては現在の挙動が望ましいことには同意します。ただ、windowsのようにfcntl(GETFL)できない環境ではmode継承がされてないので挙動が変わってしまうのですがどこにも文書化されてません。これはこれで問題だと思います。
引数だけでなく、記述を追加する必要もあるということですよね。¶
Nobuhiro IMAI nov@yo.rim.or.jp
Key fingerprint = F39E D552 545D 7C64 D690 F644 5A15 746C BD8E 7106
=end
Updated by no6v (Nobuhiro IMAI) almost 15 years ago
=begin
いまいです。
From: Nobuhiro IMAI <nov_at_yo.rim.or.jp>
Date: Sat, 27 Feb 2010 13:01:30 +0900
上記URLはいちおう1.9.1用のはずなんですが、誰が修正担当なんでしょう??
あのURLを見るのが間違い? ruby-lang.org からリンクが貼ってあるから、ほとんどの人は
そこから誘導されていると思いますが私にはどう修正してよいのかまだ理解できていないのですが、リファレンスの
問題ということは認識できたので、以下に記録してしておきました。題名が不適切かもしれません。¶
http://redmine.ruby-lang.org/issues/show/2800
これは意図的でしょうか?意図したものである場合、ドキュメントの修正をご検討くださいませ
1.8までのドキュメントのバグだと思います。
動作としては現在の挙動が望ましいことには同意します。ただ、windowsのようにfcntl(GETFL)できない環境ではmode継承がされてないので挙動が変わってしまうのですがどこにも文書化されてません。これはこれで問題だと思います。
引数だけでなく、記述を追加する必要もあるということですよね。
今のところ、メソッドシグネチャで引数にデフォルト値がある場合は書いてお
く、というルール[1]があるようなので、説明文だけ追加[2]しました。内容が
あっているか見ていただけるとありがたいです。
- http://www.fdiary.net/ml/ruby-reference-manual/msg/360
-
http://redmine.ruby-lang.org/repositories/diff/rurema?rev=3924
--
Nobuhiro IMAI nov@yo.rim.or.jp
Key fingerprint = F39E D552 545D 7C64 D690 F644 5A15 746C BD8E 7106
=end
Updated by no6v (Nobuhiro IMAI) almost 15 years ago
=begin
いまいです。
From: KOSAKI Motohiro <kosaki.motohiro_at_jp.fujitsu.com>
Date: Wed, 3 Mar 2010 13:23:29 +0900
今のところ、メソッドシグネチャで引数にデフォルト値がある場合は書いてお
く、というルール[1]があるようなので、説明文だけ追加[2]しました。内容が
あっているか見ていただけるとありがたいです。確認しました。
ありがとうございます。
エンドユーザは自分の環境がfcntlが利用できる環境かどうか知っているのだろうか?
と素朴な疑問がわきました。
require "fcntl" できるとか、今回の用途では Fcntl::F_GETFL が定義されて
いる、とか見ればいいのかな?私自身、よく分かってません。
まったく分かってなくて恐縮なのですが、リファレンスの習慣的には「xxが利用できる環境」
という表記と「Windows環境では」という表記のどちらが一般的なのでしょうか。
前者の場合、なにも問題ないと思います。
行単位でしか調べていませんが、「Windows 環境」という表現は少なく、例え
ば、Encoding.locale_charmap の説明には「nl_langinfo 等がない環境では」
という表現があったので、今回はとりあえずこのままにしておこうと思います。
Nobuhiro IMAI nov@yo.rim.or.jp
Key fingerprint = F39E D552 545D 7C64 D690 F644 5A15 746C BD8E 7106
=end
Updated by wanabe (_ wanabe) over 14 years ago
- Status changed from Open to Closed
=begin
r24102 についての議論は [Bug #2796] で、とのことですのでクローズさせて頂きます。
問題がありましたら再オープンをお願いします。
=end