diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-05-22 10:42:09 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-05-22 10:42:09 +0000 |
commit | 46c64caff68dd536eeeaa1c945eb66b886a0721d (patch) | |
tree | c247176796312d6ad96189884c555bdbacef224d | |
parent | 224172757ea4e9fb8f1d406b8e056d564cb9b517 (diff) | |
download | ruby-46c64caff68dd536eeeaa1c945eb66b886a0721d.tar.gz |
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.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50600 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | process.c | 59 | ||||
-rw-r--r-- | test/ruby/test_process.rb | 12 |
3 files changed, 61 insertions, 18 deletions
@@ -1,3 +1,11 @@ +Fri May 22 19:42:06 2015 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * 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@ruby-lang.org> * NEWS: added news for net-telnet and rake @@ -2436,8 +2436,8 @@ rb_execarg_parent_start(VALUE execarg_obj) } } -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) } 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 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 *eargp, char *errmsg, size_t errmsg_buflen) 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) 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; diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index ac5091b278..a43dcf475c 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -2017,4 +2017,16 @@ EOS 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 |