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/