summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal.h4
-rw-r--r--io.c4
-rw-r--r--process.c8
3 files changed, 9 insertions, 7 deletions
diff --git a/internal.h b/internal.h
index 3309b65ad5..b40af16b48 100644
--- a/internal.h
+++ b/internal.h
@@ -963,9 +963,9 @@ VALUE rb_int_positive_pow(long x, unsigned long y);
/* process.c */
int rb_exec_async_signal_safe(const struct rb_execarg *e, char *errmsg, size_t errmsg_buflen);
rb_pid_t rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds, char *errmsg, size_t errmsg_buflen);
-VALUE rb_execarg_new(int argc, VALUE *argv, int accept_shell);
+VALUE rb_execarg_new(int argc, const VALUE *argv, int accept_shell);
struct rb_execarg *rb_execarg_get(VALUE execarg_obj); /* dangerous. needs GC guard. */
-VALUE rb_execarg_init(int argc, VALUE *argv, int accept_shell, VALUE execarg_obj);
+VALUE rb_execarg_init(int argc, const VALUE *argv, int accept_shell, VALUE execarg_obj);
int rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val);
void rb_execarg_fixup(VALUE execarg_obj);
int rb_execarg_run_options(const struct rb_execarg *e, struct rb_execarg *s, char* errmsg, size_t errmsg_buflen);
diff --git a/io.c b/io.c
index c78de9ada1..3062a5fc3a 100644
--- a/io.c
+++ b/io.c
@@ -6225,10 +6225,8 @@ rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
rb_raise(rb_eArgError, "too many arguments");
}
#endif
- tmp = rb_ary_dup(tmp);
- RBASIC_CLEAR_CLASS(tmp);
execarg_obj = rb_execarg_new((int)len, RARRAY_CONST_PTR(tmp), FALSE);
- rb_ary_clear(tmp);
+ RB_GC_GUARD(tmp);
}
else {
SafeStringValue(pname);
diff --git a/process.c b/process.c
index 33a294866d..f0ed4a4206 100644
--- a/process.c
+++ b/process.c
@@ -2198,7 +2198,7 @@ rb_exec_fillarg(VALUE prog, int argc, VALUE *argv, VALUE env, VALUE opthash, VAL
}
VALUE
-rb_execarg_new(int argc, VALUE *argv, int accept_shell)
+rb_execarg_new(int argc, const VALUE *argv, int accept_shell)
{
VALUE execarg_obj;
struct rb_execarg *eargp;
@@ -2217,13 +2217,17 @@ rb_execarg_get(VALUE execarg_obj)
}
VALUE
-rb_execarg_init(int argc, VALUE *argv, int accept_shell, VALUE execarg_obj)
+rb_execarg_init(int argc, const VALUE *orig_argv, int accept_shell, VALUE execarg_obj)
{
struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
VALUE prog, ret;
VALUE env = Qnil, opthash = Qnil;
+ VALUE argv_buf;
+ VALUE *argv = ALLOCV_N(VALUE, argv_buf, argc);
+ MEMCPY(argv, orig_argv, VALUE, argc);
prog = rb_exec_getargs(&argc, &argv, accept_shell, &env, &opthash);
rb_exec_fillarg(prog, argc, argv, env, opthash, execarg_obj);
+ ALLOCV_END(argv_buf);
ret = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
RB_GC_GUARD(execarg_obj);
return ret;