diff options
-rw-r--r-- | stdlib/doc-syms.tl | 6 | ||||
-rw-r--r-- | sysif.c | 69 | ||||
-rw-r--r-- | sysif.h | 4 | ||||
-rw-r--r-- | txr.1 | 92 |
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") @@ -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 } @@ -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); @@ -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 |