Bug #5952

コマンドラインモードで CGI.new を 2 回実行すると IOError が発生する

Added by Hiroshi SHIBATA about 2 years ago. Updated about 2 years ago.

[ruby-dev:45160]
Status:Closed
Priority:Normal
Assignee:Nobuyoshi Nakada
Category:core
Target version:1.9.3
ruby -v:ruby 1.9.3p28 (2012-01-28 revision 34386) [x86_64-darwin11.2.0] Backport:

Description

=begin
1.9.3p28, trunk で以下のスクリプトを実行すると2回目の CGI.new で パラメータを受け取る時に IOError が発生します。
% cat cli.rb
require 'cgi'
CGI.new
CGI.new

% ruby cli.rb

(offline mode: enter name=value pairs on standard input)
/Users/hsbt/.rbenv/versions/2.0.0-dev/lib/ruby/2.0.0/cgi/core.rb:595:in tty?': closed stream (IOError)
from /Users/hsbt/.rbenv/versions/2.0.0-dev/lib/ruby/2.0.0/cgi/core.rb:595:in
readfromcmdline'
from /Users/hsbt/.rbenv/versions/2.0.0-dev/lib/ruby/2.0.0/cgi/core.rb:645:in initialize_query'
from /Users/hsbt/.rbenv/versions/2.0.0-dev/lib/ruby/2.0.0/cgi/core.rb:806:in
initialize'
from cli.rb:4:in new'
from cli.rb:4:in
'

1.9.2p290 や 1.8.7p357 ではエラーなく2回パラメータを入力可能です。
=end


Related issues

Related to Backport93 - Backport #5955: Please backport r34409(io.c: skip stdin, which should be ... Closed 02/01/2012

Associated revisions

Revision 34409
Added by Nobuyoshi Nakada about 2 years ago

  • io.c (argf_close): skip stdin, which should be readable again. [Bug #5952]
  • io.c (argf_readlines): reinitialize after all read to be readable again.

Revision 34417
Added by Yui NARUSE about 2 years ago

  • io.c (argfnextargv): reset ARGF.next_p on ARGV.replace. r34409 breaks replacing ARGV. [Bug #5952]

History

#1 Updated by Tomoyuki Chikanaga about 2 years ago

  • Category set to core

r29781 以降 Kernel#readlines (ARGF.readlines) で EOF を検出すると stdin を close するようになっていたようです。以下のようなサンプルで現象を確認できます。

readlines.rb:
p STDIN.closed? # => false
p readlines # => [] <- Ctrl-D で EOF を送出
p STDIN.closed? # => true
p readlines # => [] <- すぐにかえってくる

1.9.2 では最後の STDIN.closed? は false のままで、2度目の readlines は入力を待ちます。

ARGF.current_file が標準入力だったら close しないようにするととりあえずこの現象は直りました。これでどうでしょう。

diff --git a/io.c b/io.c
index a3a45c0..e877f13 100644
--- a/io.c
+++ b/io.c
@@ -7684,7 +7684,8 @@ argfreadlines(int argc, VALUE *argv, VALUE argf)
}
else {
lines = rb
ioreadlines(argc, argv, ARGF.currentfile);
- argfclose(ARGF.currentfile);
+ if ( ARGF.currentfile != rbstdin )
+ argfclose(ARGF.currentfile);
}
ARGF.nextp = 1;
rb
ary_concat(ary, lines);

#2 Updated by Nobuyoshi Nakada about 2 years ago

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

This issue was solved with changeset r34409.
Hiroshi, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • io.c (argf_close): skip stdin, which should be readable again. [Bug #5952]
  • io.c (argf_readlines): reinitialize after all read to be readable again.

#3 Updated by Hiroshi SHIBATA about 2 years ago

r34409 で修正されているのを確認しました。ありがとうございます。

#4 Updated by Yui NARUSE about 2 years ago

  • Status changed from Closed to Assigned
  • Assignee set to Nobuhiro Iwamatsu

#5 Updated by Yui NARUSE about 2 years ago

  • Assignee changed from Nobuhiro Iwamatsu to Nobuyoshi Nakada

#6 Updated by Yui NARUSE about 2 years ago

  • Status changed from Assigned to Closed

The test is removed on r34412.

#7 Updated by Motohiro KOSAKI about 2 years ago

2012年1月31日9:34 Tomoyuki Chikanaga nagachika00@gmail.com:

Issue #5952 has been updated by Tomoyuki Chikanaga.

Category set to core

r29781 以降 Kernel#readlines (ARGF.readlines) で EOF を検出すると stdin を close するようになっていたようです。以下のようなサンプルで現象を確認できます。

readlines.rb:
p STDIN.closed? # => false
p readlines # => [] <- Ctrl-D で EOF を送出
p STDIN.closed? # => true
p readlines # => [] <- すぐにかえってくる

1.9.2 では最後の STDIN.closed? は false のままで、2度目の readlines は入力を待ちます。

ARGF.current_file が標準入力だったら close しないようにするととりあえずこの現象は直りました。これでどうでしょう。

経緯をよく分かっていないのですが、stdinはcloseしてはいけないけど、pipeはcloseしていいというのはなにか変な感じがします。一切closeしてはいけないのではないでしょうか

Also available in: Atom PDF