[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]