diff --git a/process.c b/process.c index f45ff2f5c5..0bfaa705c8 100644 --- a/process.c +++ b/process.c @@ -1634,7 +1634,35 @@ check_exec_redirect(VALUE key, VALUE val, struct rb_execarg *eargp) } #if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM) -static int rlimit_type_by_lname(const char *name); +static int rlimit_type_by_sym(VALUE key); + +static void +rb_execarg_addopt_rlimit(struct rb_execarg *eargp, int rtype, VALUE val) +{ + VALUE ary = eargp->rlimit_limits; + VALUE tmp, softlim, hardlim; + if (eargp->rlimit_limits == Qfalse) + ary = eargp->rlimit_limits = hide_obj(rb_ary_new()); + else + ary = eargp->rlimit_limits; + tmp = rb_check_array_type(val); + if (!NIL_P(tmp)) { + if (RARRAY_LEN(tmp) == 1) + softlim = hardlim = rb_to_int(rb_ary_entry(tmp, 0)); + else if (RARRAY_LEN(tmp) == 2) { + softlim = rb_to_int(rb_ary_entry(tmp, 0)); + hardlim = rb_to_int(rb_ary_entry(tmp, 1)); + } + else { + rb_raise(rb_eArgError, "wrong exec rlimit option"); + } + } + else { + softlim = hardlim = rb_to_int(val); + } + tmp = hide_obj(rb_ary_new3(3, INT2NUM(rtype), softlim, hardlim)); + rb_ary_push(ary, tmp); +} #endif int @@ -1643,12 +1671,19 @@ rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val) struct rb_execarg *eargp = rb_execarg_get(execarg_obj); ID id; -#if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM) - int rtype; -#endif switch (TYPE(key)) { case T_SYMBOL: +#if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM) + { + int rtype = rlimit_type_by_sym(key); + if (rtype != -1) { + rb_execarg_addopt_rlimit(eargp, rtype, val); + RB_GC_GUARD(execarg_obj); + return ST_CONTINUE; + } + } +#endif if (!(id = rb_check_id(&key))) return ST_STOP; #ifdef HAVE_SETPGID if (id == id_pgroup) { @@ -1680,35 +1715,6 @@ rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val) eargp->new_pgroup_flag = RTEST(val) ? 1 : 0; } else -#endif -#if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM) - if (strncmp("rlimit_", rb_id2name(id), 7) == 0 && - (rtype = rlimit_type_by_lname(rb_id2name(id)+7)) != -1) { - VALUE ary = eargp->rlimit_limits; - VALUE tmp, softlim, hardlim; - if (eargp->rlimit_limits == Qfalse) - ary = eargp->rlimit_limits = hide_obj(rb_ary_new()); - else - ary = eargp->rlimit_limits; - tmp = rb_check_array_type(val); - if (!NIL_P(tmp)) { - if (RARRAY_LEN(tmp) == 1) - softlim = hardlim = rb_to_int(rb_ary_entry(tmp, 0)); - else if (RARRAY_LEN(tmp) == 2) { - softlim = rb_to_int(rb_ary_entry(tmp, 0)); - hardlim = rb_to_int(rb_ary_entry(tmp, 1)); - } - else { - rb_raise(rb_eArgError, "wrong exec rlimit option"); - } - } - else { - softlim = hardlim = rb_to_int(val); - } - tmp = hide_obj(rb_ary_new3(3, INT2NUM(rtype), softlim, hardlim)); - rb_ary_push(ary, tmp); - } - else #endif if (id == id_unsetenv_others) { if (eargp->unsetenv_others_given) { @@ -4792,6 +4798,20 @@ rlimit_type_by_lname(const char *name) return rlimit_resource_name2int(name, 1); } +static int +rlimit_type_by_sym(VALUE key) +{ + const char *rname = RSTRING_PTR(rb_sym2str(key)); + int rtype = -1; + + if (strncmp("rlimit_", rname, 7) == 0) { + rtype = rlimit_type_by_lname(rname + 7); + } + + RB_GC_GUARD(key); + return rtype; +} + static int rlimit_resource_type(VALUE rtype) { diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index 95d32dbced..41b8b68d9d 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -242,6 +242,18 @@ class TestProcess < Test::Unit::TestCase :rlimit_core=>n, :rlimit_cpu=>3600]) {|io| assert_equal("[#{n}, #{n}]\n[3600, 3600]", io.read.chomp) } + + assert_raise(ArgumentError) do + system(RUBY, '-e', 'exit', 'rlimit_bogus'.to_sym => 123) + end + assert_separately([],<<-"end;") # [ruby-core:82033] [Bug #13744] + assert(system("#{RUBY}", "-e", + "exit([3600,3600] == Process.getrlimit(:CPU))", + 'rlimit_cpu'.to_sym => 3600)) + assert_raise(ArgumentError) do + system("#{RUBY}", '-e', 'exit', :rlimit_bogus => 123) + end + end; end MANDATORY_ENVS = %w[RUBYLIB]