[前][次][番号順一覧][スレッド一覧]

ruby-changes:4089

From: ko1@a...
Date: Sat, 23 Feb 2008 01:12:54 +0900 (JST)
Subject: [ruby-changes:4089] akr - Ruby:r15579 (trunk): * process.c (rlimit_resource_type): new function.

akr	2008-02-23 01:12:32 +0900 (Sat, 23 Feb 2008)

  New Revision: 15579

  Modified files:
    trunk/ChangeLog
    trunk/process.c
    trunk/test/ruby/test_process.rb

  Log:
    * 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.


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/test/ruby/test_process.rb?r1=15579&r2=15578&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=15579&r2=15578&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/process.c?r1=15579&r2=15578&diff_format=u

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 15578)
+++ ChangeLog	(revision 15579)
@@ -1,3 +1,12 @@
+Sat Feb 23 01:09:47 2008  Tanaka Akira  <akr@f...>
+
+	* 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@r...>
 
 	* string.c (rb_enc_cr_str_copy): check string's coderange is 7bit or
Index: process.c
===================================================================
--- process.c	(revision 15578)
+++ process.c	(revision 15579)
@@ -2102,6 +2102,133 @@
 # 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 @@
  *  _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 @@
 
     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 @@
  *  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 @@
     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;
Index: test/ruby/test_process.rb
===================================================================
--- test/ruby/test_process.rb	(revision 15578)
+++ test/ruby/test_process.rb	(revision 15579)
@@ -38,4 +38,36 @@
     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

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]