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

ruby-changes:8790

From: yugui <ko1@a...>
Date: Sat, 22 Nov 2008 23:53:05 +0900 (JST)
Subject: [ruby-changes:8790] Ruby:r20326 (ruby_1_9_1): merges r20298 from trunk into ruby_1_9_1.

yugui	2008-11-22 23:52:44 +0900 (Sat, 22 Nov 2008)

  New Revision: 20326

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=20326

  Log:
    merges r20298 from trunk into ruby_1_9_1.
    * ext/pty/pty.c (get_device_once): abandon asynchronous exception
      that might cause serious problem if a program terminated early.
      asynchronous exception is a very bad thing anyway.  use
      Process.waitpid(pid) or PTY.check(pid) to poll program
      termination. if PTY.check is called with optional second
      argument being true, it raises an exception same as one from
      previous behavior.  [incompatible] fix: [ruby-core:19583]

  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 20325)
+++ ruby_1_9_1/ChangeLog	(revision 20326)
@@ -1,3 +1,13 @@
+Sat Nov 22 03:41:22 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* ext/pty/pty.c (get_device_once): abandon asynchronous exception
+	  that might cause serious problem if a program terminated early.
+	  asynchronous exception is a very bad thing anyway.  use
+	  Process.waitpid(pid) or PTY.check(pid) to poll program
+	  termination. if PTY.check is called with optional second
+	  argument being true, it raises an exception same as one from
+	  previous behavior.  [incompatible] fix: [ruby-core:19583]
+
 Fri Nov 21 22:17:15 2008  Yukihiro Matsumoto  <matz@r...>
 
 	* ruby.c (usage): -W description updated.  [ruby-core:19858]
Index: ruby_1_9_1/ext/pty/pty.c
===================================================================
--- ruby_1_9_1/ext/pty/pty.c	(revision 20325)
+++ ruby_1_9_1/ext/pty/pty.c	(revision 20326)
@@ -127,51 +127,8 @@
 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 {
@@ -217,7 +174,6 @@
     }
     getDevice(&master, &slave, SlaveName);
 
-    info->thread = rb_thread_current();
     if ((pid = fork()) < 0) {
 	close(master);
 	close(slave);
@@ -288,15 +244,6 @@
     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)
 {
@@ -396,13 +343,19 @@
     }
 }
 
+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);
@@ -426,32 +379,55 @@
     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_finalize_syswait, (VALUE)&thinfo);
+	rb_ensure(rb_yield, res, pty_detach_process, (VALUE)&info);
 	return Qnil;
     }
     return res;
 }
 
-/* ruby function: protect_signal - obsolete */
-static VALUE
-pty_protect(VALUE self)
+static void
+raise_from_check(pid_t pid, int status)
 {
-    rb_warn("PTY::protect_signal is no longer needed");
-    rb_yield(Qnil);
-    return 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);
 }
 
-/* ruby function: reset_signal - obsolete */
 static VALUE
-pty_reset_signal(VALUE self)
+pty_check(int argc, VALUE *argv, VALUE self)
 {
-    rb_warn("PTY::reset_signal is no longer needed");
-    return 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 */
 }
 
 static VALUE cPTY;
@@ -462,8 +438,7 @@
     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_module_function(cPTY,"protect_signal",pty_protect,0);
-    rb_define_module_function(cPTY,"reset_signal",pty_reset_signal,0);
+    rb_define_singleton_function(cPTY,"check",pty_check,-1);
 
     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/

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