summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure22
-rw-r--r--sysif.c36
-rw-r--r--txr.144
3 files changed, 90 insertions, 12 deletions
diff --git a/configure b/configure
index 1518af29..e0759ab1 100755
--- a/configure
+++ b/configure
@@ -2193,6 +2193,28 @@ else
printf "no\n"
fi
+printf "Checking for setgroups ... "
+
+cat > conftest.c <<!
+#include <sys/types.h>
+#include <unistd.h>
+#include <grp.h>
+
+int main(int argc, char **argv)
+{
+ int res = setgroups(0, 0);
+ return 0;
+}
+!
+
+if conftest ; then
+ printf "yes\n"
+ printf "#define HAVE_SETGROUPS 1\n" >> $config_h
+ have_unistd=y
+else
+ printf "no\n"
+fi
+
printf "Checking for old school getpwent, getpwuid and getpwnam ... "
cat > conftest.c <<!
diff --git a/sysif.c b/sysif.c
index a3fdbb69..bc0dc822 100644
--- a/sysif.c
+++ b/sysif.c
@@ -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));
diff --git a/txr.1 b/txr.1
index 7bf7052a..85e24742 100644
--- a/txr.1
+++ b/txr.1
@@ -36954,6 +36954,23 @@ of the same name. They retrieve the real user ID, effective user ID,
real group ID and effective group ID, respectively, of the calling
process.
+.coNP Functions @, setuid @, seteuid @ setgid and @ setegid
+.synb
+.mets (setuid << uid )
+.mets (seteuid << uid )
+.mets (setgid << gid )
+.mets (setegid << gid )
+.syne
+.desc
+These functions directly correspond to the POSIX C library functions
+of the same name. They set the real user ID, effective user ID,
+real group ID and effective group ID, respectively, of the calling
+process.
+On success, they return
+.codn t .
+On failure, they throw an exception of type
+.codn system-error .
+
.coNP Function @ getgroups
.synb
.mets (getgroups)
@@ -36969,21 +36986,24 @@ Whether or not the effective group ID retrieved by
is included in this list is system-dependent. Programs should not
depend on its presence or absence.
-.coNP Functions @, setuid @, seteuid @ setgid and @ setegid
+.coNP Function @ setgroups
.synb
-.mets (setuid << uid )
-.mets (seteuid << uid )
-.mets (setgid << gid )
-.mets (setegid << gid )
+.mets (setgroups << gid-list )
.syne
.desc
-These functions directly correspond to the POSIX C library functions
-of the same name. They set the real user ID, effective user ID,
-real group ID and effective group ID, respectively, of the calling
-process.
-On success, they return
-.codn t .
-On failure, they throw an exception of type
+The
+.code setgroups
+function corresponds to a C library function found in some Unix
+operating systems, complementary to the
+.code getgroups
+function. The argument to
+.meta gid-list
+must be a list of numeric group IDs.
+If the function is successful, this list is installed as the list of
+supplementary group IDs of the calling process, and the value
+.code t
+is returned.
+On failure, it throws an exception of type
.codn system-error .
.SS* Unix Password Database