/* * call-seq: * Process.waitall => [ [pid1,status1], ...] * * Waits for all children, returning an array of * _pid_/_status_ pairs (where _status_ is a * <code>Process::Status</code> object). * * fork { sleep 0.2; exit 2 } #=> 27432 * fork { sleep 0.1; exit 1 } #=> 27433 * fork { exit 0 } #=> 27434 * p Process.waitall * * <em>produces</em>: * * [[27434, #<Process::Status: pid=27434,exited(0)>], * [27433, #<Process::Status: pid=27433,exited(1)>], * [27432, #<Process::Status: pid=27432,exited(2)>]] */ static VALUE proc_waitall() { VALUE result; int pid, status; rb_secure(2); result = rb_ary_new(); #ifdef NO_WAITPID if (pid_tbl) { st_foreach(pid_tbl, waitall_each, result); } for (pid = -1;;) { pid = wait(&status); if (pid == -1) { if (errno == ECHILD) break; if (errno == EINTR) { rb_thread_schedule(); continue; } rb_sys_fail(0); } last_status_set(status, pid); rb_ary_push(result, rb_assoc_new(INT2NUM(pid), rb_last_status)); } #else rb_last_status = Qnil; for (pid = -1;;) { pid = rb_waitpid(-1, &status, 0); if (pid == -1) { if (errno == ECHILD) break; rb_sys_fail(0); } rb_ary_push(result, rb_assoc_new(INT2NUM(pid), rb_last_status)); } #endif return result; }