diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | process.c | 59 |
2 files changed, 66 insertions, 1 deletions
@@ -1,3 +1,11 @@ +Mon Jun 4 11:33:42 2012 NAKAMURA Usaku <usa@ruby-lang.org> + + * process.c (rb_run_exec_options_err): restore save_env() call for + non-fork environments. + + * process.c (rb_exec_err): restore environments after the failure of + exec to fix [ruby-core:44093] [Bug #6249] on non-fork environments + Mon Jun 4 10:42:04 2012 NAKAMURA Usaku <usa@ruby-lang.org> * io.c (pipe_open): follow up changes in r35889. @@ -2423,6 +2423,30 @@ run_exec_rlimit(VALUE ary, VALUE save, char *errmsg, size_t errmsg_buflen) } #endif +#if !defined(HAVE_FORK) +static VALUE +save_env_i(VALUE i, VALUE ary, int argc, VALUE *argv) +{ + rb_ary_push(ary, hide_obj(rb_ary_dup(argv[0]))); + return Qnil; +} + +static void +save_env(VALUE save) +{ + if (!NIL_P(save) && NIL_P(rb_ary_entry(save, EXEC_OPTION_ENV))) { + VALUE env = rb_const_get(rb_cObject, rb_intern("ENV")); + if (RTEST(env)) { + VALUE ary = hide_obj(rb_ary_new()); + rb_block_call(env, rb_intern("each"), 0, 0, save_env_i, + (VALUE)ary); + rb_ary_store(save, EXEC_OPTION_ENV, ary); + } + rb_ary_store(save, EXEC_OPTION_UNSETENV_OTHERS, Qtrue); + } +} +#endif + int rb_run_exec_options_err(const struct rb_exec_arg *e, struct rb_exec_arg *s, char *errmsg, size_t errmsg_buflen) { @@ -2457,6 +2481,29 @@ rb_run_exec_options_err(const struct rb_exec_arg *e, struct rb_exec_arg *s, char } #endif +#if !defined(HAVE_FORK) + obj = rb_ary_entry(options, EXEC_OPTION_UNSETENV_OTHERS); + if (RTEST(obj)) { + save_env(soptions); + rb_env_clear(); + } + + obj = rb_ary_entry(options, EXEC_OPTION_ENV); + if (!NIL_P(obj)) { + long i; + save_env(soptions); + for (i = 0; i < RARRAY_LEN(obj); i++) { + VALUE pair = RARRAY_PTR(obj)[i]; + VALUE key = RARRAY_PTR(pair)[0]; + VALUE val = RARRAY_PTR(pair)[1]; + if (NIL_P(val)) + ruby_setenv(StringValueCStr(key), 0); + else + ruby_setenv(StringValueCStr(key), StringValueCStr(val)); + } + } +#endif + obj = rb_ary_entry(options, EXEC_OPTION_UMASK); if (!NIL_P(obj)) { mode_t mask = NUM2MODET(obj); @@ -2527,8 +2574,13 @@ int rb_exec_err(const struct rb_exec_arg *e, char *errmsg, size_t errmsg_buflen) { const char *prog = e->prog; +#if !defined(HAVE_FORK) + struct rb_exec_arg sarg, *sargp = &sarg; +#else +# define sargp NULL +#endif - if (rb_run_exec_options_err(e, NULL, errmsg, errmsg_buflen) < 0) { + if (rb_run_exec_options_err(e, sargp, errmsg, errmsg_buflen) < 0) { return -1; } @@ -2538,6 +2590,11 @@ rb_exec_err(const struct rb_exec_arg *e, char *errmsg, size_t errmsg_buflen) else { proc_exec_v(prog, e->argv_str, e->envp_str); } +#if !defined(HAVE_FORK) + rb_run_exec_options_err(sargp, NULL, errmsg, errmsg_buflen); +#else +# undef sargp +#endif return -1; } |