近永です。

以下のようなことをすると、Segmentation Fault します。

chika#ruby -v
ruby 1.5.0 (1999-10-12) [i586-linux]
chika#cat test.rb
require "readline"
require "pstore"
include Readline

class SignalInt < StandardError
end
trap("SIGINT"){raise SignalInt}

while (key = readline("key>",true)) != nil
  db = PStore.new("dbfile")
  db.transaction do
    begin
      db["root"][key] = readline("value>",true)
    rescue SignalInt
      print "interrupted!\n"
      db.abort
    end
  end
end

chika#ruby test.rb
key>hoge
value>interrupted!  <==C-c
key>foo
value>Segmentation Fault  <==C-c

どうも2度目にSIGINTを送ると、なんどもなんども、
無限にSIGINTを受けとってるみたいでした。
Readline.readline を gets.chomp などにかえると
この状態はおきません。
これってバグでしょうか?
僕の書きかたが悪い気もするんですが……

とおもって、[ruby-dev:2297]あたりを読んでみたら
signal trap で例外を発生させるのは
よくないみたいでしたが、この場合も
trapの書きかたが悪いのでしょうか?
確かに

trap("SIGINT"){$int_flag = true}
..snip...
db.transaction do
  db["root"][key] = readline("value>",true)
  if $int_flag then db.abort; $int_flag = false; end
end
のようにすれば問題は回避できますが
C-c Returnと2度キーを押すことになるし、
まちがえてC-cを押してしまったときに気がつかずに
入力したつもりになることがありそうで
ちょっといやなのですが…

このこと(trap に渡すブロック内では raise を使わない)は
どこかに書かれてたでしょうか?
なかったらどこかで注意しておいたほうが
いいと思うのですが。
あるいは、なにか勘違いをしてるのかも。
そうだったらすみません。

	Chikanaga Tomoyuki.
	chikanaga / molbio.biophys.kyoto-u.ac.jp