なかだです。

At Wed, 10 Dec 2003 15:00:54 +0900,
U.Nakamura wrote:
> ごとうゆうぞうさんが直し方を発見して、それにわたなべひろふみさんが
> 手を加えたものを、私が代理で先ほどcommitしておきました。
> # ややこしい
> 
> たぶん直ってると思いますが、よかったら確認してみてください。

これは条件が変わってコンパイルされる部分が変わったわけですが、
元の部分(!defined(TIOCSCTTY)のとき)を使う環境では解決していない
ような気がします。一度slaveをclose()してしまうのがまずいのでは
なかろうか、という推測でこういうパッチを作ってみましたが、実際
そういう環境は持ってないのでよく分かりません。

あと、できればPTY::ChildExited#initializeも。


Index: ext/pty/pty.c =================================================================== RCS file: /cvs/ruby/src/ruby/ext/pty/pty.c,v retrieving revision 1.19 diff -u -2 -p -d -r1.19 pty.c --- ext/pty/pty.c 11 Dec 2003 02:39:59 -0000 1.19 +++ ext/pty/pty.c 12 Dec 2003 09:00:21 -0000 @@ -119,4 +119,20 @@ extern int errno; static VALUE eChildExited; +extern VALUE rb_last_status; + +static VALUE +echild_initialize(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + VALUE mesg, status; + if (rb_scan_args(argc, argv, "11", &mesg, &status) < 2) { + status = rb_last_status; + } + rb_call_super(1, &mesg); + rb_iv_set(self, "status", status); + return self; +} static VALUE @@ -133,19 +149,4 @@ struct pty_info { }; -static void -raise_from_wait(state, info) - struct pty_info *info; - char *state; -{ - extern VALUE rb_last_status; - char buf[1024]; - VALUE exc; - - snprintf(buf, sizeof(buf), "pty - %s: %d", state, info->child_pid); - exc = rb_exc_new2(eChildExited, buf); - rb_iv_set(exc, "status", rb_last_status); - rb_funcall(info->thread, rb_intern("raise"), 1, exc); -} - static VALUE pty_syswait(info) @@ -153,4 +154,6 @@ pty_syswait(info) { int cpid, status; + char buf[40], *state; + VALUE exc, args[2]; for (;;) { @@ -159,21 +162,22 @@ pty_syswait(info) #if defined(IF_STOPPED) - if (IF_STOPPED(status)) { /* suspend */ - raise_from_wait("stopped", info); - } -#elif defined(WIFSTOPPED) - if (WIFSTOPPED(status)) { /* suspend */ - raise_from_wait("stopped", info); - } -#else +#define WIFSTOPPED(status) IF_STOPPED(status) +#elif !defined(WIFSTOPPED) ---->> Either IF_STOPPED or WIFSTOPPED is needed <<---- #endif /* WIFSTOPPED | IF_STOPPED */ + if (WIFSTOPPED(status)) { /* suspend */ + state = "stopped"; + } else if (kill(info->child_pid, 0) == 0) { - raise_from_wait("changed", info); + state = "changed"; } else { - raise_from_wait("exited", info); - return Qnil; + state = "exited"; } + snprintf(buf, sizeof(buf), "pty - %s: %d", state, info->child_pid); + args[0] = rb_str_new2(buf); + args[1] = rb_last_status; + exc = rb_class_new_instance(2, args, eChildExited); + rb_funcall(info->thread, rb_intern("raise"), 1, exc); } } @@ -268,5 +272,5 @@ establishShell(argc, argv, info) /* errors ignored for sun */ #else - close(slave); + i = slave; slave = open(SlaveName, O_RDWR); if (slave < 0) { @@ -274,4 +278,5 @@ establishShell(argc, argv, info) _exit(1); } + close(i); close(master); #endif
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