* process.c (proc_waitall): new method based on a patch from Brian

Fundakowski Feldman <green@green.dyndns.org>.

* process.c (last_status_set): objectify $? value (Process::Status).


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1190 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2001-02-15 06:01:00 +00:00
Родитель 756dcb0034
Коммит 011ed67616
6 изменённых файлов: 266 добавлений и 45 удалений

Просмотреть файл

@ -2,6 +2,13 @@ Thu Feb 15 11:33:49 2001 Shugo Maeda <shugo@ruby-lang.org>
* lib/cgi/session.rb (close): fixed reversed condition. * lib/cgi/session.rb (close): fixed reversed condition.
Thu Feb 15 08:34:14 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* process.c (proc_waitall): new method based on a patch from Brian
Fundakowski Feldman <green@green.dyndns.org>.
* process.c (last_status_set): objectify $? value (Process::Status).
Wed Feb 14 17:28:24 2001 Shugo Maeda <shugo@ruby-lang.org> Wed Feb 14 17:28:24 2001 Shugo Maeda <shugo@ruby-lang.org>
* lib/net/imap.rb: supports unknown resp_text_code. * lib/net/imap.rb: supports unknown resp_text_code.

4
dir.c
Просмотреть файл

@ -558,7 +558,7 @@ extract_elem(path)
} }
static void static void
remove_backslases(p) remove_backslashes(p)
char *p; char *p;
{ {
char *pend = p + strlen(p); char *pend = p + strlen(p);
@ -590,7 +590,7 @@ rb_glob_helper(path, flag, func, arg)
char *p, *m; char *p, *m;
if (!has_magic(path, 0)) { if (!has_magic(path, 0)) {
remove_backslases(path); remove_backslashes(path);
if (rb_sys_stat(path, &st) == 0) { if (rb_sys_stat(path, &st) == 0) {
(*func)(path, arg); (*func)(path, arg);
} }

Просмотреть файл

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Thu Mar 31 12:21:29 JST 1994 created at: Thu Mar 31 12:21:29 JST 1994
Copyright (C) 1993-2000 Yukihiro Matsumoto Copyright (C) 1993-2001 Yukihiro Matsumoto
************************************************/ ************************************************/

Просмотреть файл

@ -47,6 +47,8 @@ module Ping
s = TCPsocket.new(host, service) s = TCPsocket.new(host, service)
s.close s.close
end end
rescue Errno::ECONNREFUSED
return true
rescue rescue
return false return false
end end

Просмотреть файл

@ -28,9 +28,6 @@ VALUE rb_cTrueClass;
VALUE rb_cFalseClass; VALUE rb_cFalseClass;
VALUE rb_cSymbol; VALUE rb_cSymbol;
VALUE rb_f_sprintf();
VALUE rb_obj_alloc();
static ID eq, eql; static ID eq, eql;
static ID inspect; static ID inspect;
static ID clone; static ID clone;

293
process.c
Просмотреть файл

@ -65,8 +65,127 @@ get_ppid()
#endif #endif
} }
static VALUE rb_cProcStatus;
VALUE rb_last_status = Qnil; VALUE rb_last_status = Qnil;
static VALUE
last_status_set(status)
int status;
{
rb_last_status = rb_obj_alloc(rb_cProcStatus);
rb_iv_set(rb_last_status, "status", INT2FIX(status));
}
static VALUE
pst_to_i(st)
VALUE st;
{
return rb_iv_get(st, "status");
}
static VALUE
pst_to_s(st)
VALUE st;
{
return rb_fix2str(pst_to_i(st), 10);
}
static VALUE
pst_equal(st1, st2)
VALUE st1, st2;
{
if (st1 == st2) return Qtrue;
return rb_equal(pst_to_i(st1), st2);
}
static VALUE
pst_bitand(st1, st2)
VALUE st1, st2;
{
int status = NUM2INT(st1) & NUM2INT(st2);
return INT2NUM(status);
}
static VALUE
pst_ifstopped(st)
VALUE st;
{
int status = NUM2INT(st);
if (WIFSTOPPED(status))
return Qtrue;
else
return Qfalse;
}
static VALUE
pst_stopsig(st)
VALUE st;
{
int status = NUM2INT(st);
return INT2NUM(WSTOPSIG(status));
}
static VALUE
pst_ifsignaled(st)
VALUE st;
{
int status = NUM2INT(st);
if (WIFSIGNALED(st))
return Qtrue;
else
return Qfalse;
}
static VALUE
pst_termsig(st)
VALUE st;
{
int status = NUM2INT(st);
return INT2NUM(WTERMSIG(status));
}
static VALUE
pst_ifexited(st)
VALUE st;
{
int status = NUM2INT(st);
if (WIFEXITED(status))
return Qtrue;
else
return Qfalse;
}
static VALUE
pst_exitstatus(st)
VALUE st;
{
int status = NUM2INT(st);
return INT2NUM(WEXITSTATUS(status));
}
static VALUE
pst_coredump(st)
VALUE st;
{
#ifdef WCOREDUMP
int status = NUM2INT(st);
if (WCOREDUMP(status))
return Qtrue;
else
return Qfalse;
#else
return Qfalse;
#endif
}
#if !defined(HAVE_WAITPID) && !defined(HAVE_WAIT4) #if !defined(HAVE_WAITPID) && !defined(HAVE_WAIT4)
#define NO_WAITPID #define NO_WAITPID
static st_table *pid_tbl; static st_table *pid_tbl;
@ -108,7 +227,7 @@ rb_waitpid(pid, flags, st)
} }
#else /* NO_WAITPID */ #else /* NO_WAITPID */
if (pid_tbl && st_lookup(pid_tbl, pid, st)) { if (pid_tbl && st_lookup(pid_tbl, pid, st)) {
rb_last_status = INT2FIX(*st); last_status_set(*st);
st_delete(pid_tbl, &pid, NULL); st_delete(pid_tbl, &pid, NULL);
return pid; return pid;
} }
@ -137,7 +256,7 @@ rb_waitpid(pid, flags, st)
if (!rb_thread_alone()) rb_thread_schedule(); if (!rb_thread_alone()) rb_thread_schedule();
} }
#endif #endif
rb_last_status = INT2FIX(*st); last_status_set(*st);
return result; return result;
} }
@ -158,25 +277,49 @@ wait_each(key, value, data)
data->status = value; data->status = value;
return ST_DELETE; 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 #endif
static VALUE static VALUE
proc_wait() proc_wait()
{ {
int pid, state; int pid, status;
#ifdef NO_WAITPID #ifdef NO_WAITPID
struct wait_data data; struct wait_data data;
data.status = -1; data.status = -1;
st_foreach(pid_tbl, wait_each, &data); st_foreach(pid_tbl, wait_each, &data);
if (data.status != -1) { if (data.status != -1) {
rb_last_status = data.status; last_status_set(data.status);
return INT2FIX(data.pid); return INT2FIX(data.pid);
} }
while (1) { while (1) {
TRAP_BEG; TRAP_BEG;
pid = wait(&state); pid = wait(&status);
TRAP_END; TRAP_END;
if (pid >= 0) break; if (pid >= 0) break;
if (errno == EINTR) { if (errno == EINTR) {
@ -185,9 +328,9 @@ proc_wait()
} }
rb_sys_fail(0); rb_sys_fail(0);
} }
rb_last_status = INT2FIX(state); last_status_set(status);
#else #else
if ((pid = rb_waitpid(-1, 0, &state)) < 0) if ((pid = rb_waitpid(-1, 0, &status)) < 0)
rb_sys_fail(0); rb_sys_fail(0);
#endif #endif
return INT2FIX(pid); return INT2FIX(pid);
@ -234,6 +377,58 @@ proc_waitpid2(argc, argv)
return rb_assoc_new(pid, rb_last_status); return rb_assoc_new(pid, rb_last_status);
} }
static VALUE
proc_waitall()
{
VALUE pid_status_ary, pid_status_member;
int pid, status;
#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) {
last_status_set(data.status);
return pid_status_ary;
}
for (pid = -1;;) {
pid = wait(&status);
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(status));
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;;) {
pid = rb_waitpid(-1, 0, &status);
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(status));
rb_ary_push(pid_status_ary, pid_status_member);
}
#endif
return pid_status_ary;
}
#ifndef HAVE_STRING_H #ifndef HAVE_STRING_H
char *strtok(); char *strtok();
#endif #endif
@ -354,24 +549,24 @@ rb_proc_exec(str)
for (s=str; *s; s++) { for (s=str; *s; s++) {
if (*s != ' ' && !ISALPHA(*s) && strchr("*?{}[]<>()~&|\\$;'`\"\n",*s)) { if (*s != ' ' && !ISALPHA(*s) && strchr("*?{}[]<>()~&|\\$;'`\"\n",*s)) {
#if defined(MSDOS) #if defined(MSDOS)
int state; int status;
before_exec(); before_exec();
state = system(str); status = system(str);
after_exec(); after_exec();
if (state != -1) if (status != -1)
exit(state); exit(status);
#else #else
#if defined(__human68k__) || defined(__CYGWIN32__) || defined(__EMX__) #if defined(__human68k__) || defined(__CYGWIN32__) || defined(__EMX__)
char *shell = dln_find_exe("sh", 0); char *shell = dln_find_exe("sh", 0);
int state = -1; int status = -1;
before_exec(); before_exec();
if (shell) if (shell)
execl(shell, "sh", "-c", str, (char *) NULL); execl(shell, "sh", "-c", str, (char *) NULL);
else else
state = system(str); status = system(str);
after_exec(); after_exec();
if (state != -1) if (status != -1)
exit(state); exit(status);
#else #else
before_exec(); before_exec();
execl("/bin/sh", "sh", "-c", str, (char *)NULL); execl("/bin/sh", "sh", "-c", str, (char *)NULL);
@ -404,7 +599,7 @@ proc_spawn_v(argv, prog)
char *prog; char *prog;
{ {
char *extension; char *extension;
int state; int status;
if (prog) { if (prog) {
security(prog); security(prog);
@ -439,9 +634,9 @@ proc_spawn_v(argv, prog)
} }
} }
before_exec(); before_exec();
state = spawnv(P_WAIT, prog, argv); status = spawnv(P_WAIT, prog, argv);
after_exec(); after_exec();
return state; return status;
} }
static int static int
@ -472,7 +667,7 @@ proc_spawn(sv)
char *str; char *str;
char *s, *t; char *s, *t;
char **argv, **a; char **argv, **a;
int state; int status;
Check_SafeStr(sv); Check_SafeStr(sv);
str = s = RSTRING(sv)->ptr; str = s = RSTRING(sv)->ptr;
@ -480,9 +675,9 @@ proc_spawn(sv)
if (*s != ' ' && !ISALPHA(*s) && strchr("*?{}[]<>()~&|\\$;'`\"\n",*s)) { if (*s != ' ' && !ISALPHA(*s) && strchr("*?{}[]<>()~&|\\$;'`\"\n",*s)) {
char *shell = dln_find_exe("sh", 0); char *shell = dln_find_exe("sh", 0);
before_exec(); before_exec();
state = shell?spawnl(P_WAIT,shell,"sh","-c",str,(char*)NULL):system(str); status = shell?spawnl(P_WAIT,shell,"sh","-c",str,(char*)NULL):system(str);
after_exec(); after_exec();
return state; return status;
} }
} }
a = argv = ALLOCA_N(char*, (s - str) / 2 + 2); a = argv = ALLOCA_N(char*, (s - str) / 2 + 2);
@ -623,12 +818,12 @@ rb_f_system(argc, argv)
{ {
#if defined(NT) || defined(__EMX__) #if defined(NT) || defined(__EMX__)
VALUE cmd; VALUE cmd;
int state; int status;
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
if (argc == 0) { if (argc == 0) {
rb_last_status = INT2FIX(0); rb_last_status = Qnil;
rb_raise(rb_eArgError, "wrong # of arguments"); rb_raise(rb_eArgError, "wrong # of arguments");
} }
@ -641,18 +836,18 @@ rb_f_system(argc, argv)
cmd = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" ")); cmd = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
Check_SafeStr(cmd); Check_SafeStr(cmd);
state = do_spawn(RSTRING(cmd)->ptr); status = do_spawn(RSTRING(cmd)->ptr);
rb_last_status = INT2FIX(state); last_status_set(status);
if (state == 0) return Qtrue; if (status == 0) return Qtrue;
return Qfalse; return Qfalse;
#else #else
#ifdef DJGPP #ifdef DJGPP
VALUE cmd; VALUE cmd;
int state; int status;
if (argc == 0) { if (argc == 0) {
rb_last_status = INT2FIX(0); rb_last_status = Qnil;
rb_raise(rb_eArgError, "wrong # of arguments"); rb_raise(rb_eArgError, "wrong # of arguments");
} }
@ -665,22 +860,22 @@ rb_f_system(argc, argv)
cmd = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" ")); cmd = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
Check_SafeStr(cmd); Check_SafeStr(cmd);
state = system(RSTRING(cmd)->ptr); status = system(RSTRING(cmd)->ptr);
rb_last_status = INT2FIX((state & 0xff) << 8); last_status_set((status & 0xff) << 8);
if (state == 0) return Qtrue; if (status == 0) return Qtrue;
return Qfalse; return Qfalse;
#else #else
#if defined(__human68k__) #if defined(__human68k__)
VALUE prog = 0; VALUE prog = 0;
int i; int i;
int state; int status;
fflush(stdin); fflush(stdin);
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
if (argc == 0) { if (argc == 0) {
rb_last_status = INT2FIX(0); rb_last_status = Qnil;
rb_raise(rb_eArgError, "wrong # of arguments"); rb_raise(rb_eArgError, "wrong # of arguments");
} }
@ -693,13 +888,13 @@ rb_f_system(argc, argv)
} }
if (argc == 1 && prog == 0) { if (argc == 1 && prog == 0) {
state = proc_spawn(argv[0]); status = proc_spawn(argv[0]);
} }
else { else {
state = proc_spawn_n(argc, argv, prog); status = proc_spawn_n(argc, argv, prog);
} }
rb_last_status = state == -1 ? INT2FIX(127) : INT2FIX(state); last_status_set(status == -1 ? 127 : status);
return state == 0 ? Qtrue : Qfalse; return status == 0 ? Qtrue : Qfalse;
#else #else
volatile VALUE prog = 0; volatile VALUE prog = 0;
int pid; int pid;
@ -708,7 +903,7 @@ rb_f_system(argc, argv)
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
if (argc == 0) { if (argc == 0) {
rb_last_status = INT2FIX(0); rb_last_status = Qnil;
rb_raise(rb_eArgError, "wrong # of arguments"); rb_raise(rb_eArgError, "wrong # of arguments");
} }
@ -750,7 +945,8 @@ rb_f_system(argc, argv)
rb_syswait(pid); rb_syswait(pid);
} }
if (rb_last_status == INT2FIX(0)) return Qtrue; if (NUM2INT(rb_last_status) == 0)
return Qtrue;
return Qfalse; return Qfalse;
#endif /* __human68k__ */ #endif /* __human68k__ */
#endif /* DJGPP */ #endif /* DJGPP */
@ -1092,9 +1288,28 @@ Init_process()
#ifndef NT #ifndef NT
rb_define_module_function(rb_mProcess, "wait", proc_wait, 0); 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, "wait2", proc_wait2, 0);
rb_define_module_function(rb_mProcess, "waitall", proc_waitall, 0);
rb_define_module_function(rb_mProcess, "waitpid", proc_waitpid, -1); 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, "waitpid2", proc_waitpid2, -1);
rb_cProcStatus = rb_define_class_under(rb_mProcess, "Status", rb_cObject);
rb_undef_method(CLASS_OF(rb_cProcStatus), "new");
rb_define_method(rb_cProcStatus, "==", pst_equal, 1);
rb_define_method(rb_cProcStatus, "&", pst_bitand, 1);
rb_define_method(rb_cProcStatus, "to_i", pst_to_i, 0);
rb_define_method(rb_cProcStatus, "to_int", pst_to_i, 0);
rb_define_method(rb_cProcStatus, "to_s", pst_to_s, 0);
rb_define_method(rb_cProcStatus, "inspect", pst_to_s, 0);
rb_define_method(rb_cProcStatus, "ifstopped?", pst_ifstopped, 0);
rb_define_method(rb_cProcStatus, "stopsig", pst_stopsig, 0);
rb_define_method(rb_cProcStatus, "ifsignaled?", pst_ifsignaled, 0);
rb_define_method(rb_cProcStatus, "termsig", pst_termsig, 0);
rb_define_method(rb_cProcStatus, "ifexited?", pst_ifexited, 0);
rb_define_method(rb_cProcStatus, "exitstatus", pst_exitstatus, 0);
rb_define_method(rb_cProcStatus, "coredump?", pst_coredump, 0);
rb_define_module_function(rb_mProcess, "pid", get_pid, 0); rb_define_module_function(rb_mProcess, "pid", get_pid, 0);
rb_define_module_function(rb_mProcess, "ppid", get_ppid, 0); rb_define_module_function(rb_mProcess, "ppid", get_ppid, 0);
#endif /* ifndef NT */ #endif /* ifndef NT */