From 6a3d357ceae266a96599a4bf2454731d774cb61d Mon Sep 17 00:00:00 2001 From: akr Date: Sun, 14 Nov 2004 10:06:16 +0000 Subject: * 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: http://svn.ruby-lang.org/repos/ruby/trunk@7264 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- process.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 149 insertions(+), 1 deletion(-) (limited to 'process.c') diff --git a/process.c b/process.c index 1ed5dd935..68dd92113 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); -- cgit