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
This commit is contained in:
parent
224172757e
commit
46c64caff6
@ -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>
|
Fri May 22 16:48:32 2015 SHIBATA Hiroshi <hsbt@ruby-lang.org>
|
||||||
|
|
||||||
* NEWS: added news for net-telnet and rake
|
* NEWS: added news for net-telnet and rake
|
||||||
|
59
process.c
59
process.c
@ -2436,8 +2436,8 @@ rb_execarg_parent_start(VALUE execarg_obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static VALUE
|
||||||
rb_execarg_parent_end(VALUE execarg_obj)
|
execarg_parent_end(VALUE execarg_obj)
|
||||||
{
|
{
|
||||||
struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
|
struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
|
||||||
int err = errno;
|
int err = errno;
|
||||||
@ -2461,6 +2461,13 @@ rb_execarg_parent_end(VALUE execarg_obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
errno = err;
|
errno = err;
|
||||||
|
return execarg_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_execarg_parent_end(VALUE execarg_obj)
|
||||||
|
{
|
||||||
|
execarg_parent_end(execarg_obj);
|
||||||
RB_GC_GUARD(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_spawn_process(struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen)
|
||||||
{
|
{
|
||||||
rb_pid_t pid;
|
rb_pid_t pid;
|
||||||
#if !USE_SPAWNV
|
|
||||||
int status;
|
|
||||||
#endif
|
|
||||||
#if !defined HAVE_WORKING_FORK || USE_SPAWNV
|
#if !defined HAVE_WORKING_FORK || USE_SPAWNV
|
||||||
VALUE prog;
|
VALUE prog;
|
||||||
struct rb_execarg sarg;
|
struct rb_execarg sarg;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined HAVE_WORKING_FORK && !USE_SPAWNV
|
#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
|
#else
|
||||||
prog = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
|
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;
|
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
|
static rb_pid_t
|
||||||
rb_spawn_internal(int argc, const VALUE *argv, char *errmsg, size_t errmsg_buflen)
|
rb_spawn_internal(int argc, const VALUE *argv, char *errmsg, size_t errmsg_buflen)
|
||||||
{
|
{
|
||||||
VALUE execarg_obj;
|
VALUE execarg_obj;
|
||||||
struct rb_execarg *eargp;
|
|
||||||
rb_pid_t ret;
|
|
||||||
|
|
||||||
execarg_obj = rb_execarg_new(argc, argv, TRUE);
|
execarg_obj = rb_execarg_new(argc, argv, TRUE);
|
||||||
eargp = rb_execarg_get(execarg_obj);
|
return rb_execarg_spawn(execarg_obj, errmsg, errmsg_buflen);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_pid_t
|
rb_pid_t
|
||||||
@ -4267,12 +4293,9 @@ rb_f_spawn(int argc, VALUE *argv)
|
|||||||
|
|
||||||
execarg_obj = rb_execarg_new(argc, argv, TRUE);
|
execarg_obj = rb_execarg_new(argc, argv, TRUE);
|
||||||
eargp = rb_execarg_get(execarg_obj);
|
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;
|
fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
|
||||||
|
|
||||||
pid = rb_spawn_process(eargp, errmsg, sizeof(errmsg));
|
pid = rb_execarg_spawn(execarg_obj, errmsg, sizeof(errmsg));
|
||||||
rb_execarg_parent_end(execarg_obj);
|
|
||||||
RB_GC_GUARD(execarg_obj);
|
|
||||||
|
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
const char *prog = errmsg;
|
const char *prog = errmsg;
|
||||||
|
@ -2017,4 +2017,16 @@ EOS
|
|||||||
status = th.value
|
status = th.value
|
||||||
assert status.success?, status.inspect
|
assert status.success?, status.inspect
|
||||||
end if defined?(fork)
|
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
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user