From: Koji Arai Date: 2001-04-02T01:59:17+09:00 Subject: [ruby-dev:12719] Process.waitall (Re: [BUG] Process::Status) 新井です。 Process.waitall が ステータス値を返していたので Process::Status を返すようにしました. また、以前、提案したように waktall がブロックを持てるように してみました.(そうしなかった理由がありました?) 5.times {|n| fork { exit n } } p Process.waitall {|pid, status| case when status.signaled? p "child #{pid} was killed by signal #{status.termsig}" when status.stopped? # 実際には Process.wait を使用しているので,ここに来ることはない p "child #{pid} was stopped by signal #{status.stopsig}" when status.exited? p "child #{pid} exited normaly. status=#{status.exitstatus}" when status.coredump? p "child #{pid} dumped core." else p "unknown status %#x" % status.to_i end } => "child 4930 exited normaly. status=4" "child 4929 exited normaly. status=3" "child 4928 exited normaly. status=2" "child 4927 exited normaly. status=1" "child 4926 exited normaly. status=0" [nil, nil, nil, nil, nil] ブロックを伴う場合の waitall の戻り値を各ブロックの戻り値の 配列にしましたが、これは余計だったような気が今はしてます。 In message "[ruby-dev:12715] [BUG] Process::Status" on 01 Apr 2001 18:38:33 +0900, Koji Arai wrote: > 新井です。 > > Process::Status にバグがありました。 このパッチも含みます. Index: process.c =================================================================== RCS file: /src/ruby/process.c,v retrieving revision 1.33 diff -u -p -u -r1.33 process.c --- process.c 2001/03/28 08:43:25 1.33 +++ process.c 2001/04/01 16:54:33 @@ -170,7 +170,7 @@ pst_wifsignaled(st) { int status = NUM2INT(st); - if (WIFSIGNALED(st)) + if (WIFSIGNALED(status)) return Qtrue; else return Qfalse; @@ -418,6 +418,8 @@ proc_waitall() { VALUE pid_status_ary, pid_status_member; int pid, status; + + rb_last_status = Qnil; #ifdef NO_WAITPID struct waitall_data data; @@ -440,13 +442,13 @@ proc_waitall() } rb_sys_fail(0); } - pid_status_member = rb_ary_new2(2); - rb_ary_push(pid_status_member, INT2NUM(pid)); - rb_ary_push(pid_status_member, INT2NUM(status)); - rb_ary_push(pid_status_ary, pid_status_member); + last_status_set(status); + pid_status_member = rb_assoc_new(INT2NUM(pid), rb_last_status); + if (rb_block_given_p()) + rb_ary_push(pid_status_ary, rb_yield(pid_status_member)); + else + rb_ary_push(pid_status_ary, pid_status_member); } - if (RARRAY(pid_status_ary)->len != 0) - last_status_set(status); #else pid_status_ary = rb_ary_new(); for (pid = -1;;) { @@ -456,10 +458,12 @@ proc_waitall() break; rb_sys_fail(0); } - pid_status_member = rb_ary_new2(2); - rb_ary_push(pid_status_member, INT2NUM(pid)); - rb_ary_push(pid_status_member, INT2NUM(status)); - rb_ary_push(pid_status_ary, pid_status_member); + last_status_set(status); + pid_status_member = rb_assoc_new(INT2NUM(pid), rb_last_status); + if (rb_block_given_p()) + rb_ary_push(pid_status_ary, rb_yield(pid_status_member)); + else + rb_ary_push(pid_status_ary, pid_status_member); } #endif return pid_status_ary; -- 新井康司 (Koji Arai)