summaryrefslogtreecommitdiff
path: root/process.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-06-27 00:15:51 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-06-27 00:15:51 +0000
commit2240eb37b8c9abdfd1583bc29ea713695d6a2f6d (patch)
treef173c376626adf6d6fe6b79356fcd0e2f0faa481 /process.c
parent1ca611f360d96abf74d065f082e4b7d77fdfeb77 (diff)
popen: shell commands with envvars and execopts
* io.c (is_popen_fork): check if fork and raise NotImplementedError if unavailable. * io.c (rb_io_s_popen): allow environment variables hash and exec options as flat parameters, not in an array arguments. [Feature#6651] [EXPERIMENTAL] * process.c (rb_execarg_extract_options): extract exec options, but no exceptions on non-exec options and returns them as a Hash. * process.c (rb_execarg_setenv): set environment variables. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36229 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'process.c')
-rw-r--r--process.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/process.c b/process.c
index c8c6b04340..1546969dbd 100644
--- a/process.c
+++ b/process.c
@@ -1654,8 +1654,7 @@ rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
goto redirect;
}
else {
- rb_raise(rb_eArgError, "wrong exec option symbol: %s",
- rb_id2name(id));
+ return ST_STOP;
}
break;
@@ -1667,7 +1666,7 @@ redirect:
break;
default:
- rb_raise(rb_eArgError, "wrong exec option");
+ return ST_STOP;
}
RB_GC_GUARD(execarg_obj);
@@ -1686,7 +1685,28 @@ 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;
VALUE execarg_obj = (VALUE)arg;
- return rb_execarg_addopt(execarg_obj, key, val);
+ if (rb_execarg_addopt(execarg_obj, key, val) != ST_CONTINUE) {
+ if (SYMBOL_P(key))
+ rb_raise(rb_eArgError, "wrong exec option symbol: %"PRIsVALUE,
+ key);
+ rb_raise(rb_eArgError, "wrong exec option");
+ }
+ return ST_CONTINUE;
+}
+
+static int
+check_exec_options_i_extract(st_data_t st_key, st_data_t st_val, st_data_t arg)
+{
+ VALUE key = (VALUE)st_key;
+ VALUE val = (VALUE)st_val;
+ VALUE *args = (VALUE *)arg;
+ VALUE execarg_obj = args[0];
+ if (rb_execarg_addopt(execarg_obj, key, val) != ST_CONTINUE) {
+ VALUE nonopts = args[1];
+ if (NIL_P(nonopts)) args[1] = nonopts = rb_hash_new();
+ rb_hash_aset(nonopts, key, val);
+ }
+ return ST_CONTINUE;
}
static int
@@ -1775,6 +1795,18 @@ rb_check_exec_options(VALUE opthash, VALUE execarg_obj)
st_foreach(RHASH_TBL(opthash), check_exec_options_i, (st_data_t)execarg_obj);
}
+VALUE
+rb_execarg_extract_options(VALUE execarg_obj, VALUE opthash)
+{
+ VALUE args[2];
+ if (RHASH_EMPTY_P(opthash))
+ return Qnil;
+ args[0] = execarg_obj;
+ args[1] = Qnil;
+ st_foreach(RHASH_TBL(opthash), check_exec_options_i_extract, (st_data_t)args);
+ return args[1];
+}
+
static int
check_exec_env_i(st_data_t st_key, st_data_t st_val, st_data_t arg)
{
@@ -2093,6 +2125,14 @@ rb_exec_arg_init(int argc, VALUE *argv, int accept_shell, struct rb_exec_arg *e)
return rb_execarg_init(argc, argv, accept_shell, e->execarg_obj);
}
+void
+rb_execarg_setenv(VALUE execarg_obj, VALUE env)
+{
+ struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
+ env = !NIL_P(env) ? rb_check_exec_env(env) : Qfalse;
+ eargp->env_modification = env;
+}
+
static int
fill_envp_buf_i(st_data_t st_key, st_data_t st_val, st_data_t arg)
{