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

ruby-changes:38519

From: nobu <ko1@a...>
Date: Fri, 22 May 2015 19:42:23 +0900 (JST)
Subject: [ruby-changes:38519] nobu:r50600 (trunk): process.c: do not discard status

nobu	2015-05-22 19:42:09 +0900 (Fri, 22 May 2015)

  New Revision: 50600

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

  Log:
    process.c: do not discard status
    
    * process.c (rb_spawn_process): do not discard global escape
      status.  [ruby-core:69304] [Bug #11166]
    * process.c (rb_execarg_spawn): extract the start procedure in a
      parent process with ensuring the end procedure.

  Modified files:
    trunk/ChangeLog
    trunk/process.c
    trunk/test/ruby/test_process.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 50599)
+++ ChangeLog	(revision 50600)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri May 22 19:42:06 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* process.c (rb_spawn_process): do not discard global escape
+	  status.  [ruby-core:69304] [Bug #11166]
+
+	* process.c (rb_execarg_spawn): extract the start procedure in a
+	  parent process with ensuring the end procedure.
+
 Fri May 22 16:48:32 2015  SHIBATA Hiroshi  <hsbt@r...>
 
 	* NEWS: added news for net-telnet and rake
Index: process.c
===================================================================
--- process.c	(revision 50599)
+++ process.c	(revision 50600)
@@ -2436,8 +2436,8 @@ rb_execarg_parent_start(VALUE execarg_ob https://github.com/ruby/ruby/blob/trunk/process.c#L2436
     }
 }
 
-void
-rb_execarg_parent_end(VALUE execarg_obj)
+static VALUE
+execarg_parent_end(VALUE execarg_obj)
 {
     struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
     int err = errno;
@@ -2461,6 +2461,13 @@ rb_execarg_parent_end(VALUE execarg_obj) https://github.com/ruby/ruby/blob/trunk/process.c#L2461
     }
 
     errno = err;
+    return execarg_obj;
+}
+
+void
+rb_execarg_parent_end(VALUE execarg_obj)
+{
+    execarg_parent_end(execarg_obj);
     RB_GC_GUARD(execarg_obj);
 }
 
@@ -3845,16 +3852,13 @@ static rb_pid_t https://github.com/ruby/ruby/blob/trunk/process.c#L3852
 rb_spawn_process(struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen)
 {
     rb_pid_t pid;
-#if !USE_SPAWNV
-    int status;
-#endif
 #if !defined HAVE_WORKING_FORK || USE_SPAWNV
     VALUE prog;
     struct rb_execarg sarg;
 #endif
 
 #if defined HAVE_WORKING_FORK && !USE_SPAWNV
-    pid = rb_fork_async_signal_safe(&status, rb_exec_atfork, eargp, eargp->redirect_fds, errmsg, errmsg_buflen);
+    pid = rb_fork_async_signal_safe(NULL, rb_exec_atfork, eargp, eargp->redirect_fds, errmsg, errmsg_buflen);
 #else
     prog = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
 
@@ -3892,20 +3896,42 @@ rb_spawn_process(struct rb_execarg *earg https://github.com/ruby/ruby/blob/trunk/process.c#L3896
     return pid;
 }
 
+struct spawn_args {
+    VALUE execarg;
+    struct {
+	char *ptr;
+	size_t buflen;
+    } errmsg;
+};
+
+static VALUE
+do_spawn_process(VALUE arg)
+{
+    struct spawn_args *argp = (struct spawn_args *)arg;
+    rb_execarg_parent_start1(argp->execarg);
+    return (VALUE)rb_spawn_process(DATA_PTR(argp->execarg),
+				   argp->errmsg.ptr, argp->errmsg.buflen);
+}
+
+static rb_pid_t
+rb_execarg_spawn(VALUE execarg_obj, char *errmsg, size_t errmsg_buflen)
+{
+    struct spawn_args args;
+
+    args.execarg = execarg_obj;
+    args.errmsg.ptr = errmsg;
+    args.errmsg.buflen = errmsg_buflen;
+    return (rb_pid_t)rb_ensure(do_spawn_process, (VALUE)&args,
+			       execarg_parent_end, execarg_obj);
+}
+
 static rb_pid_t
 rb_spawn_internal(int argc, const VALUE *argv, char *errmsg, size_t errmsg_buflen)
 {
     VALUE execarg_obj;
-    struct rb_execarg *eargp;
-    rb_pid_t ret;
 
     execarg_obj = rb_execarg_new(argc, argv, TRUE);
-    eargp = rb_execarg_get(execarg_obj);
-    rb_execarg_parent_start(execarg_obj);
-    ret = rb_spawn_process(eargp, errmsg, errmsg_buflen);
-    rb_execarg_parent_end(execarg_obj);
-    RB_GC_GUARD(execarg_obj);
-    return ret;
+    return rb_execarg_spawn(execarg_obj, errmsg, errmsg_buflen);
 }
 
 rb_pid_t
@@ -4267,12 +4293,9 @@ rb_f_spawn(int argc, VALUE *argv) https://github.com/ruby/ruby/blob/trunk/process.c#L4293
 
     execarg_obj = rb_execarg_new(argc, argv, TRUE);
     eargp = rb_execarg_get(execarg_obj);
-    rb_execarg_parent_start(execarg_obj);
     fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
 
-    pid = rb_spawn_process(eargp, errmsg, sizeof(errmsg));
-    rb_execarg_parent_end(execarg_obj);
-    RB_GC_GUARD(execarg_obj);
+    pid = rb_execarg_spawn(execarg_obj, errmsg, sizeof(errmsg));
 
     if (pid == -1) {
 	const char *prog = errmsg;
Index: test/ruby/test_process.rb
===================================================================
--- test/ruby/test_process.rb	(revision 50599)
+++ test/ruby/test_process.rb	(revision 50600)
@@ -2017,4 +2017,16 @@ EOS https://github.com/ruby/ruby/blob/trunk/test/ruby/test_process.rb#L2017
     status = th.value
     assert status.success?, status.inspect
   end if defined?(fork)
+
+  def test_kill_at_spawn_failure
+    bug11166 = '[ruby-core:69304] [Bug #11166]'
+    th = nil
+    x = with_tmpchdir {|d|
+      prog = "#{d}/notexist"
+      th = Thread.start {system(prog);sleep}
+      th.kill
+      th.join(0.1)
+    }
+    assert_equal(th, x)
+  end if defined?(fork)
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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