From: OHARA Shigeki Date: 2003-12-10T14:09:11+09:00 Subject: [ruby-list:38886] pty problem 大原です。 ruby 1.6.8 (2002-12-24) [i386-freebsd4.6.2] を利用しているのですが、 Expect モジュールから slogin コマンドを使おうとすると、 RuntimeError で例外が上がる現象に遭遇するようになってしまいました。 # 再現する小さなコードはちょっと面倒で作れませんでした。 具体的には、"Child_changed:" という message で RuntimeError が上がっていて、 spawn した直後に slogin コマンドが死んでいるようでしたので、 当該エラーの箇所で、 rb_raise(rb_eRuntimeError, "Child_changed: %d, sig=%d, exit=%d", cpid, WTERMSIG(statusp), WEXITSTATUS(statusp)); のように signal の種類を出力するようにして試してみたところ、 26 (SIGVTALRM) が飛んでいることがわかりました。 これが setitimer(2) によって飛ばされると仮定して、 slogin には setitimer は無く、 execve(2) は親の setitimer の値を継承するということなので、 Ruby の側に原因があると考え、Ruby の pty.c で、 execvp の直前で timer を clear するよう以下のような修正をしたところ、 RuntimeError が上がる現象がおさまるようになりました。 diff -ur ruby-1.6.7/ext/pty/pty.c ruby-1.6.7.pty/ext/pty/pty.c --- ruby-1.6.7/ext/pty/pty.c Sun Jan 27 02:15:53 2002 +++ ruby-1.6.7.pty/ext/pty/pty.c Tue Jul 2 17:18:25 2002 @@ -297,7 +297,18 @@ argc++; } argv[argc] = NULL; - execvp(argv[0],argv); + { +/* XXX */ +#if defined(HAVE_SETITIMER) +#include + struct itimerval tval; + tval.it_interval.tv_sec = 0; + tval.it_interval.tv_usec = 0; + tval.it_value = tval.it_interval; + setitimer(ITIMER_VIRTUAL, &tval, NULL); +#endif /* HAVE_SETITIMER */ + execvp(argv[0],argv); + } sleep(1); _exit(1); } ---- OHARA Shigeki (大原 重樹)