1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* process.c (rlimit_resource_type): new function.

(rlimit_resource_value): new function.
  (proc_getrlimit): use rlimit_resource_type to accept
  symbol and string as resource type.
  (proc_setrlimit): use rlimit_resource_type and rlimit_resource_value
  to accept symbol and string as resource type and values.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15579 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2008-02-22 16:12:32 +00:00
parent 7b218308e0
commit 310735aa4a
3 changed files with 202 additions and 24 deletions

View file

@ -1,3 +1,12 @@
Sat Feb 23 01:09:47 2008 Tanaka Akira <akr@fsij.org>
* process.c (rlimit_resource_type): new function.
(rlimit_resource_value): new function.
(proc_getrlimit): use rlimit_resource_type to accept
symbol and string as resource type.
(proc_setrlimit): use rlimit_resource_type and rlimit_resource_value
to accept symbol and string as resource type and values.
Fri Feb 22 21:12:42 2008 NARUSE, Yui <naruse@ruby-lang.org> Fri Feb 22 21:12:42 2008 NARUSE, Yui <naruse@ruby-lang.org>
* string.c (rb_enc_cr_str_copy): check string's coderange is 7bit or * string.c (rb_enc_cr_str_copy): check string's coderange is 7bit or

185
process.c
View file

@ -2102,6 +2102,133 @@ proc_setpriority(VALUE obj, VALUE which, VALUE who, VALUE prio)
# define NUM2RLIM(v) NUM2ULL(v) # define NUM2RLIM(v) NUM2ULL(v)
#endif #endif
#if defined(RLIM2NUM)
static int
rlimit_resource_type(VALUE rtype)
{
const char *name;
VALUE v;
switch (TYPE(rtype)) {
case T_SYMBOL:
name = rb_id2name(SYM2ID(rtype));
break;
default:
v = rb_check_string_type(rtype);
if (!NIL_P(v)) {
rtype = v;
case T_STRING:
name = StringValueCStr(rtype);
break;
}
/* fall through */
case T_FIXNUM:
case T_BIGNUM:
return NUM2INT(rtype);
}
switch (*name) {
case 'A':
#ifdef RLIMIT_AS
if (strcmp(name, "AS") == 0) return RLIMIT_AS;
#endif
break;
case 'C':
#ifdef RLIMIT_CORE
if (strcmp(name, "CORE") == 0) return RLIMIT_CORE;
#endif
#ifdef RLIMIT_CPU
if (strcmp(name, "CPU") == 0) return RLIMIT_CPU;
#endif
break;
case 'D':
#ifdef RLIMIT_DATA
if (strcmp(name, "DATA") == 0) return RLIMIT_DATA;
#endif
break;
case 'F':
#ifdef RLIMIT_FSIZE
if (strcmp(name, "FSIZE") == 0) return RLIMIT_FSIZE;
#endif
break;
case 'M':
#ifdef RLIMIT_MEMLOCK
if (strcmp(name, "MEMLOCK") == 0) return RLIMIT_MEMLOCK;
#endif
break;
case 'N':
#ifdef RLIMIT_NOFILE
if (strcmp(name, "NOFILE") == 0) return RLIMIT_NOFILE;
#endif
#ifdef RLIMIT_NPROC
if (strcmp(name, "NPROC") == 0) return RLIMIT_NPROC;
#endif
break;
case 'R':
#ifdef RLIMIT_RSS
if (strcmp(name, "RSS") == 0) return RLIMIT_RSS;
#endif
break;
case 'S':
#ifdef RLIMIT_STACK
if (strcmp(name, "STACK") == 0) return RLIMIT_STACK;
#endif
#ifdef RLIMIT_SBSIZE
if (strcmp(name, "SBSIZE") == 0) return RLIMIT_SBSIZE;
#endif
break;
}
rb_raise(rb_eArgError, "invalid resource name: %s", name);
}
static rlim_t
rlimit_resource_value(VALUE rval)
{
const char *name;
VALUE v;
switch (TYPE(rval)) {
case T_SYMBOL:
name = rb_id2name(SYM2ID(rval));
break;
default:
v = rb_check_string_type(rval);
if (!NIL_P(v)) {
rval = v;
case T_STRING:
name = StringValueCStr(rval);
break;
}
/* fall through */
case T_FIXNUM:
case T_BIGNUM:
return NUM2INT(rval);
}
#ifdef RLIM_INFINITY
if (strcmp(name, "INFINITY") == 0) return RLIM_INFINITY;
#endif
#ifdef RLIM_SAVED_MAX
if (strcmp(name, "SAVED_MAX") == 0) return RLIM_SAVED_MAX;
#endif
#ifdef RLIM_SAVED_CUR
if (strcmp(name, "SAVED_CUR") == 0) return RLIM_SAVED_CUR;
#endif
rb_raise(rb_eArgError, "invalid resource value: %s", name);
}
#endif
/* /*
* call-seq: * call-seq:
* Process.getrlimit(resource) => [cur_limit, max_limit] * Process.getrlimit(resource) => [cur_limit, max_limit]
@ -2110,9 +2237,10 @@ proc_setpriority(VALUE obj, VALUE which, VALUE who, VALUE prio)
* _cur_limit_ means current (soft) limit and * _cur_limit_ means current (soft) limit and
* _max_limit_ means maximum (hard) limit. * _max_limit_ means maximum (hard) limit.
* *
* _resource_ indicates the kind of resource to limit: * _resource_ indicates the kind of resource to limit.
* such as <code>Process::RLIMIT_CORE</code>, * It is specified as a symbol such as <code>:CORE</code>,
* <code>Process::RLIMIT_CPU</code>, etc. * a string such as <code>"CORE"</code> or
* a constant such as <code>Process::RLIMIT_CORE</code>.
* See Process.setrlimit for details. * See Process.setrlimit for details.
* *
* _cur_limit_ and _max_limit_ may be <code>Process::RLIM_INFINITY</code>, * _cur_limit_ and _max_limit_ may be <code>Process::RLIM_INFINITY</code>,
@ -2129,7 +2257,7 @@ proc_getrlimit(VALUE obj, VALUE resource)
rb_secure(2); rb_secure(2);
if (getrlimit(NUM2INT(resource), &rlim) < 0) { if (getrlimit(rlimit_resource_type(resource), &rlim) < 0) {
rb_sys_fail("getrlimit"); rb_sys_fail("getrlimit");
} }
return rb_assoc_new(RLIM2NUM(rlim.rlim_cur), RLIM2NUM(rlim.rlim_max)); return rb_assoc_new(RLIM2NUM(rlim.rlim_cur), RLIM2NUM(rlim.rlim_max));
@ -2150,29 +2278,38 @@ proc_getrlimit(VALUE obj, VALUE resource)
* If _max_limit_ is not given, _cur_limit_ is used. * If _max_limit_ is not given, _cur_limit_ is used.
* *
* _resource_ indicates the kind of resource to limit. * _resource_ indicates the kind of resource to limit.
* The list of resources are OS dependent. * It should be a symbol such as <code>:CORE</code>,
* a string such as <code>"CORE"</code> or
* a constant such as <code>Process::RLIMIT_CORE</code>.
* The available resources are OS dependent.
* Ruby may support following resources. * Ruby may support following resources.
* *
* [Process::RLIMIT_CORE] core size (bytes) (SUSv3) * [CORE] core size (bytes) (SUSv3)
* [Process::RLIMIT_CPU] CPU time (seconds) (SUSv3) * [CPU] CPU time (seconds) (SUSv3)
* [Process::RLIMIT_DATA] data segment (bytes) (SUSv3) * [DATA] data segment (bytes) (SUSv3)
* [Process::RLIMIT_FSIZE] file size (bytes) (SUSv3) * [FSIZE] file size (bytes) (SUSv3)
* [Process::RLIMIT_NOFILE] file descriptors (number) (SUSv3) * [NOFILE] file descriptors (number) (SUSv3)
* [Process::RLIMIT_STACK] stack size (bytes) (SUSv3) * [STACK] stack size (bytes) (SUSv3)
* [Process::RLIMIT_AS] total available memory (bytes) (SUSv3, NetBSD, FreeBSD, OpenBSD but 4.4BSD-Lite) * [AS] total available memory (bytes) (SUSv3, NetBSD, FreeBSD, OpenBSD but 4.4BSD-Lite)
* [Process::RLIMIT_MEMLOCK] total size for mlock(2) (bytes) (4.4BSD, GNU/Linux) * [MEMLOCK] total size for mlock(2) (bytes) (4.4BSD, GNU/Linux)
* [Process::RLIMIT_NPROC] number of processes for the user (number) (4.4BSD, GNU/Linux) * [NPROC] number of processes for the user (number) (4.4BSD, GNU/Linux)
* [Process::RLIMIT_RSS] resident memory size (bytes) (4.2BSD, GNU/Linux) * [RSS] resident memory size (bytes) (4.2BSD, GNU/Linux)
* [Process::RLIMIT_SBSIZE] all socket buffers (bytes) (NetBSD, FreeBSD) * [SBSIZE] all socket buffers (bytes) (NetBSD, FreeBSD)
* *
* Other <code>Process::RLIMIT_???</code> constants may be defined. * _cur_limit_ and _max_limit_ may be
* * <code>:INFINITY</code>, <code>"INFINITY"</code> or
* _cur_limit_ and _max_limit_ may be <code>Process::RLIM_INFINITY</code>, * <code>Process::RLIM_INFINITY</code>,
* which means that the resource is not limited. * which means that the resource is not limited.
* They may be <code>Process::RLIM_SAVED_MAX</code> or * They may be <code>Process::RLIM_SAVED_MAX</code>,
* <code>Process::RLIM_SAVED_CUR</code> too. * <code>Process::RLIM_SAVED_CUR</code> and
* corresponding symbols and strings too.
* See system setrlimit(2) manual for details. * See system setrlimit(2) manual for details.
* *
* The following example raise the soft limit of core size to
* the hard limit to try to make core dump possible.
*
* Process.setrlimit(:CORE, Process.getrlimit(:CORE)[1])
*
*/ */
static VALUE static VALUE
@ -2188,10 +2325,10 @@ proc_setrlimit(int argc, VALUE *argv, VALUE obj)
if (rlim_max == Qnil) if (rlim_max == Qnil)
rlim_max = rlim_cur; rlim_max = rlim_cur;
rlim.rlim_cur = NUM2RLIM(rlim_cur); rlim.rlim_cur = rlimit_resource_value(rlim_cur);
rlim.rlim_max = NUM2RLIM(rlim_max); rlim.rlim_max = rlimit_resource_value(rlim_max);
if (setrlimit(NUM2INT(resource), &rlim) < 0) { if (setrlimit(rlimit_resource_type(resource), &rlim) < 0) {
rb_sys_fail("setrlimit"); rb_sys_fail("setrlimit");
} }
return Qnil; return Qnil;

