diff options
-rw-r--r-- | ChangeLog | 31 | ||||
-rw-r--r-- | include/ruby/intern.h | 6 | ||||
-rw-r--r-- | io.c | 75 | ||||
-rw-r--r-- | process.c | 118 |
4 files changed, 125 insertions, 105 deletions
@@ -1,3 +1,34 @@ +Mon Apr 28 09:02:43 2008 Tanaka Akira <akr@fsij.org> + + * include/ruby/intern.h (rb_exec_arg_init): declared. + (rb_exec_arg_addopt): delared. + (rb_exec_arg_fix): declared. + (rb_exec_initarg): removed. + (rb_exec_getargs): removed. + (rb_exec_initarg2): removed. + + * io.c (struct popen_arg): make execarg as a pointer. + (popen_exec): follow popen_arg change. + (pipe_open): add eargp argument. extract argc and argv from eargp. + use rb_exec_arg_addopt to add redirect options. + (pipe_open_v): set up struct rb_exec_arg. + (pipe_open_s): set up struct rb_exec_arg. + + * process.c (rb_exec_arg_addopt): new function extracted from + check_exec_options_i. + (check_exec_options_i): use rb_exec_arg_addopt. + (rb_check_exec_options): opthash is always a hash now. + (rb_exec_getargs): make it static. + (rb_exec_fillarg): renamed from rb_exec_initarg2. don't set up + redirect_fds. + (rb_exec_arg_init): new function. + (rb_exec_arg_fix): new function. + (rb_f_exec): use rb_exec_arg_init and rb_exec_arg_fix. use + rb_exec_arg_addopt to set close_others option. + (run_exec_options): make close_others by default. + (rb_spawn_internal): use rb_exec_arg_init and rb_exec_arg_fix. use + rb_exec_arg_addopt to set close_others option. + Sun Apr 27 18:59:04 2008 Tadayoshi Funaba <tadf@dotrb.org> * rational.c (nurat_expt): use f_rational_new2. [ruby-dev:34524] diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 4df92419b4..9938bb8ec3 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -453,9 +453,9 @@ struct rb_exec_arg { }; int rb_proc_exec_n(int, VALUE*, const char*); int rb_proc_exec(const char*); -VALUE rb_exec_initarg(int argc, VALUE *argv, int accept_shell, struct rb_exec_arg *e); -VALUE rb_exec_getargs(int *argc_p, VALUE **argv_p, int accept_shell, VALUE *env_ret, VALUE *opthash_ret); -void rb_exec_initarg2(VALUE prog, int argc, VALUE *argv, VALUE env, VALUE opthash, struct rb_exec_arg *e); +VALUE rb_exec_arg_init(int argc, VALUE *argv, int accept_shell, struct rb_exec_arg *e); +int rb_exec_arg_addopt(struct rb_exec_arg *e, VALUE key, VALUE val); +void rb_exec_arg_fix(struct rb_exec_arg *e); int rb_exec(const struct rb_exec_arg*); rb_pid_t rb_fork(int*, int (*)(void*), void*, VALUE); VALUE rb_f_exec(int,VALUE*); @@ -3608,7 +3608,7 @@ rb_io_unbuffered(rb_io_t *fptr) #ifdef HAVE_FORK struct popen_arg { - struct rb_exec_arg exec; + struct rb_exec_arg *execp; int modef; int pair[2]; int write_pair[2]; @@ -3673,13 +3673,12 @@ popen_exec(void *pp) struct popen_arg *p = (struct popen_arg*)pp; rb_thread_atfork(); - return rb_exec(&p->exec); + return rb_exec(p->execp); } #endif static VALUE -pipe_open(VALUE prog, int argc, VALUE *argv, - VALUE env, VALUE opthash, const char *mode) +pipe_open(struct rb_exec_arg *eargp, VALUE prog, const char *mode) { int modef = rb_io_mode_flags(mode); int pid = 0; @@ -3690,7 +3689,6 @@ pipe_open(VALUE prog, int argc, VALUE *argv, #if defined(HAVE_FORK) int status; struct popen_arg arg; - VALUE env2 = 0; #elif defined(_WIN32) int openmode = rb_io_mode_modenum(mode); const char *exename = NULL; @@ -3700,15 +3698,30 @@ pipe_open(VALUE prog, int argc, VALUE *argv, int fd = -1; int write_fd = -1; const char *cmd = 0; + int argc; + VALUE *argv; if (prog) cmd = StringValueCStr(prog); -#if defined(HAVE_FORK) - if (prog) { - env2 = rb_hash_new(); - RBASIC(env2)->klass = 0; + if (!eargp) { + /* fork : IO.popen("-") */ + argc = 0; + argv = 0; + } + else if (eargp->argc) { + /* no shell : IO.popen([prog, arg0], arg1, ...) */ + argc = eargp->argc; + argv = eargp->argv; + } + else { + /* with shell : IO.popen(prog) */ + argc = 0; + argv = 0; } + +#if defined(HAVE_FORK) + arg.execp = eargp; arg.modef = modef; arg.pair[0] = arg.pair[1] = -1; arg.write_pair[0] = arg.write_pair[1] = -1; @@ -3725,40 +3738,31 @@ pipe_open(VALUE prog, int argc, VALUE *argv, rb_sys_fail(cmd); } UPDATE_MAXFD_PIPE(arg.pair); - if (env2) { - rb_hash_aset(env2, INT2FIX(0), INT2FIX(arg.write_pair[0])); - rb_hash_aset(env2, INT2FIX(1), INT2FIX(arg.pair[1])); + if (eargp) { + rb_exec_arg_addopt(eargp, INT2FIX(0), INT2FIX(arg.write_pair[0])); + rb_exec_arg_addopt(eargp, INT2FIX(1), INT2FIX(arg.pair[1])); } break; case FMODE_READABLE: if (pipe(arg.pair) < 0) rb_sys_fail(cmd); UPDATE_MAXFD_PIPE(arg.pair); - if (env2) - rb_hash_aset(env2, INT2FIX(1), INT2FIX(arg.pair[1])); + if (eargp) + rb_exec_arg_addopt(eargp, INT2FIX(1), INT2FIX(arg.pair[1])); break; case FMODE_WRITABLE: if (pipe(arg.pair) < 0) rb_sys_fail(cmd); UPDATE_MAXFD_PIPE(arg.pair); - if (env2) - rb_hash_aset(env2, INT2FIX(0), INT2FIX(arg.pair[0])); + if (eargp) + rb_exec_arg_addopt(eargp, INT2FIX(0), INT2FIX(arg.pair[0])); break; default: rb_sys_fail(cmd); } - if (prog) { - VALUE close_others = ID2SYM(rb_intern("close_others")); - if (NIL_P(opthash) || !st_lookup(RHASH_TBL(opthash), close_others, 0)) - rb_hash_aset(env2, close_others, Qtrue); - if (NIL_P(opthash)) - opthash = env2; - else { - opthash = rb_assoc_new(env2, opthash); - RBASIC(opthash)->klass = 0; - } - rb_exec_initarg2(prog, argc, argv, env, opthash, &arg.exec); - pid = rb_fork(&status, popen_exec, &arg, arg.exec.redirect_fds); + if (eargp) { + rb_exec_arg_fix(arg.execp); + pid = rb_fork(&status, popen_exec, &arg, arg.execp->redirect_fds); } else { fflush(stdin); /* is it really needed? */ @@ -3871,9 +3875,10 @@ pipe_open(VALUE prog, int argc, VALUE *argv, static VALUE pipe_open_v(int argc, VALUE *argv, const char *mode) { - VALUE prog, env=Qnil, opthash=Qnil; - prog = rb_exec_getargs(&argc, &argv, Qfalse, &env, &opthash); - return pipe_open(prog, argc, argv, env, opthash, mode); + VALUE prog; + struct rb_exec_arg earg; + prog = rb_exec_arg_init(argc, argv, Qfalse, &earg); + return pipe_open(&earg, prog, mode); } static VALUE @@ -3882,18 +3887,18 @@ pipe_open_s(VALUE prog, const char *mode) const char *cmd = RSTRING_PTR(prog); int argc = 1; VALUE *argv = &prog; - VALUE env=Qnil, opthash=Qnil; + struct rb_exec_arg earg; if (RSTRING_LEN(prog) == 1 && cmd[0] == '-') { #if !defined(HAVE_FORK) rb_raise(rb_eNotImpError, "fork() function is unimplemented on this machine"); #endif - return pipe_open(0, 0, 0, Qnil, Qnil, mode); + return pipe_open(0, 0, mode); } - rb_exec_getargs(&argc, &argv, Qtrue, &env, &opthash); - return pipe_open(prog, 0, 0, Qnil, Qnil, mode); + rb_exec_arg_init(argc, argv, Qtrue, &earg); + return pipe_open(&earg, prog, mode); } /* @@ -1349,12 +1349,10 @@ check_exec_redirect(VALUE key, VALUE val, VALUE options) static int rlimit_type_by_lname(const char *name); #endif -static int -check_exec_options_i(st_data_t st_key, st_data_t st_val, st_data_t arg) +int +rb_exec_arg_addopt(struct rb_exec_arg *e, VALUE key, VALUE val) { - VALUE key = (VALUE)st_key; - VALUE val = (VALUE)st_val; - VALUE options = (VALUE)arg; + VALUE options = e->options; ID id; #ifdef RLIM2NUM int rtype; @@ -1477,6 +1475,15 @@ redirect: return ST_CONTINUE; } +static int +check_exec_options_i(st_data_t st_key, st_data_t st_val, st_data_t arg) +{ + VALUE key = (VALUE)st_key; + VALUE val = (VALUE)st_val; + struct rb_exec_arg *e = (struct rb_exec_arg *)arg; + return rb_exec_arg_addopt(e, key, val); +} + static VALUE check_exec_fds(VALUE options) { @@ -1513,29 +1520,12 @@ check_exec_fds(VALUE options) return h; } -static VALUE -rb_check_exec_options(VALUE opthash, VALUE *fds) +static void +rb_check_exec_options(VALUE opthash, struct rb_exec_arg *e) { - VALUE options, h; - int i; - - options = hide_obj(rb_ary_new()); - - if (TYPE(opthash) == T_ARRAY) { - for (i = 0; i < RARRAY_LEN(opthash); i++) { - VALUE hash = RARRAY_PTR(opthash)[i]; - st_foreach(RHASH_TBL(hash), check_exec_options_i, (st_data_t)options); - } - } - else { - st_foreach(RHASH_TBL(opthash), check_exec_options_i, (st_data_t)options); - } - - h = check_exec_fds(options); - if (fds) - *fds = h; - - return options; + if (RHASH_EMPTY_P(opthash)) + return; + st_foreach(RHASH_TBL(opthash), check_exec_options_i, (st_data_t)e); } static int @@ -1602,15 +1592,15 @@ rb_check_argv(int argc, VALUE *argv) return prog; } -VALUE -rb_exec_getargs(int *argc_p, VALUE **argv_p, int accept_shell, VALUE *env_ret, VALUE *options_ret) +static VALUE +rb_exec_getargs(int *argc_p, VALUE **argv_p, int accept_shell, VALUE *env_ret, VALUE *opthash_ret, struct rb_exec_arg *e) { VALUE hash, prog; if (0 < *argc_p) { hash = rb_check_convert_type((*argv_p)[*argc_p-1], T_HASH, "Hash", "to_hash"); if (!NIL_P(hash)) { - *options_ret = hash; + *opthash_ret = hash; (*argc_p)--; } } @@ -1634,41 +1624,43 @@ rb_exec_getargs(int *argc_p, VALUE **argv_p, int accept_shell, VALUE *env_ret, V return prog; } -void -rb_exec_initarg2(VALUE prog, int argc, VALUE *argv, - VALUE env, VALUE opthash, struct rb_exec_arg *e) +static void +rb_exec_fillarg(VALUE prog, int argc, VALUE *argv, VALUE env, VALUE opthash, struct rb_exec_arg *e) { - VALUE options=Qnil, fds=Qnil; - + VALUE options; MEMZERO(e, struct rb_exec_arg, 1); + options = hide_obj(rb_ary_new()); + e->options = options; if (!NIL_P(opthash)) { - options = rb_check_exec_options(opthash, &fds); + rb_check_exec_options(opthash, e); } if (!NIL_P(env)) { env = rb_check_exec_env(env); - if (NIL_P(options)) - options = hide_obj(rb_ary_new()); rb_ary_store(options, EXEC_OPTION_ENV, env); } e->argc = argc; e->argv = argv; e->prog = prog ? RSTRING_PTR(prog) : 0; - e->options = options; - e->redirect_fds = fds; } - VALUE -rb_exec_initarg(int argc, VALUE *argv, int accept_shell, struct rb_exec_arg *e) +rb_exec_arg_init(int argc, VALUE *argv, int accept_shell, struct rb_exec_arg *e) { - VALUE prog, env=Qnil, opthash=Qnil; - prog = rb_exec_getargs(&argc, &argv, accept_shell, &env, &opthash); - rb_exec_initarg2(prog, argc, argv, env, opthash, e); + VALUE prog; + VALUE env = Qnil, opthash = Qnil; + prog = rb_exec_getargs(&argc, &argv, accept_shell, &env, &opthash, e); + rb_exec_fillarg(prog, argc, argv, env, opthash, e); return prog; } +void +rb_exec_arg_fix(struct rb_exec_arg *e) +{ + e->redirect_fds = check_exec_fds(e->options); +} + /* * call-seq: * exec([env,] command [, arg, ...] [,options]) @@ -1704,12 +1696,15 @@ rb_exec_initarg(int argc, VALUE *argv, int accept_shell, struct rb_exec_arg *e) VALUE rb_f_exec(int argc, VALUE *argv) { - struct rb_exec_arg e; + struct rb_exec_arg earg; - rb_exec_initarg(argc, argv, Qtrue, &e); + rb_exec_arg_init(argc, argv, Qtrue, &earg); + if (NIL_P(rb_ary_entry(earg.options, EXEC_OPTION_CLOSE_OTHERS))) + rb_exec_arg_addopt(&earg, ID2SYM(rb_intern("close_others")), Qfalse); + rb_exec_arg_fix(&earg); - rb_exec(&e); - rb_sys_fail(e.prog); + rb_exec(&earg); + rb_sys_fail(earg.prog); return Qnil; /* dummy */ } @@ -2055,7 +2050,7 @@ run_exec_options(const struct rb_exec_arg *e) #ifdef HAVE_FORK obj = rb_ary_entry(options, EXEC_OPTION_CLOSE_OTHERS); - if (RTEST(obj)) { + if (obj != Qfalse) { rb_close_before_exec(3, FIX2INT(obj), e->redirect_fds); } #endif @@ -2550,24 +2545,13 @@ rb_spawn_internal(int argc, VALUE *argv, int default_close_others) rb_pid_t status; VALUE prog; struct rb_exec_arg earg; - int argc2 = argc; - VALUE *argv2 = argv, env = Qnil, opthash = Qnil; - VALUE close_others = ID2SYM(rb_intern("close_others")); - - prog = rb_exec_getargs(&argc2, &argv2, Qtrue, &env, &opthash); - if (default_close_others) { - if (NIL_P(opthash)) { - opthash = rb_hash_new(); - RBASIC(opthash)->klass = 0; - } - if (RBASIC(opthash)->klass) { - opthash = rb_hash_dup(opthash); - RBASIC(opthash)->klass = 0; - } - if (!st_lookup(RHASH_TBL(opthash), close_others, 0)) - rb_hash_aset(opthash, close_others, Qtrue); + + prog = rb_exec_arg_init(argc, argv, Qtrue, &earg); + if (NIL_P(rb_ary_entry(earg.options, EXEC_OPTION_CLOSE_OTHERS))) { + VALUE v = default_close_others ? Qtrue : Qfalse; + rb_exec_arg_addopt(&earg, ID2SYM(rb_intern("close_others")), v); } - rb_exec_initarg2(prog, argc2, argv2, env, opthash, &earg); + rb_exec_arg_fix(&earg); #if defined HAVE_FORK status = rb_fork(&status, rb_exec_atfork, &earg, earg.redirect_fds); |