Project

General

Profile

Bug #1582

IO.new Raises Other Errors between 1.8 and 1.9

Added by ujihisa (Tatsuhiro Ujihisa) over 10 years ago. Updated over 8 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
ruby -v:
ruby 1.9.2dev (2009-06-05 trunk 23641) [i386-darwin9.7.0]
Backport:
[ruby-dev:38571]

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

Related issues

Related to Ruby master - Bug #2796: IO behaviors on mingwClosedActions

History

#1

Updated by akr (Akira Tanaka) over 10 years ago

=begin
32bit Solaris の FILE 構造体は fd が 1byte で表現されているため、rb_fdopen で FILE構造体を生成すると、256以上の fd を扱えなくなります。

=end

#2

Updated by ujihisa (Tatsuhiro Ujihisa) over 10 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

#3

Updated by akr (Akira Tanaka) over 10 years ago

=begin
そのとおりで、1.8 では動きません。

1.9 では動くようにしたので、それを動かないようにするのは受け入れられません。
=end

#4

Updated by yugui (Yuki Sonoda) over 10 years ago

  • Status changed from Open to Rejected

=begin
本件はrejectということで良いでしょうか?
=end

#5

Updated by nobu (Nobuyoshi Nakada) over 10 years ago

  • Status changed from Rejected to Open

=begin

=end

#6

Updated by nobu (Nobuyoshi Nakada) over 10 years ago

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

=begin
Applied in changeset r24102.
=end

#7

Updated by mame (Yusuke Endoh) over 9 years ago

  • Status changed from Closed to Open

=begin
遠藤です。

なかださんの修正に regression があるみたいです。
いまから kosaki さんが詳細を書いてくれます。

--
Yusuke Endoh mame@tsg.ne.jp
=end

#8

Updated by kosaki (Motohiro KOSAKI) over 9 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

#9

Updated by nobu (Nobuyoshi Nakada) over 9 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: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.fileno, "r"); p f2.gets'
-e:1:in initialize': 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

#10

Updated by kosaki (Motohiro KOSAKI) over 9 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: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.fileno, "r"); p f2.gets'
-e:1:in initialize': 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

#11

Updated by no6v (Nobuhiro IMAI) over 9 years ago

=begin
いまいです。

From: KOSAKI Motohiro
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

#12

Updated by no6v (Nobuhiro IMAI) over 9 years ago

=begin
いまいです。

From: Nobuhiro IMAI
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]しました。内容が
あっているか見ていただけるとありがたいです。

  1. http://www.fdiary.net/ml/ruby-reference-manual/msg/360
  2. 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

#13

Updated by no6v (Nobuhiro IMAI) over 9 years ago

=begin
いまいです。

From: KOSAKI Motohiro
Date: Wed, 3 Mar 2010 13:23:29 +0900

今のところ、メソッドシグネチャで引数にデフォルト値がある場合は書いてお
く、というルール[1]があるようなので、説明文だけ追加[2]しました。内容が
あっているか見ていただけるとありがたいです。

  1. http://www.fdiary.net/ml/ruby-reference-manual/msg/360
  2. http://redmine.ruby-lang.org/repositories/diff/rurema?rev=3924

確認しました。

ありがとうございます。

エンドユーザは自分の環境が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

#14

Updated by wanabe (_ wanabe) over 9 years ago

  • Status changed from Open to Closed

=begin
r24102 についての議論は [Bug #2796] で、とのことですのでクローズさせて頂きます。
問題がありましたら再オープンをお願いします。
=end

Also available in: Atom PDF