From: keiju@... (=?ISO-2022-JP?B?GyRCQFBETTc9PHkbKEI=?= ) Date: 1998-03-18T11:55:54+09:00 Subject: [ruby-dev:1850] Re: trap and throw problem けいじゅ@日本ラショナルソフトウェアです. In [ruby-dev :01848 ] the message: "[ruby-dev:1848] Re: trap and throw problem ", on Mar/18 10:48(JST) Yukihiro Matsumoto writes: >まつもと ゆきひろです > >このコードではlongjmpでmainの先頭に戻るので,bufの領域やpの >値がそのまま残っているからだと思います.rubyのgetsの場合,そ >の関数の外側までジャンプしますので,読み込んだ領域が残ってい >るのは考えにくいんですが…. そうじゃなくて, stdioの内部バッファに溜っているものがそのまま出ている みたいですよ. >同じ状況を作るためには以下のようなコードが必要だと思います. 同じもの+signalがあると"trap!\n"を出すコードで確かめました. 状況は同じ です. in> abc out> abc in> trap! # 入力待ちの時にいきなり^C in> out> abc # 次のgets()で, 全行の"abc"を読み込む. in> trap! # もう一度^C, in> out> abc # さっきと同じ結果 in> trap! # もう一度... in> out> abc in> def out> def in> trap! # ここも同じ結果 in> out> def in> ggggtrap! # 途中まで入力した場合 in> out> def # 途中までの結果は捨てられ, その前の結果が出 # る... in> . out> . >|前にもいったように, ハンドラ中でthrow/raiseしたらそれまでの入力を捨て >|てくれる仕様ならば, この問題は解決すると思いますが... > >というか,捨ててるつもりなんですけど…. 以下のプログラムのように, 毎回setbufするようにしたら問題なくなりました. # 当たり前だけど... #include #include // jmp_buf env; sigjmp_buf env; void sig() { printf("trap!!\n"); siglongjmp(env, 1); } foo() { char stdin_buf[1024]; char buf[1024]; char *p; setbuf(stdin, stdin_buf); while (1) { signal(SIGINT, sig); printf("in> "); fflush(stdout); p = buf; for (p = buf; *p = getc(stdin); ++p) { if (*p == '\n') break; } *p = 0; printf("out> %s\n", buf); if (strcmp(buf, ".") == 0) exit(0); } } main() { sigsetjmp(env, 0); //setjmp(env); foo(); } __ ................................石塚 圭樹@日本ラショナルソフトェア... ----------------------------------->> e-mail: keiju@rational.com <<---