summaryrefslogtreecommitdiffstats
path: root/sysif.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-07-13 07:59:19 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-07-13 07:59:19 -0700
commit753b4a6d7eac7d7f0d46eab124df0aca80431f74 (patch)
tree56acb3e9bc6ba8754f49e56a0a2c3661d24904ae /sysif.c
parent3656ba07ccf49eb25cf3b1f30298de9b2c0955d4 (diff)
downloadtxr-753b4a6d7eac7d7f0d46eab124df0aca80431f74.tar.gz
txr-753b4a6d7eac7d7f0d46eab124df0aca80431f74.tar.bz2
txr-753b4a6d7eac7d7f0d46eab124df0aca80431f74.zip
New functions: getrlimit, setrlimit.
* stdlib/doc-syms.tl: Updated. * sysif.c (rlim_s, cur_s, max_s): New symbol variables. (rlim_st): New variable. (getrlimit_wrap, setrlimit_wrap): New functions. (sysif_init): gc-protect rlim-st. Initialize symbol vsariables. Create rlim struct type. Register getrlimit and setrlimit intrinsics. Register variables rlim-saved-max, rlim-saved-cur, rlim-infinity, rlimit-core, rlimit-cpu, rlimit-data, rlimit-fsize, rlimit-nofile, rlimit-stack and rlimit-as. * txr.1: Documented under new Unix Resource Limits section.
Diffstat (limited to 'sysif.c')
-rw-r--r--sysif.c69
1 files changed, 68 insertions, 1 deletions
diff --git a/sysif.c b/sysif.c
index ca393083..0cd8c8f3 100644
--- a/sysif.c
+++ b/sysif.c
@@ -88,6 +88,9 @@
#if HAVE_UTIME
#include <utime.h>
#endif
+#if HAVE_RLIMIT
+#include <sys/resource.h>
+#endif
#include "alloca.h"
#include "lib.h"
#include "stream.h"
@@ -149,6 +152,11 @@ val flock_s, type_s, whence_s, start_s, len_s, pid_s;
val dlhandle_s, dlsym_s;
#endif
+#if HAVE_RLIMIT
+val rlim_s, cur_s, max_s;
+static val rlim_st;
+#endif
+
struct cobj_class *dir_cls;
static val at_exit_list;
@@ -2446,9 +2454,47 @@ static val dirstat(val dirent, val dir_path, val stat_opt)
return stat;
}
+#if HAVE_RLIMIT
+val getrlimit_wrap(val resource, val rlim_opt)
+{
+ val self = lit("getrlimit");
+ struct rlimit rl;
+ val rlim = rlim_opt;
+ int res = getrlimit(c_int(resource, self), &rl);
+
+ if (res != 0)
+ uw_throwf(system_error_s, lit("~a failed for ~a: ~d/~s"),
+ self, resource, num(errno), errno_to_str(errno), nao);
+
+ if (missingp(rlim)) {
+ args_decl(args, ARGS_MIN);
+ rlim = make_struct(rlim_st, nil, args);
+ }
+
+ slotset(rlim, cur_s, unum(rl.rlim_cur));
+ slotset(rlim, max_s, unum(rl.rlim_max));
+ return rlim;
+}
+
+val setrlimit_wrap(val resource, val rlim)
+{
+ val self = lit("setrlimit");
+ struct rlimit rl;
+ rl.rlim_cur = c_unum(slot(rlim, cur_s), self);
+ rl.rlim_max = c_unum(slot(rlim, max_s), self);
+ int res = setrlimit(c_int(resource, self), &rl);
+
+ if (res != 0)
+ uw_throwf(system_error_s, lit("~a failed for ~a: ~d/~s"),
+ self, resource, num(errno), errno_to_str(errno), nao);
+
+ return t;
+}
+#endif
+
void sysif_init(void)
{
- protect(&at_exit_list, &dirent_st, &env_list, &env_hash, convert(val *, 0));
+ protect(&at_exit_list, &dirent_st, &rlim_st, &env_list, &env_hash, convert(val *, 0));
atexit(at_exit_handler);
@@ -3048,4 +3094,25 @@ void sysif_init(void)
reg_varl(intern(lit("dt-reg"), user_package), num_fast(DT_REG));
reg_varl(intern(lit("dt-lnk"), user_package), num_fast(DT_LNK));
reg_varl(intern(lit("dt-sock"), user_package), num_fast(DT_SOCK));
+
+#if HAVE_RLIMIT
+ rlim_s = intern(lit("rlim"), user_package);
+ cur_s = intern(lit("cur"), user_package);
+ max_s = intern(lit("max"), user_package);
+ rlim_st = make_struct_type(rlim_s, nil, nil,
+ list(cur_s, max_s, nao),
+ nil, nil, nil, nil);
+ reg_fun(intern(lit("getrlimit"), user_package), func_n2o(getrlimit_wrap, 1));
+ reg_fun(intern(lit("setrlimit"), user_package), func_n2(setrlimit_wrap));
+ reg_varl(intern(lit("rlim-saved-max"), user_package), num_fast(RLIM_SAVED_MAX));
+ reg_varl(intern(lit("rlim-saved-cur"), user_package), num_fast(RLIM_SAVED_CUR));
+ reg_varl(intern(lit("rlim-infinity"), user_package), num_fast(RLIM_INFINITY));
+ reg_varl(intern(lit("rlimit-core"), user_package), num_fast(RLIMIT_CORE));
+ reg_varl(intern(lit("rlimit-cpu"), user_package), num_fast(RLIMIT_CPU));
+ reg_varl(intern(lit("rlimit-data"), user_package), num_fast(RLIMIT_DATA));
+ reg_varl(intern(lit("rlimit-fsize"), user_package), num_fast(RLIMIT_FSIZE));
+ reg_varl(intern(lit("rlimit-nofile"), user_package), num_fast(RLIMIT_NOFILE));
+ reg_varl(intern(lit("rlimit-stack"), user_package), num_fast(RLIMIT_STACK));
+ reg_varl(intern(lit("rlimit-as"), user_package), num_fast(RLIMIT_AS));
+#endif
}