summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--stdlib/doc-syms.tl6
-rw-r--r--sysif.c69
-rw-r--r--sysif.h4
-rw-r--r--txr.192
4 files changed, 170 insertions, 1 deletions
diff --git a/stdlib/doc-syms.tl b/stdlib/doc-syms.tl
index 0d69f2a2..47581464 100644
--- a/stdlib/doc-syms.tl
+++ b/stdlib/doc-syms.tl
@@ -883,6 +883,7 @@
("getpwuid" "N-03E528C6")
("getresgid" "N-03D37234")
("getresuid" "N-03D37234")
+ ("getrlimit" "N-03AB0CF0")
("getuid" "N-00125C22")
("gid-t" "N-01D716FE")
("ginterate" "N-02F671F4")
@@ -1550,6 +1551,10 @@
("rlcp" "N-024EB211")
("rlcp-tree" "N-024EB211")
("rlet" "N-008212A0")
+ ("rlim" "N-0178F77B")
+ ("rlim-infinity" "N-01548AE6")
+ ("rlim-saved-cur" "N-01548AE6")
+ ("rlim-saved-max" "N-01548AE6")
("rlist" "N-02FD60D0")
("rlist*" "N-02FD60D0")
("rmdir" "N-03D90503")
@@ -1643,6 +1648,7 @@
("setpwent" "N-0377C43A")
("setresgid" "N-027671E8")
("setresuid" "N-027671E8")
+ ("setrlimit" "N-03AB0CF0")
("setuid" "N-03897D65")
("seventh" "N-01B0FA33")
("sh" "N-0158244A")
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
}
diff --git a/sysif.h b/sysif.h
index 811f76a0..d42238c8 100644
--- a/sysif.h
+++ b/sysif.h
@@ -67,4 +67,8 @@ INLINE void simulate_setuid_setgid(val open_script) { }
#if HAVE_UNISTD_H
val getcwd_wrap(void);
#endif
+#if HAVE_RLIMIT
+val getrlimit_wrap(val resource, val rlim_opt);
+val setrlimit_wrap(val resource, val rlim);
+#endif
void sysif_init(void);
diff --git a/txr.1 b/txr.1
index 10b4e71a..4daf8073 100644
--- a/txr.1
+++ b/txr.1
@@ -71479,6 +71479,98 @@ slot of the returned
structure will have the value
.codn nil .
+.SS* Unix Resource Limits
+
+.coNP Structure @ rlim
+.synb
+.mets (defstruct rlim nil
+.mets \ \ cur max)
+.syne
+.desc
+The
+.code rlim
+structure is required by the functions
+.code getrlimit
+and
+.codn setrlimit .
+It is analogous to the C structure by the same name described in POSIX.
+
+.coNP Variables @, rlim-saved-max @ rlim-saved-cur and @ rlim-infinity
+.desc
+These variables correspond to the POSIX constants
+.codn RLIM_SAVED_MAX ,
+.code RLIM_SAVED_CUR
+and
+.codn RLIM_INFINITY .
+They have the same values, and are suitable as slot values of the
+.code rlim
+structure.
+
+Variables @, rlimit-core @, rlimit-cpu @, rlimit-data @, rlimit-fsize @, rlimit-nofile @ rlimit-stack and @ rlimit-as
+.desc
+These variables correspond to the POSIX constants
+.codn RLIMIT_CORE ,
+.codn RLIMIT_CPU ,
+.code RLIMIT_DATA
+and so forth.
+
+.coNP Functions @ getrlimit and @ setrlimit
+.synb
+.mets (getrlimit < resource <> [ rlim ])
+.mets (setrlimit < resource << rlim )
+.syne
+.desc
+The
+.code getrlimit
+function retrieves information about the limits imposed for a particular parameter indicated by the
+.meta resource
+integer.
+
+The
+.code setrlimit
+function changes the limit information for a resource parameter.
+
+The
+.meta resource
+parameter is the value of one of the variables
+.codn rlimit-core ,
+.codn rlimit-cpu ,
+.code rlimit-data
+and so forth.
+
+The
+.meta rlim
+argument is a structure of type
+.codn rlim .
+If this argument is given to the
+.code getrlimit
+function, then it fills in that structure with the retrieved
+parameters. Otherwise it allocates a new structure and fills
+that one. In either situation, the filled structure is returned,
+if the underlying call to the host operating system is successful.
+
+In the case of
+.codn setrlimit ,
+the
+.code rlim
+object must have non-negative integer values which are in the range
+of the platform's
+.code rlim_t
+type.
+
+If the underlying system call fails, then these functions throw
+an exception. In the successful case, the
+.code getrlimit
+function returns the
+.code rlim
+structure, and
+.code setrlimit
+returns
+.codn t .
+
+Further information about resource limits is available in the POSIX standard
+and platform documentation.
+
.SS* Web Programming Support
.coNP Functions @ url-encode and @ url-decode