* process.c (rb_fork_async_signal_safe): Inline rb_fork_internal.
(rb_fork_ruby): Ditto. (rb_fork_internal): Removed. (chfunc_protect): Removed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47355 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
51f41f6618
commit
a78a9b0d17
@ -1,3 +1,10 @@
|
|||||||
|
Tue Sep 2 22:56:25 2014 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* process.c (rb_fork_async_signal_safe): Inline rb_fork_internal.
|
||||||
|
(rb_fork_ruby): Ditto.
|
||||||
|
(rb_fork_internal): Removed.
|
||||||
|
(chfunc_protect): Removed.
|
||||||
|
|
||||||
Tue Sep 2 22:43:52 2014 Tanaka Akira <akr@fsij.org>
|
Tue Sep 2 22:43:52 2014 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* test/ruby/test_io.rb (test_new_with_block): Set autoclose to avoid
|
* test/ruby/test_io.rb (test_new_with_block): Set autoclose to avoid
|
||||||
|
120
process.c
120
process.c
@ -2819,8 +2819,8 @@ static int
|
|||||||
run_exec_pgroup(const struct rb_execarg *eargp, struct rb_execarg *sargp, char *errmsg, size_t errmsg_buflen)
|
run_exec_pgroup(const struct rb_execarg *eargp, struct rb_execarg *sargp, char *errmsg, size_t errmsg_buflen)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If FD_CLOEXEC is available, rb_fork_internal waits the child's execve.
|
* If FD_CLOEXEC is available, rb_fork_async_signal_safe waits the child's execve.
|
||||||
* So setpgid is done in the child when rb_fork_internal is returned in
|
* So setpgid is done in the child when rb_fork_async_signal_safe is returned in
|
||||||
* the parent.
|
* the parent.
|
||||||
* No race condition, even without setpgid from the parent.
|
* No race condition, even without setpgid from the parent.
|
||||||
* (Is there an environment which has setpgid but no FD_CLOEXEC?)
|
* (Is there an environment which has setpgid but no FD_CLOEXEC?)
|
||||||
@ -3154,21 +3154,6 @@ pipe_nocrash(int filedes[2], VALUE fds)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct chfunc_protect_t {
|
|
||||||
int (*chfunc)(void*, char *, size_t);
|
|
||||||
void *arg;
|
|
||||||
char *errmsg;
|
|
||||||
size_t buflen;
|
|
||||||
};
|
|
||||||
|
|
||||||
static VALUE
|
|
||||||
chfunc_protect(VALUE arg)
|
|
||||||
{
|
|
||||||
struct chfunc_protect_t *p = (struct chfunc_protect_t *)arg;
|
|
||||||
|
|
||||||
return (VALUE)(*p->chfunc)(p->arg, p->errmsg, p->buflen);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
@ -3345,9 +3330,8 @@ recv_child_error(int fd, int *statep, VALUE *excp, int *errp, char *errmsg, size
|
|||||||
return size != 0;
|
return size != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rb_pid_t
|
rb_pid_t
|
||||||
rb_fork_internal(int *status, int (*chfunc)(void*, char *, size_t), void *charg,
|
rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds,
|
||||||
int chfunc_is_async_signal_safe, VALUE fds,
|
|
||||||
char *errmsg, size_t errmsg_buflen)
|
char *errmsg, size_t errmsg_buflen)
|
||||||
{
|
{
|
||||||
rb_pid_t pid;
|
rb_pid_t pid;
|
||||||
@ -3355,75 +3339,59 @@ rb_fork_internal(int *status, int (*chfunc)(void*, char *, size_t), void *charg,
|
|||||||
int ep[2];
|
int ep[2];
|
||||||
VALUE exc = Qnil;
|
VALUE exc = Qnil;
|
||||||
int error_occurred;
|
int error_occurred;
|
||||||
|
int chfunc_is_async_signal_safe = TRUE;
|
||||||
|
|
||||||
if (status) *status = 0;
|
if (status) *status = 0;
|
||||||
|
|
||||||
if (!chfunc) {
|
if (pipe_nocrash(ep, fds)) return -1;
|
||||||
pid = retry_fork(status, NULL, FALSE);
|
pid = retry_fork(status, ep, chfunc_is_async_signal_safe);
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
return pid;
|
|
||||||
if (!pid) {
|
|
||||||
forked_child = 1;
|
|
||||||
after_fork();
|
|
||||||
}
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
if (!pid) {
|
||||||
else {
|
int ret;
|
||||||
if (pipe_nocrash(ep, fds)) return -1;
|
forked_child = 1;
|
||||||
pid = retry_fork(status, ep, chfunc_is_async_signal_safe);
|
close(ep[0]);
|
||||||
if (pid < 0)
|
ret = chfunc(charg, errmsg, errmsg_buflen);
|
||||||
return pid;
|
if (!ret) _exit(EXIT_SUCCESS);
|
||||||
if (!pid) {
|
send_child_error(ep[1], state, errmsg, errmsg_buflen, chfunc_is_async_signal_safe);
|
||||||
int ret;
|
|
||||||
forked_child = 1;
|
|
||||||
close(ep[0]);
|
|
||||||
if (chfunc_is_async_signal_safe)
|
|
||||||
ret = chfunc(charg, errmsg, errmsg_buflen);
|
|
||||||
else {
|
|
||||||
struct chfunc_protect_t arg;
|
|
||||||
arg.chfunc = chfunc;
|
|
||||||
arg.arg = charg;
|
|
||||||
arg.errmsg = errmsg;
|
|
||||||
arg.buflen = errmsg_buflen;
|
|
||||||
ret = (int)rb_protect(chfunc_protect, (VALUE)&arg, &state);
|
|
||||||
}
|
|
||||||
if (!ret) _exit(EXIT_SUCCESS);
|
|
||||||
send_child_error(ep[1], state, errmsg, errmsg_buflen, chfunc_is_async_signal_safe);
|
|
||||||
#if EXIT_SUCCESS == 127
|
#if EXIT_SUCCESS == 127
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
#else
|
#else
|
||||||
_exit(127);
|
_exit(127);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
close(ep[1]);
|
|
||||||
error_occurred = recv_child_error(ep[0], &state, &exc, &err, errmsg, errmsg_buflen, chfunc_is_async_signal_safe);
|
|
||||||
if (state || error_occurred) {
|
|
||||||
if (status) {
|
|
||||||
rb_protect(proc_syswait, (VALUE)pid, status);
|
|
||||||
if (state) *status = state;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rb_syswait(pid);
|
|
||||||
if (state) rb_exc_raise(exc);
|
|
||||||
}
|
|
||||||
errno = err;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return pid;
|
|
||||||
}
|
}
|
||||||
}
|
close(ep[1]);
|
||||||
|
error_occurred = recv_child_error(ep[0], &state, &exc, &err, errmsg, errmsg_buflen, chfunc_is_async_signal_safe);
|
||||||
rb_pid_t
|
if (state || error_occurred) {
|
||||||
rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds,
|
if (status) {
|
||||||
char *errmsg, size_t errmsg_buflen)
|
rb_protect(proc_syswait, (VALUE)pid, status);
|
||||||
{
|
if (state) *status = state;
|
||||||
return rb_fork_internal(status, chfunc, charg, TRUE, fds, errmsg, errmsg_buflen);
|
}
|
||||||
|
else {
|
||||||
|
rb_syswait(pid);
|
||||||
|
if (state) rb_exc_raise(exc);
|
||||||
|
}
|
||||||
|
errno = err;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_pid_t
|
rb_pid_t
|
||||||
rb_fork_ruby(int *status)
|
rb_fork_ruby(int *status)
|
||||||
{
|
{
|
||||||
return rb_fork_internal(status, NULL, NULL, FALSE, Qnil, NULL, 0);
|
rb_pid_t pid;
|
||||||
|
|
||||||
|
if (status) *status = 0;
|
||||||
|
|
||||||
|
pid = retry_fork(status, NULL, FALSE);
|
||||||
|
if (pid < 0)
|
||||||
|
return pid;
|
||||||
|
if (!pid) {
|
||||||
|
forked_child = 1;
|
||||||
|
after_fork();
|
||||||
|
}
|
||||||
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user