From 5c4db58b1240737e0058d856c3cc92c0841f2d0c Mon Sep 17 00:00:00 2001 From: normal Date: Thu, 13 Jul 2017 20:47:36 +0000 Subject: 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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59322 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- process.c | 86 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 33 deletions(-) (limited to 'process.c') 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) { -- cgit v1.2.3