View file

@ -38,4 +38,36 @@ class TestProcess < Test::Unit::TestCase
Process.wait pid Process.wait pid
assert_equal(0, $?.to_i, "#{$?}") assert_equal(0, $?.to_i, "#{$?}")
end end
def test_rlimit_name
return unless rlimit_exist?
[
:AS, "AS",
:CORE, "CORE",
:CPU, "CPU",
:DATA, "DATA",
:FSIZE, "FSIZE",
:MEMLOCK, "MEMLOCK",
:NOFILE, "NOFILE",
:NPROC, "NPROC",
:RSS, "RSS",
:STACK, "STACK",
:SBSIZE, "SBSIZE",
].each {|name|
if Process.const_defined? "RLIMIT_#{name}"
assert_nothing_raised { Process.getrlimit(name) }
else
assert_raise(ArgumentError) { Process.getrlimit(name) }
end
}
assert_raise(ArgumentError) { Process.getrlimit(:FOO) }
assert_raise(ArgumentError) { Process.getrlimit("FOO") }
end
def test_rlimit_value
return unless rlimit_exist?
assert_raise(ArgumentError) { Process.setrlimit(:CORE, :FOO) }
assert_raise(Errno::EPERM) { Process.setrlimit(:NOFILE, :INFINITY) }
assert_raise(Errno::EPERM) { Process.setrlimit(:NOFILE, "INFINITY") }
end
end end