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:
parent
7b218308e0
commit
310735aa4a
3 changed files with 202 additions and 24 deletions
|
@ -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
185
process.c
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue