summaryrefslogtreecommitdiff
path: root/process.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-09-02 13:56:35 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-09-02 13:56:35 +0000
commita78a9b0d17a98c3571b82f3fa1cf31d250a9dea0 (patch)
tree1bb0070c1e309e518ba9f670890fda4b95b104ec /process.c
parent51f41f66181932aa0a42be2a430a04813c0d6abf (diff)
* 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
Diffstat (limited to 'process.c')
-rw-r--r--process.c116
1 files changed, 42 insertions, 74 deletions
diff --git a/process.c b/process.c
index f2bf7c13af..dc4f17d537 100644
--- a/process.c
+++ b/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)
{
/*
- * If FD_CLOEXEC is available, rb_fork_internal waits the child's execve.
- * So setpgid is done in the child when rb_fork_internal is returned in
+ * 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_async_signal_safe is returned in
* the parent.
* No race condition, even without setpgid from the parent.
* (Is there an environment which has setpgid but no FD_CLOEXEC?)
@@ -3154,21 +3154,6 @@ pipe_nocrash(int filedes[2], VALUE fds)
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
#define O_BINARY 0
#endif
@@ -3345,9 +3330,8 @@ recv_child_error(int fd, int *statep, VALUE *excp, int *errp, char *errmsg, size
return size != 0;
}
-static rb_pid_t
-rb_fork_internal(int *status, int (*chfunc)(void*, char *, size_t), void *charg,
- int chfunc_is_async_signal_safe, VALUE fds,
+rb_pid_t
+rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds,
char *errmsg, size_t errmsg_buflen)
{
rb_pid_t pid;
@@ -3355,75 +3339,59 @@ rb_fork_internal(int *status, int (*chfunc)(void*, char *, size_t), void *charg,
int ep[2];
VALUE exc = Qnil;
int error_occurred;
+ int chfunc_is_async_signal_safe = TRUE;
if (status) *status = 0;
- if (!chfunc) {
- pid = retry_fork(status, NULL, FALSE);
- if (pid < 0)
- return pid;
- if (!pid) {
- forked_child = 1;
- after_fork();
- }
+ if (pipe_nocrash(ep, fds)) return -1;
+ pid = retry_fork(status, ep, chfunc_is_async_signal_safe);
+ if (pid < 0)
return pid;
- }
- else {
- if (pipe_nocrash(ep, fds)) return -1;
- pid = retry_fork(status, ep, chfunc_is_async_signal_safe);
- if (pid < 0)
- return pid;
- if (!pid) {
- 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 (!pid) {
+ int ret;
+ forked_child = 1;
+ close(ep[0]);
+ ret = chfunc(charg, errmsg, errmsg_buflen);
+ if (!ret) _exit(EXIT_SUCCESS);
+ send_child_error(ep[1], state, errmsg, errmsg_buflen, chfunc_is_async_signal_safe);
#if EXIT_SUCCESS == 127
- _exit(EXIT_FAILURE);
+ _exit(EXIT_FAILURE);
#else
- _exit(127);
+ _exit(127);
#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;
}
- 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;
+ else {
+ rb_syswait(pid);
+ if (state) rb_exc_raise(exc);
}
- return pid;
+ errno = err;
+ return -1;
}
-}
-
-rb_pid_t
-rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds,
- char *errmsg, size_t errmsg_buflen)
-{
- return rb_fork_internal(status, chfunc, charg, TRUE, fds, errmsg, errmsg_buflen);
+ return pid;
}
rb_pid_t
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