зеркало из https://github.com/github/ruby.git
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:
Родитель
224172757e
Коммит
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>
|
||||
|
||||
* 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
|
||||
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;
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче