From: "Brian F. Feldman" Date: 2000-10-22T01:39:03+09:00 Subject: [ruby-talk:5739] Process additions I still have some process additions that I'd like to see in the standard Ruby process.c (if only because it feels that they should be standard). They include the wait-flags, Process.waitall, and now Process.gids/ Process.groups, useful because on many platforms there will be multiple groups that a user may belong to. I believe the work I have done will enable these extensions to work on other systems (that is, e.g., ones without getgroups()). Let me know what you all think. I also made a change for consistency to file.c, to set the NGROUPS according to NGROUPS_MAX if possible. Thanks for your time! --- file.c.orig Fri Oct 20 20:21:21 2000 +++ file.c Fri Oct 20 20:22:11 2000 @@ -390,7 +390,9 @@ return Qtrue; # ifdef HAVE_GETGROUPS -# ifndef NGROUPS +# ifdef NGROUPS_MAX +# define NGROUPS NGROUPS_MAX +# else # define NGROUPS 32 # endif { --- process.c.orig Tue Oct 17 14:13:58 2000 +++ process.c Fri Oct 20 20:32:00 2000 @@ -158,6 +158,30 @@ data->status = value; return ST_DELETE; } + +struct waitall_data { + int pid; + int status; + VALUE ary; +} + +static int +waitall_each(key, value, data) + int key, value; + struct wait_data *data; +{ + VALUE pid_status_member; + + if (data->status != -1) return ST_STOP; + + data->pid = key; + data->status = value; + pid_status_member = rb_ary_new2(2); + rb_ary_push(pid_status_member, INT2NUM(key)); + rb_ary_push(pid_status_member, INT2NUM(value)); + rb_ary_push(data->ary, pid_status_member); + return ST_DELETE; +} #endif static VALUE @@ -230,6 +254,135 @@ return rb_assoc_new(pid, rb_last_status); } +static VALUE +rb_f_waitall() +{ + VALUE pid_status_ary, pid_status_member; + int pid, state; +#ifdef NO_WAITPID + struct waitall_data data; + + data.ary = pid_status_ary = rb_ary_new(); + data.status = -1; + st_foreach(pid_tbl, waitall_each, &data); + if (data.status != -1) { + rb_last_status = data.status; + return pid_status_ary; + } + + for (pid = -1;;) { + pid = wait(&state); + if (pid == -1) { + if (errno == ECHILD) + break; + if (errno == EINTR) { + rb_thread_schedule(); + continue; + } + 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(state)); + rb_ary_push(pid_status_ary, pid_status_member); + } + if (RARRAY(pid_status_ary)->len != 0) + rb_last_status = INT2FIX(state); +#else + pid_status_ary = rb_ary_new(); + for (pid = -1;;) { + pid = rb_waitpid(-1, 0, &state); + if (pid == -1) { + if (errno == ECHILD) + 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(state)); + rb_ary_push(pid_status_ary, pid_status_member); + } +#endif + return pid_status_ary; +} + +static VALUE +rb_f_wifstopped(obj, statusnum) + VALUE obj, statusnum; +{ + int status = NUM2INT(statusnum); + + if (WIFSTOPPED(status)) + return Qtrue; + else + return Qfalse; +} + +static VALUE +rb_f_wstopsig(obj, statusnum) + VALUE obj, statusnum; +{ + int status = NUM2INT(statusnum); + + return INT2NUM(WSTOPSIG(status)); +} + +static VALUE +rb_f_wifsignaled(obj, statusnum) + VALUE obj, statusnum; +{ + int status = NUM2INT(statusnum); + + if (WIFSIGNALED(status)) + return Qtrue; + else + return Qfalse; +} + +static VALUE +rb_f_wtermsig(obj, statusnum) + VALUE obj, statusnum; +{ + int status = NUM2INT(statusnum); + + return INT2NUM(WTERMSIG(status)); +} + +static VALUE +rb_f_wifexited(obj, statusnum) + VALUE obj, statusnum; +{ + int status = NUM2INT(statusnum); + + if (WIFEXITED(status)) + return Qtrue; + else + return Qfalse; +} + +static VALUE +rb_f_wexitstatus(obj, statusnum) + VALUE obj, statusnum; +{ + int status = NUM2INT(statusnum); + + return INT2NUM(WEXITSTATUS(status)); +} + +#ifdef WCOREDUMP +static VALUE +rb_f_wcoredump(obj, statusnum) + VALUE obj, statusnum; +{ + int status = NUM2INT(statusnum); + + if (WCOREDUMP(status)) + return Qtrue; + else + return Qfalse; +} +#endif + char *strtok(); #ifdef HAVE_SETITIMER @@ -993,6 +1146,33 @@ } static VALUE +proc_getgroups(obj) + VALUE obj; +{ +# ifdef HAVE_GETGROUPS +# ifdef NGROUPS_MAX +# define NGROUPS NGROUPS_MAX +# else +# define NGROUPS 32 +# endif + GETGROUPS_T gary[NGROUPS]; + VALUE groups; + int anum, i; + + anum = getgroups(NGROUPS, gary); + if (anum == -1) + rb_sys_fail(0); + groups = rb_ary_new2(anum); + for (i = 0; i < anum; i++) + rb_ary_push(groups, INT2NUM(gary[i])); + + return groups; +# else + return rb_ary_new3(1, proc_getgid()); +# endif +} + +static VALUE proc_geteuid(obj) VALUE obj; { @@ -1083,8 +1263,18 @@ #ifndef NT rb_define_module_function(rb_mProcess, "wait", proc_wait, 0); rb_define_module_function(rb_mProcess, "wait2", proc_wait2, 0); + rb_define_module_function(rb_mProcess, "waitall", rb_f_waitall, 0); rb_define_module_function(rb_mProcess, "waitpid", proc_waitpid, -1); rb_define_module_function(rb_mProcess, "waitpid2", proc_waitpid2, -1); + rb_define_module_function(rb_mProcess, "wifstopped", rb_f_wifstopped, 1); + rb_define_module_function(rb_mProcess, "wstopsig", rb_f_wstopsig, 1); + rb_define_module_function(rb_mProcess, "wifsignaled", rb_f_wifsignaled, 1); + rb_define_module_function(rb_mProcess, "wtermsig", rb_f_wtermsig, 1); + rb_define_module_function(rb_mProcess, "wifexited", rb_f_wifexited, 1); + rb_define_module_function(rb_mProcess, "wexitstatus", rb_f_wexitstatus, 1); +#ifdef WCOREDUMP + rb_define_module_function(rb_mProcess, "wcoredump", rb_f_wcoredump, 1); +#endif rb_define_module_function(rb_mProcess, "pid", get_pid, 0); rb_define_module_function(rb_mProcess, "ppid", get_ppid, 0); @@ -1114,4 +1304,6 @@ rb_define_module_function(rb_mProcess, "euid=", proc_seteuid, 1); rb_define_module_function(rb_mProcess, "egid", proc_getegid, 0); rb_define_module_function(rb_mProcess, "egid=", proc_setegid, 1); + rb_define_module_function(rb_mProcess, "gids", proc_getgroups, 0); + rb_define_module_function(rb_mProcess, "groups", proc_getgroups, 0); } -- Brian Fundakowski Feldman \ FreeBSD: The Power to Serve! / green@FreeBSD.org `------------------------------'