ruby-changes:24158
From: nobu <ko1@a...>
Date: Sun, 24 Jun 2012 23:02:30 +0900 (JST)
Subject: [ruby-changes:24158] nobu:r36209 (trunk): io.c: spawnv
nobu 2012-06-24 23:02:19 +0900 (Sun, 24 Jun 2012) New Revision: 36209 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=36209 Log: io.c: spawnv * io.c (pipe_open): merge win32 code using spawnv(). Modified files: trunk/ChangeLog trunk/io.c Index: ChangeLog =================================================================== --- ChangeLog (revision 36208) +++ ChangeLog (revision 36209) @@ -1,3 +1,7 @@ +Sun Jun 24 23:02:17 2012 Nobuyoshi Nakada <nobu@r...> + + * io.c (pipe_open): merge win32 code using spawnv(). + Sun Jun 24 22:53:42 2012 Nobuyoshi Nakada <nobu@r...> * process.c (check_exec_fds): separate check_exec_fds_1() since Index: io.c =================================================================== --- io.c (revision 36208) +++ io.c (revision 36209) @@ -5340,7 +5340,13 @@ 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 { VALUE execarg_obj; struct rb_execarg *eargp; @@ -5348,7 +5354,9 @@ int pair[2]; int write_pair[2]; }; +#endif +#ifdef HAVE_FORK static void popen_redirect(struct popen_arg *p) { @@ -5478,12 +5486,24 @@ VALUE write_port; #if defined(HAVE_FORK) int status; - struct popen_arg arg; char errmsg[80] = { '\0' }; -#elif defined(_WIN32) - volatile VALUE argbuf; +#endif +#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; - int pair[2], write_pair[2]; + char **envp = NULL; #endif #if !defined(HAVE_FORK) struct rb_execarg sarg, *sargp = &sarg; @@ -5493,7 +5513,7 @@ int write_fd = -1; #if !defined(HAVE_FORK) const char *cmd = 0; -#if !defined(_WIN32) +#if !defined(HAVE_SPAWNV) int argc; VALUE *argv; #endif @@ -5502,12 +5522,17 @@ cmd = StringValueCStr(prog); #endif -#if defined(HAVE_FORK) +#if defined(HAVE_FORK) || defined(HAVE_SPAWNV) arg.execarg_obj = execarg_obj; arg.eargp = eargp; arg.modef = fmode; arg.pair[0] = arg.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)) { case FMODE_READABLE|FMODE_WRITABLE: if (rb_pipe(arg.write_pair) < 0) @@ -5541,9 +5566,29 @@ } if (!NIL_P(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)); +# 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 { +# if defined(HAVE_FORK) pid = rb_fork_ruby(&status); if (pid == 0) { /* child */ rb_thread_atfork(); @@ -5552,11 +5597,16 @@ rb_io_synchronized(RFILE(orig_stderr)->fptr); return Qnil; } +# else + rb_notimplement(); +# endif } /* parent */ if (pid == -1) { - int e = errno; +# if defined(HAVE_FORK) + e = errno; +# endif close(arg.pair[0]); close(arg.pair[1]); if ((fmode & (FMODE_READABLE|FMODE_WRITABLE)) == (FMODE_READABLE|FMODE_WRITABLE)) { @@ -5564,8 +5614,10 @@ close(arg.write_pair[1]); } errno = e; +# if defined(HAVE_FORK) if (errmsg[0]) rb_sys_fail(errmsg); +# endif rb_sys_fail_str(prog); } if ((fmode & FMODE_READABLE) && (fmode & FMODE_WRITABLE)) { @@ -5582,92 +5634,6 @@ close(arg.pair[0]); 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 if (argc) { prog = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" ")); @@ -5747,8 +5713,9 @@ #if !defined(HAVE_FORK) rb_raise(rb_eNotImpError, "fork() function is unimplemented on this machine"); -#endif +#else return pipe_open(Qnil, modestr, fmode, convconfig); +#endif } execarg_obj = rb_execarg_new(argc, argv, TRUE); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/