ruby-changes:8797
From: yugui <ko1@a...>
Date: Sun, 23 Nov 2008 13:44:28 +0900 (JST)
Subject: [ruby-changes:8797] Ruby:r20333 (ruby_1_9_1): * ext/pty/pty.c: reverts 20326. .
yugui 2008-11-23 13:44:12 +0900 (Sun, 23 Nov 2008) New Revision: 20333 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=20333 Log: * ext/pty/pty.c: reverts 20326. [ruby-dev:37146]. Modified files: branches/ruby_1_9_1/ChangeLog branches/ruby_1_9_1/ext/pty/pty.c Index: ruby_1_9_1/ChangeLog =================================================================== --- ruby_1_9_1/ChangeLog (revision 20332) +++ ruby_1_9_1/ChangeLog (revision 20333) @@ -1,3 +1,7 @@ +Sun Nov 23 13:39:49 2008 Yuki Sonoda (Yugui) <yugui@y...> + + * ext/pty/pty.c: reverts 20326. [ruby-dev:37146]. + Sat Nov 22 23:59:06 2008 Yuki Sonoda (Yugui) <yugui@y...> * lib/time.rb: reverts r20305. [ruby-dev:37144]. Index: ruby_1_9_1/ext/pty/pty.c =================================================================== --- ruby_1_9_1/ext/pty/pty.c (revision 20332) +++ ruby_1_9_1/ext/pty/pty.c (revision 20333) @@ -127,8 +127,51 @@ struct pty_info { int fd; rb_pid_t child_pid; + VALUE thread; }; +static void +raise_from_wait(const char *state, const struct pty_info *info) +{ + char buf[1024]; + VALUE exc; + + snprintf(buf, sizeof(buf), "pty - %s: %ld", state, (long)info->child_pid); + exc = rb_exc_new2(eChildExited, buf); + rb_iv_set(exc, "status", rb_last_status_get()); + rb_funcall(info->thread, rb_intern("raise"), 1, exc); +} + +static VALUE +pty_syswait(void *arg) +{ + const struct pty_info *const info = arg; + rb_pid_t cpid; + int status; + + for (;;) { + cpid = rb_waitpid(info->child_pid, &status, WUNTRACED); + if (cpid == -1) return Qnil; + +#if defined(WIFSTOPPED) +#elif defined(IF_STOPPED) +#define WIFSTOPPED(status) IF_STOPPED(status) +#else +---->> Either IF_STOPPED or WIFSTOPPED is needed <<---- +#endif /* WIFSTOPPED | IF_STOPPED */ + if (WIFSTOPPED(status)) { /* suspend */ + raise_from_wait("stopped", info); + } + else if (kill(info->child_pid, 0) == 0) { + raise_from_wait("changed", info); + } + else { + raise_from_wait("exited", info); + return Qnil; + } + } +} + static void getDevice(int*, int*, char [DEVICELEN]); struct exec_info { @@ -174,6 +217,7 @@ } getDevice(&master, &slave, SlaveName); + info->thread = rb_thread_current(); if ((pid = fork()) < 0) { close(master); close(slave); @@ -244,6 +288,15 @@ info->fd = master; } +static VALUE +pty_finalize_syswait(struct pty_info *info) +{ + rb_thread_kill(info->thread); + rb_funcall(info->thread, rb_intern("value"), 0); + rb_detach_process(info->child_pid); + return Qnil; +} + static int get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail) { @@ -343,19 +396,13 @@ } } -static VALUE -pty_detach_process(struct pty_info *info) -{ - rb_detach_process(info->child_pid); - return Qnil; -} - /* ruby function: getpty */ static VALUE pty_getpty(int argc, VALUE *argv, VALUE self) { VALUE res; struct pty_info info; + struct pty_info thinfo; rb_io_t *wfptr,*rfptr; VALUE rport = rb_obj_alloc(rb_cFile); VALUE wport = rb_obj_alloc(rb_cFile); @@ -379,55 +426,32 @@ rb_ary_store(res,1,(VALUE)wport); rb_ary_store(res,2,PIDT2NUM(info.child_pid)); + thinfo.thread = rb_thread_create(pty_syswait, (void*)&info); + thinfo.child_pid = info.child_pid; + rb_thread_schedule(); + if (rb_block_given_p()) { - rb_ensure(rb_yield, res, pty_detach_process, (VALUE)&info); + rb_ensure(rb_yield, res, pty_finalize_syswait, (VALUE)&thinfo); return Qnil; } return res; } -static void -raise_from_check(pid_t pid, int status) +/* ruby function: protect_signal - obsolete */ +static VALUE +pty_protect(VALUE self) { - const char *state; - char buf[1024]; - VALUE exc; - -#if defined(WIFSTOPPED) -#elif defined(IF_STOPPED) -#define WIFSTOPPED(status) IF_STOPPED(status) -#else ----->> Either IF_STOPPED or WIFSTOPPED is needed <<---- -#endif /* WIFSTOPPED | IF_STOPPED */ - if (WIFSTOPPED(status)) { /* suspend */ - state = "stopped"; - } - else if (kill(pid, 0) == 0) { - state = "changed"; - } - else { - state = "exited"; - } - snprintf(buf, sizeof(buf), "pty - %s: %ld", state, (long)pid); - exc = rb_exc_new2(eChildExited, buf); - rb_iv_set(exc, "status", rb_last_status_get()); - rb_exc_raise(exc); + rb_warn("PTY::protect_signal is no longer needed"); + rb_yield(Qnil); + return self; } +/* ruby function: reset_signal - obsolete */ static VALUE -pty_check(int argc, VALUE *argv, VALUE self) +pty_reset_signal(VALUE self) { - VALUE pid, exc; - pid_t cpid; - int status; - - rb_scan_args(argc, argv, "11", &pid, &exc); - cpid = rb_waitpid(NUM2PIDT(pid), &status, WUNTRACED); - if (cpid == -1) return Qnil; - - if (!RTEST(exc)) return status; - raise_from_check(pid, status); - return Qnil; /* not reached */ + rb_warn("PTY::reset_signal is no longer needed"); + return self; } static VALUE cPTY; @@ -438,7 +462,8 @@ cPTY = rb_define_module("PTY"); rb_define_module_function(cPTY,"getpty",pty_getpty,-1); rb_define_module_function(cPTY,"spawn",pty_getpty,-1); - rb_define_singleton_function(cPTY,"check",pty_check,-1); + rb_define_module_function(cPTY,"protect_signal",pty_protect,0); + rb_define_module_function(cPTY,"reset_signal",pty_reset_signal,0); eChildExited = rb_define_class_under(cPTY,"ChildExited",rb_eRuntimeError); rb_define_method(eChildExited,"status",echild_status,0); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/