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>
* 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)
#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:
* 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
* _max_limit_ means maximum (hard) limit.
*
* _resource_ indicates the kind of resource to limit:
* such as <code>Process::RLIMIT_CORE</code>,
* <code>Process::RLIMIT_CPU</code>, etc.
* _resource_ indicates the kind of resource to limit.
* It is specified as a symbol such as <code>:CORE</code>,
* a string such as <code>"CORE"</code> or
* a constant such as <code>Process::RLIMIT_CORE</code>.
* See Process.setrlimit for details.
*
* _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);
if (getrlimit(NUM2INT(resource), &rlim) < 0) {
if (getrlimit(rlimit_resource_type(resource), &rlim) < 0) {
rb_sys_fail("getrlimit");
}
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.
*
* _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.
*
* [Process::RLIMIT_CORE] core size (bytes) (SUSv3)
* [Process::RLIMIT_CPU] CPU time (seconds) (SUSv3)
* [Process::RLIMIT_DATA] data segment (bytes) (SUSv3)
* [Process::RLIMIT_FSIZE] file size (bytes) (SUSv3)
* [Process::RLIMIT_NOFILE] file descriptors (number) (SUSv3)
* [Process::RLIMIT_STACK] stack size (bytes) (SUSv3)
* [Process::RLIMIT_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)
* [Process::RLIMIT_NPROC] number of processes for the user (number) (4.4BSD, GNU/Linux)
* [Process::RLIMIT_RSS] resident memory size (bytes) (4.2BSD, GNU/Linux)
* [Process::RLIMIT_SBSIZE] all socket buffers (bytes) (NetBSD, FreeBSD)
* [CORE] core size (bytes) (SUSv3)
* [CPU] CPU time (seconds) (SUSv3)
* [DATA] data segment (bytes) (SUSv3)
* [FSIZE] file size (bytes) (SUSv3)
* [NOFILE] file descriptors (number) (SUSv3)
* [STACK] stack size (bytes) (SUSv3)
* [AS] total available memory (bytes) (SUSv3, NetBSD, FreeBSD, OpenBSD but 4.4BSD-Lite)
* [MEMLOCK] total size for mlock(2) (bytes) (4.4BSD, GNU/Linux)
* [NPROC] number of processes for the user (number) (4.4BSD, GNU/Linux)
* [RSS] resident memory size (bytes) (4.2BSD, GNU/Linux)
* [SBSIZE] all socket buffers (bytes) (NetBSD, FreeBSD)
*
* Other <code>Process::RLIMIT_???</code> constants may be defined.
*
* _cur_limit_ and _max_limit_ may be <code>Process::RLIM_INFINITY</code>,
* _cur_limit_ and _max_limit_ may be
* <code>:INFINITY</code>, <code>"INFINITY"</code> or
* <code>Process::RLIM_INFINITY</code>,
* which means that the resource is not limited.
* They may be <code>Process::RLIM_SAVED_MAX</code> or
* <code>Process::RLIM_SAVED_CUR</code> too.
* They may be <code>Process::RLIM_SAVED_MAX</code>,
* <code>Process::RLIM_SAVED_CUR</code> and
* corresponding symbols and strings too.
* 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
@ -2188,10 +2325,10 @@ proc_setrlimit(int argc, VALUE *argv, VALUE obj)
if (rlim_max == Qnil)
rlim_max = rlim_cur;
rlim.rlim_cur = NUM2RLIM(rlim_cur);
rlim.rlim_max = NUM2RLIM(rlim_max);
rlim.rlim_cur = rlimit_resource_value(rlim_cur);
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");
}
return Qnil;

View file

@ -38,4 +38,36 @@ class TestProcess < Test::Unit::TestCase
Process.wait pid
assert_equal(0, $?.to_i, "#{$?}")
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