mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
io.c: spawnv
* io.c (pipe_open): merge win32 code using spawnv(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36209 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5be0ab591c
commit
cc1c97ae31
2 changed files with 66 additions and 95 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
Sun Jun 24 23:02:17 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* io.c (pipe_open): merge win32 code using spawnv().
|
||||||
|
|
||||||
Sun Jun 24 22:53:42 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sun Jun 24 22:53:42 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* process.c (check_exec_fds): separate check_exec_fds_1() since
|
* process.c (check_exec_fds): separate check_exec_fds_1() since
|
||||||
|
|
157
io.c
157
io.c
|
@ -5340,7 +5340,13 @@ rb_pipe(int *pipes)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_FORK
|
#ifdef _WIN32
|
||||||
|
#define HAVE_SPAWNV 1
|
||||||
|
#define spawnv(mode, cmd, args) rb_w32_aspawn((mode), (cmd), (args))
|
||||||
|
#define spawn(mode, cmd) rb_w32_spawn((mode), (cmd), 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_FORK) || defined(HAVE_SPAWNV)
|
||||||
struct popen_arg {
|
struct popen_arg {
|
||||||
VALUE execarg_obj;
|
VALUE execarg_obj;
|
||||||
struct rb_execarg *eargp;
|
struct rb_execarg *eargp;
|
||||||
|
@ -5348,7 +5354,9 @@ struct popen_arg {
|
||||||
int pair[2];
|
int pair[2];
|
||||||
int write_pair[2];
|
int write_pair[2];
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_FORK
|
||||||
static void
|
static void
|
||||||
popen_redirect(struct popen_arg *p)
|
popen_redirect(struct popen_arg *p)
|
||||||
{
|
{
|
||||||
|
@ -5478,12 +5486,24 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
|
||||||
VALUE write_port;
|
VALUE write_port;
|
||||||
#if defined(HAVE_FORK)
|
#if defined(HAVE_FORK)
|
||||||
int status;
|
int status;
|
||||||
struct popen_arg arg;
|
|
||||||
char errmsg[80] = { '\0' };
|
char errmsg[80] = { '\0' };
|
||||||
#elif defined(_WIN32)
|
#endif
|
||||||
volatile VALUE argbuf;
|
#if defined(HAVE_FORK) || defined(HAVE_SPAWNV)
|
||||||
|
struct popen_arg arg;
|
||||||
|
int e = 0;
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_SPAWNV)
|
||||||
|
# if defined(HAVE_SPAWNVE)
|
||||||
|
# define DO_SPAWN(cmd, args, envp) ((args) ? \
|
||||||
|
spawnve(P_NOWAIT, (cmd), (args), (envp)) : \
|
||||||
|
spawne(P_NOWAIT, (cmd), (envp)))
|
||||||
|
# else
|
||||||
|
# define DO_SPAWN(cmd, args, envp) ((args) ? \
|
||||||
|
spawnv(P_NOWAIT, (cmd), (args)) : \
|
||||||
|
spawn(P_NOWAIT, (cmd)))
|
||||||
|
# endif
|
||||||
char **args = NULL;
|
char **args = NULL;
|
||||||
int pair[2], write_pair[2];
|
char **envp = NULL;
|
||||||
#endif
|
#endif
|
||||||
#if !defined(HAVE_FORK)
|
#if !defined(HAVE_FORK)
|
||||||
struct rb_execarg sarg, *sargp = &sarg;
|
struct rb_execarg sarg, *sargp = &sarg;
|
||||||
|
@ -5493,7 +5513,7 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
|
||||||
int write_fd = -1;
|
int write_fd = -1;
|
||||||
#if !defined(HAVE_FORK)
|
#if !defined(HAVE_FORK)
|
||||||
const char *cmd = 0;
|
const char *cmd = 0;
|
||||||
#if !defined(_WIN32)
|
#if !defined(HAVE_SPAWNV)
|
||||||
int argc;
|
int argc;
|
||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
#endif
|
#endif
|
||||||
|
@ -5502,12 +5522,17 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
|
||||||
cmd = StringValueCStr(prog);
|
cmd = StringValueCStr(prog);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_FORK)
|
#if defined(HAVE_FORK) || defined(HAVE_SPAWNV)
|
||||||
arg.execarg_obj = execarg_obj;
|
arg.execarg_obj = execarg_obj;
|
||||||
arg.eargp = eargp;
|
arg.eargp = eargp;
|
||||||
arg.modef = fmode;
|
arg.modef = fmode;
|
||||||
arg.pair[0] = arg.pair[1] = -1;
|
arg.pair[0] = arg.pair[1] = -1;
|
||||||
arg.write_pair[0] = arg.write_pair[1] = -1;
|
arg.write_pair[0] = arg.write_pair[1] = -1;
|
||||||
|
# if !defined(HAVE_FORK)
|
||||||
|
if (eargp && !eargp->use_shell) {
|
||||||
|
args = ARGVSTR2ARGV(eargp->invoke.cmd.argv_str);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
switch (fmode & (FMODE_READABLE|FMODE_WRITABLE)) {
|
switch (fmode & (FMODE_READABLE|FMODE_WRITABLE)) {
|
||||||
case FMODE_READABLE|FMODE_WRITABLE:
|
case FMODE_READABLE|FMODE_WRITABLE:
|
||||||
if (rb_pipe(arg.write_pair) < 0)
|
if (rb_pipe(arg.write_pair) < 0)
|
||||||
|
@ -5541,9 +5566,29 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
|
||||||
}
|
}
|
||||||
if (!NIL_P(execarg_obj)) {
|
if (!NIL_P(execarg_obj)) {
|
||||||
rb_execarg_fixup(execarg_obj);
|
rb_execarg_fixup(execarg_obj);
|
||||||
|
# if defined(HAVE_FORK)
|
||||||
pid = rb_fork_async_signal_safe(&status, popen_exec, &arg, arg.eargp->redirect_fds, errmsg, sizeof(errmsg));
|
pid = rb_fork_async_signal_safe(&status, popen_exec, &arg, arg.eargp->redirect_fds, errmsg, sizeof(errmsg));
|
||||||
|
# else
|
||||||
|
rb_execarg_run_options(eargp, sargp, NULL, 0);
|
||||||
|
if (eargp->envp_str) envp = (char **)RSTRING_PTR(eargp->envp_str);
|
||||||
|
while ((pid = DO_SPAWN(cmd, args, envp)) == -1) {
|
||||||
|
/* exec failed */
|
||||||
|
switch (e = errno) {
|
||||||
|
case EAGAIN:
|
||||||
|
# if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
||||||
|
case EWOULDBLOCK:
|
||||||
|
# endif
|
||||||
|
rb_thread_sleep(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (eargp)
|
||||||
|
rb_execarg_run_options(sargp, NULL, NULL, 0);
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
# if defined(HAVE_FORK)
|
||||||
pid = rb_fork_ruby(&status);
|
pid = rb_fork_ruby(&status);
|
||||||
if (pid == 0) { /* child */
|
if (pid == 0) { /* child */
|
||||||
rb_thread_atfork();
|
rb_thread_atfork();
|
||||||
|
@ -5552,11 +5597,16 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
|
||||||
rb_io_synchronized(RFILE(orig_stderr)->fptr);
|
rb_io_synchronized(RFILE(orig_stderr)->fptr);
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
# else
|
||||||
|
rb_notimplement();
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parent */
|
/* parent */
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
int e = errno;
|
# if defined(HAVE_FORK)
|
||||||
|
e = errno;
|
||||||
|
# endif
|
||||||
close(arg.pair[0]);
|
close(arg.pair[0]);
|
||||||
close(arg.pair[1]);
|
close(arg.pair[1]);
|
||||||
if ((fmode & (FMODE_READABLE|FMODE_WRITABLE)) == (FMODE_READABLE|FMODE_WRITABLE)) {
|
if ((fmode & (FMODE_READABLE|FMODE_WRITABLE)) == (FMODE_READABLE|FMODE_WRITABLE)) {
|
||||||
|
@ -5564,8 +5614,10 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
|
||||||
close(arg.write_pair[1]);
|
close(arg.write_pair[1]);
|
||||||
}
|
}
|
||||||
errno = e;
|
errno = e;
|
||||||
|
# if defined(HAVE_FORK)
|
||||||
if (errmsg[0])
|
if (errmsg[0])
|
||||||
rb_sys_fail(errmsg);
|
rb_sys_fail(errmsg);
|
||||||
|
# endif
|
||||||
rb_sys_fail_str(prog);
|
rb_sys_fail_str(prog);
|
||||||
}
|
}
|
||||||
if ((fmode & FMODE_READABLE) && (fmode & FMODE_WRITABLE)) {
|
if ((fmode & FMODE_READABLE) && (fmode & FMODE_WRITABLE)) {
|
||||||
|
@ -5582,92 +5634,6 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
|
||||||
close(arg.pair[0]);
|
close(arg.pair[0]);
|
||||||
fd = arg.pair[1];
|
fd = arg.pair[1];
|
||||||
}
|
}
|
||||||
#elif defined(_WIN32)
|
|
||||||
if (eargp && !eargp->use_shell) {
|
|
||||||
args = ARGVSTR2ARGV(eargp->invoke.cmd.argv_str);
|
|
||||||
}
|
|
||||||
switch (fmode & (FMODE_READABLE|FMODE_WRITABLE)) {
|
|
||||||
case FMODE_READABLE|FMODE_WRITABLE:
|
|
||||||
if (rb_pipe(write_pair) < 0)
|
|
||||||
rb_sys_fail_str(prog);
|
|
||||||
if (rb_pipe(pair) < 0) {
|
|
||||||
int e = errno;
|
|
||||||
close(write_pair[0]);
|
|
||||||
close(write_pair[1]);
|
|
||||||
errno = e;
|
|
||||||
rb_sys_fail_str(prog);
|
|
||||||
}
|
|
||||||
if (eargp) {
|
|
||||||
rb_execarg_addopt(execarg_obj, INT2FIX(0), INT2FIX(write_pair[0]));
|
|
||||||
rb_execarg_addopt(execarg_obj, INT2FIX(1), INT2FIX(pair[1]));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FMODE_READABLE:
|
|
||||||
if (rb_pipe(pair) < 0)
|
|
||||||
rb_sys_fail_str(prog);
|
|
||||||
if (eargp)
|
|
||||||
rb_execarg_addopt(execarg_obj, INT2FIX(1), INT2FIX(pair[1]));
|
|
||||||
break;
|
|
||||||
case FMODE_WRITABLE:
|
|
||||||
if (rb_pipe(pair) < 0)
|
|
||||||
rb_sys_fail_str(prog);
|
|
||||||
if (eargp)
|
|
||||||
rb_execarg_addopt(execarg_obj, INT2FIX(0), INT2FIX(pair[0]));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
rb_sys_fail_str(prog);
|
|
||||||
}
|
|
||||||
if (!NIL_P(execarg_obj)) {
|
|
||||||
rb_execarg_fixup(execarg_obj);
|
|
||||||
rb_execarg_run_options(eargp, sargp, NULL, 0);
|
|
||||||
}
|
|
||||||
while ((pid = (args ?
|
|
||||||
rb_w32_aspawn(P_NOWAIT, cmd, args) :
|
|
||||||
rb_w32_spawn(P_NOWAIT, cmd, 0))) == -1) {
|
|
||||||
/* exec failed */
|
|
||||||
switch (errno) {
|
|
||||||
case EAGAIN:
|
|
||||||
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
|
||||||
case EWOULDBLOCK:
|
|
||||||
#endif
|
|
||||||
rb_thread_sleep(1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
int e = errno;
|
|
||||||
if (eargp)
|
|
||||||
rb_execarg_run_options(sargp, NULL, NULL, 0);
|
|
||||||
close(pair[0]);
|
|
||||||
close(pair[1]);
|
|
||||||
if ((fmode & (FMODE_READABLE|FMODE_WRITABLE)) == (FMODE_READABLE|FMODE_WRITABLE)) {
|
|
||||||
close(write_pair[0]);
|
|
||||||
close(write_pair[1]);
|
|
||||||
}
|
|
||||||
errno = e;
|
|
||||||
rb_sys_fail_str(prog);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RB_GC_GUARD(argbuf);
|
|
||||||
|
|
||||||
if (eargp)
|
|
||||||
rb_execarg_run_options(sargp, NULL, NULL, 0);
|
|
||||||
if ((fmode & FMODE_READABLE) && (fmode & FMODE_WRITABLE)) {
|
|
||||||
close(pair[1]);
|
|
||||||
fd = pair[0];
|
|
||||||
close(write_pair[0]);
|
|
||||||
write_fd = write_pair[1];
|
|
||||||
}
|
|
||||||
else if (fmode & FMODE_READABLE) {
|
|
||||||
close(pair[1]);
|
|
||||||
fd = pair[0];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
close(pair[0]);
|
|
||||||
fd = pair[1];
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
if (argc) {
|
if (argc) {
|
||||||
prog = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
|
prog = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
|
||||||
|
@ -5747,8 +5713,9 @@ pipe_open_s(VALUE prog, const char *modestr, int fmode, convconfig_t *convconfig
|
||||||
#if !defined(HAVE_FORK)
|
#if !defined(HAVE_FORK)
|
||||||
rb_raise(rb_eNotImpError,
|
rb_raise(rb_eNotImpError,
|
||||||
"fork() function is unimplemented on this machine");
|
"fork() function is unimplemented on this machine");
|
||||||
#endif
|
#else
|
||||||
return pipe_open(Qnil, modestr, fmode, convconfig);
|
return pipe_open(Qnil, modestr, fmode, convconfig);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
execarg_obj = rb_execarg_new(argc, argv, TRUE);
|
execarg_obj = rb_execarg_new(argc, argv, TRUE);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue