ruby-changes:47208
From: normal <ko1@a...>
Date: Fri, 14 Jul 2017 05:47:44 +0900 (JST)
Subject: [ruby-changes:47208] normal:r59322 (trunk): process.c: handle dynamic :rlimit_* symbols in spawn execopts
normal 2017-07-14 05:47:36 +0900 (Fri, 14 Jul 2017) New Revision: 59322 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59322 Log: process.c: handle dynamic :rlimit_* symbols in spawn execopts * process.c (rb_execarg_addopt_rlimit): hoist out of rb_execarg_addopt (rlimit_type_by_sym): new wrapper for dynamic symbol (rb_execarg_addopt): check for dsym via rlimit_type_by_sym * test/ruby/test_process.rb (test_execopts_rlimit): check dsym w/o pindown Add extra check for bogus rlimit args, too. [ruby-core:82033] [Bug #13744] Modified files: trunk/process.c trunk/test/ruby/test_process.rb Index: process.c =================================================================== --- process.c (revision 59321) +++ process.c (revision 59322) @@ -1634,7 +1634,35 @@ check_exec_redirect(VALUE key, VALUE val https://github.com/ruby/ruby/blob/trunk/process.c#L1634 } #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, VAL https://github.com/ruby/ruby/blob/trunk/process.c#L1671 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) { @@ -1681,35 +1716,6 @@ rb_execarg_addopt(VALUE execarg_obj, VAL https://github.com/ruby/ruby/blob/trunk/process.c#L1716 } 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) { rb_raise(rb_eArgError, "unsetenv_others option specified twice"); @@ -4793,6 +4799,20 @@ rlimit_type_by_lname(const char *name) https://github.com/ruby/ruby/blob/trunk/process.c#L4799 } 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) { const char *name; Index: test/ruby/test_process.rb =================================================================== --- test/ruby/test_process.rb (revision 59321) +++ test/ruby/test_process.rb (revision 59322) @@ -242,6 +242,18 @@ class TestProcess < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_process.rb#L242 :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] -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/