From 8f1c92af4f90b4817eebcaa7c1e75747a90cfb50 Mon Sep 17 00:00:00 2001 From: akr Date: Sun, 14 Nov 2004 10:06:16 +0000 Subject: [PATCH] * process.c (proc_getrlimit): new function for Process.getrlimit. (proc_setrlimit): new function for Process.setrlimit. [ruby-dev:24834] * configure.in: check rlim_t and its size. check setrlimit. * ruby.h (NUM2ULL): new macro. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7264 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 10 ++++ configure.in | 9 +++- process.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++- ruby.h | 1 + 4 files changed, 168 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 334a1db6ce..71822551d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Sun Nov 14 18:59:03 2004 Tanaka Akira + + * process.c (proc_getrlimit): new function for Process.getrlimit. + (proc_setrlimit): new function for Process.setrlimit. + [ruby-dev:24834] + + * configure.in: check rlim_t and its size. check setrlimit. + + * ruby.h (NUM2ULL): new macro. + Sun Nov 14 13:27:03 2004 Nobuyoshi Nakada * lib/pp.rb (PP#object_address_group): remove odd number of 'f' diff --git a/configure.in b/configure.in index bc69979302..3dfe9e79db 100644 --- a/configure.in +++ b/configure.in @@ -205,6 +205,12 @@ AC_CHECK_SIZEOF(float, 4) AC_CHECK_SIZEOF(double, 8) AC_CHECK_SIZEOF(time_t, 0) +AC_CHECK_TYPE(rlim_t, [AC_DEFINE(HAVE_RLIM_T)], [], [#include ]) +AC_CHECK_SIZEOF(rlim_t, 0, [ + #include + #include +]) + AC_CACHE_CHECK(for prototypes, rb_cv_have_prototypes, [AC_TRY_COMPILE([int foo(int x) { return 0; }], [return foo(10);], rb_cv_have_prototypes=yes, @@ -416,7 +422,8 @@ AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot fsync getcwd setitimer setruid seteuid setreuid setresuid setproctitle\ setrgid setegid setregid setresgid issetugid pause lchown lchmod\ getpgrp setpgrp getpgid setpgid initgroups getgroups setgroups\ - getpriority getrlimit dlopen sigprocmask sigaction _setjmp\ + getpriority getrlimit setrlimit\ + dlopen sigprocmask sigaction _setjmp\ setsid telldir seekdir fchmod mktime timegm cosh sinh tanh\ setuid setgid daemon) AC_ARG_ENABLE(setreuid, diff --git a/process.c b/process.c index 1ed5dd935a..68dd92113c 100644 --- a/process.c +++ b/process.c @@ -45,7 +45,7 @@ struct timeval rb_time_interval _((VALUE)); #ifdef HAVE_SYS_WAIT_H # include #endif -#ifdef HAVE_GETPRIORITY +#ifdef HAVE_SYS_RESOURCE_H # include #endif #include "st.h" @@ -1931,6 +1931,103 @@ proc_setpriority(obj, which, who, prio) #endif } +#ifdef HAVE_RLIM_T +#if SIZEOF_RLIM_T == SIZEOF_INT +# define RLIM2NUM(v) UINT2NUM(v) +# define NUM2RLIM(v) NUM2UINT(v) +#elif SIZEOF_RLIM_T == SIZEOF_LONG +# define RLIM2NUM(v) ULONG2NUM(v) +# define NUM2RLIM(v) NUM2ULONG(v) +#elif SIZEOF_RLIM_T == SIZEOF_LONG_LONG +# define RLIM2NUM(v) ULL2NUM(v) +# define NUM2RLIM(v) NUM2ULL(v) +#else +# error cannot find an integer type which size is same as rlim_t. +#endif +#endif + +/* + * call-seq: + * Process.getrlimit(resource) => [cur_limit, max_limit] + * + * Gets the resource limit of the process. + * _cur_limit_ means current (soft) limit and + * _max_limit_ means maximum (hard) limit. + * + * _resource_ indicates the kind of resource to limit: + * such as Process::RLIMIT_CORE, + * Process::RLIMIT_CPU, etc. + * See Process.setrlimit for details. + * + * _cur_limit_ and _max_limit_ may be Process::RLIM_INFINITY, + * Process::RLIM_SAVED_MAX or + * Process::RLIM_SAVED_CUR. + * See Process.setrlimit and the system getrlimit(2) manual for details. + */ + +static VALUE +proc_getrlimit(VALUE obj, VALUE resource) +{ +#ifdef HAVE_GETRLIMIT + struct rlimit rlim; + + if (getrlimit(NUM2INT(resource), &rlim) < 0) { + rb_sys_fail("getrlimit"); + } + return rb_assoc_new(RLIM2NUM(rlim.rlim_cur), RLIM2NUM(rlim.rlim_max)); +#else + rb_notimplement(); +#endif +} + +/* + * call-seq: + * Process.setrlimit(resource, cur_limit, max_limit) => nil + * + * Sets the resource limit of the process. + * _cur_limit_ means current (soft) limit and + * _max_limit_ means maximum (hard) limit. + * + * _resource_ indicates the kind of resource to limit. + * Although the list of resources are OS dependent, + * SUSv3 defines following resources. + * + * [Process::RLIMIT_CORE] core size (bytes) + * [Process::RLIMIT_CPU] CPU time (seconds) + * [Process::RLIMIT_DATA] data segment (bytes) + * [Process::RLIMIT_FSIZE] file size (bytes) + * [Process::RLIMIT_NOFILE] file descriptors (number) + * [Process::RLIMIT_STACK] stack size (bytes) + * [Process::RLIMIT_AS] total available memory (bytes) + * + * Other Process::RLIMIT_??? constants may be defined. + * + * _cur_limit_ and _max_limit_ may be Process::RLIM_INFINITY, + * which means that the resource is not limited. + * They may be Process::RLIM_SAVED_MAX or + * Process::RLIM_SAVED_CUR too. + * See system setrlimit(2) manual for details. + * + */ + +static VALUE +proc_setrlimit(VALUE obj, VALUE resource, VALUE rlim_cur, VALUE rlim_max) +{ +#ifdef HAVE_SETRLIMIT + struct rlimit rlim; + + rlim.rlim_cur = NUM2RLIM(rlim_cur); + rlim.rlim_max = NUM2RLIM(rlim_max); + + if (setrlimit(NUM2INT(resource), &rlim) < 0) { + rb_sys_fail("setrlimit"); + } + return Qnil; +#else + rb_notimplement(); +#endif +} + static int under_uid_switch = 0; static void check_uid_switch() @@ -3610,6 +3707,57 @@ Init_process() rb_define_const(rb_mProcess, "PRIO_USER", INT2FIX(PRIO_USER)); #endif +#ifdef HAVE_GETRLIMIT + rb_define_module_function(rb_mProcess, "getrlimit", proc_getrlimit, 1); +#endif +#ifdef HAVE_SETRLIMIT + rb_define_module_function(rb_mProcess, "setrlimit", proc_setrlimit, 3); +#endif +#ifdef HAVE_RLIM_T +#ifdef RLIM_INFINITY + rb_define_const(rb_mProcess, "RLIM_INFINITY", RLIM2NUM(RLIM_INFINITY)); +#endif +#ifdef RLIM_SAVED_MAX + rb_define_const(rb_mProcess, "RLIM_SAVED_MAX", RLIM2NUM(RLIM_SAVED_MAX)); +#endif +#ifdef RLIM_SAVED_CUR + rb_define_const(rb_mProcess, "RLIM_SAVED_CUR", RLIM2NUM(RLIM_SAVED_CUR)); +#endif +#ifdef RLIMIT_CORE + rb_define_const(rb_mProcess, "RLIMIT_CORE", INT2FIX(RLIMIT_CORE)); +#endif +#ifdef RLIMIT_CPU + rb_define_const(rb_mProcess, "RLIMIT_CPU", INT2FIX(RLIMIT_CPU)); +#endif +#ifdef RLIMIT_DATA + rb_define_const(rb_mProcess, "RLIMIT_DATA", INT2FIX(RLIMIT_DATA)); +#endif +#ifdef RLIMIT_FSIZE + rb_define_const(rb_mProcess, "RLIMIT_FSIZE", INT2FIX(RLIMIT_FSIZE)); +#endif +#ifdef RLIMIT_NOFILE + rb_define_const(rb_mProcess, "RLIMIT_NOFILE", INT2FIX(RLIMIT_NOFILE)); +#endif +#ifdef RLIMIT_STACK + rb_define_const(rb_mProcess, "RLIMIT_STACK", INT2FIX(RLIMIT_STACK)); +#endif +#ifdef RLIMIT_AS + rb_define_const(rb_mProcess, "RLIMIT_AS", INT2FIX(RLIMIT_AS)); +#endif +#ifdef RLIMIT_MEMLOCK + rb_define_const(rb_mProcess, "RLIMIT_MEMLOCK", INT2FIX(RLIMIT_MEMLOCK)); +#endif +#ifdef RLIMIT_NPROC + rb_define_const(rb_mProcess, "RLIMIT_NPROC", INT2FIX(RLIMIT_NPROC)); +#endif +#ifdef RLIMIT_RSS + rb_define_const(rb_mProcess, "RLIMIT_RSS", INT2FIX(RLIMIT_RSS)); +#endif +#ifdef RLIMIT_SBSIZE + rb_define_const(rb_mProcess, "RLIMIT_SBSIZE", INT2FIX(RLIMIT_SBSIZE)); +#endif +#endif + rb_define_module_function(rb_mProcess, "uid", proc_getuid, 0); rb_define_module_function(rb_mProcess, "uid=", proc_setuid, 1); rb_define_module_function(rb_mProcess, "gid", proc_getgid, 0); diff --git a/ruby.h b/ruby.h index 6bd5097978..383afe9333 100644 --- a/ruby.h +++ b/ruby.h @@ -265,6 +265,7 @@ unsigned long rb_fix2uint _((VALUE)); LONG_LONG rb_num2ll _((VALUE)); unsigned LONG_LONG rb_num2ull _((VALUE)); # define NUM2LL(x) (FIXNUM_P(x)?FIX2LONG(x):rb_num2ll((VALUE)x)) +# define NUM2ULL(x) rb_num2ull((VALUE)x) #endif #if HAVE_LONG_LONG && SIZEOF_OFF_T > SIZEOF_LONG