summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-04-28 00:11:46 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-04-28 00:11:46 +0000
commit59ba2bf0b676c288491b334c49886d6ba04b7dd3 (patch)
treeb7f99949fac9d4d6f2b5d4d21a7ca2b24a2a233f /io.c
parentde999ae1fc87ce096144954c9d3746363ff04b4d (diff)
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16222 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r--io.c75
1 files changed, 40 insertions, 35 deletions
diff --git a/io.c b/io.c
index f84161fb3d..38cdc79813 100644
--- a/io.c
+++ b/io.c
@@ -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);
}
/*