diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-05-01 18:54:03 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-05-01 18:54:03 -0700 |
commit | 9bbc744c3b5e0584ad7c9abe244128572a692229 (patch) | |
tree | dc82317dbb71798d60bb637fe8ae53ce651d13b4 /sysif.c | |
parent | 9c6d6519236f536efcd284f714e6f3f145767a57 (diff) | |
download | txr-9bbc744c3b5e0584ad7c9abe244128572a692229.tar.gz txr-9bbc744c3b5e0584ad7c9abe244128572a692229.tar.bz2 txr-9bbc744c3b5e0584ad7c9abe244128572a692229.zip |
Adding setgroups function.
* configure: Test for setgroups. New HAVE_SETGROUPS
preprocessor symbol for config/config.h.
* sysif.c (setgroups_wrap): New static function.
(sysif_init): Register intrinsic setgroups function.
* txr.1: Documented setgroups. Rearranged sections
so getgroups and setgroups descriptions are consecutive.
Diffstat (limited to 'sysif.c')
-rw-r--r-- | sysif.c | 36 |
1 files changed, 36 insertions, 0 deletions
@@ -946,6 +946,38 @@ void simulate_setuid(val open_script) #endif +#if HAVE_SETGROUPS + +static val setgroups_wrap(val list) +{ + cnum len = c_num(length(list)); + size_t size = len; + + if ((cnum) size != len) { + uw_throwf(system_error_s, lit("setgroups: list too long"), nao); + } else { + gid_t *arr = coerce(gid_t *, chk_malloc(size *sizeof *arr)); + int i = 0, res; + + for (; list; i++, list = cdr(list)) { + cnum gid = c_num(car(list)); + arr[i] = gid; + } + + res = setgroups(size, arr); + + free(arr); + + if (res != 0) + uw_throwf(system_error_s, lit("setgroups failed: ~d/~s"), + num(errno), string_utf8(strerror(errno)), nao); + + return t; + } +} + +#endif + #if HAVE_PWUID static val setpwent_wrap(void) @@ -1506,6 +1538,10 @@ void sysif_init(void) reg_fun(intern(lit("setegid"), user_package), func_n1(setegid_wrap)); #endif +#if HAVE_SETGROUPS + reg_fun(intern(lit("setgroups"), user_package), func_n1(setgroups_wrap)); +#endif + #if HAVE_PWUID reg_fun(intern(lit("setpwent"), user_package), func_n0(setpwent_wrap)); reg_fun(intern(lit("endpwent"), user_package), func_n0(endpwent_wrap)); |