diff --git a/libc/calls/getgroups.c b/libc/calls/getgroups.c index 1e052bf7e..e69f5f642 100644 --- a/libc/calls/getgroups.c +++ b/libc/calls/getgroups.c @@ -25,7 +25,7 @@ #include "libc/sysv/errfuns.h" /** - * Get list of supplementary group IDs + * Gets list of supplementary group IDs * * @param size - maximum number of items that can be stored in list * @param list - buffer to store output gid_t diff --git a/libc/calls/setgroups.c b/libc/calls/setgroups.c index fb9b9cb69..ace1f08d1 100644 --- a/libc/calls/setgroups.c +++ b/libc/calls/setgroups.c @@ -25,10 +25,16 @@ #include "libc/sysv/errfuns.h" /** - * Set list of supplementary group IDs + * Sets list of supplementary group IDs. * - * @param size - number of items in list - * @param list - input set of gid_t to set + * On recent versions of Linux only, it's possible to say: + * + * setgroups(0, NULL); + * + * Which will cause subsequent calls to `EPERM`. + * + * @param size number of items in list + * @param list input set of gid_t to set * @return -1 w/ EFAULT */ int setgroups(size_t size, const uint32_t list[]) { diff --git a/test/libc/calls/getgroups_test.c b/test/libc/calls/getgroups_test.c index 8ad5dd08e..82c7d3a04 100644 --- a/test/libc/calls/getgroups_test.c +++ b/test/libc/calls/getgroups_test.c @@ -18,30 +18,14 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/dce.h" -#include "libc/errno.h" +#include "libc/macros.internal.h" #include "libc/testlib/testlib.h" TEST(getgroups, test) { - int rc; - uint32_t res[1000]; - rc = getgroups(0, NULL); - if (IsLinux() || IsNetbsd() || IsOpenbsd() || IsFreebsd() || IsXnu()) { - EXPECT_NE(-1, rc); - EXPECT_NE(-1, getgroups(sizeof(res) / sizeof(res[0]), res)); - } else { - EXPECT_EQ(-1, rc); - EXPECT_EQ(ENOSYS, errno); - } -} - -TEST(setgroups, test) { - int rc; - uint32_t src[5]; - EXPECT_EQ(-1, setgroups(0, NULL)); - if (IsLinux() || IsNetbsd() || IsOpenbsd() || IsFreebsd() || IsXnu()) { - EXPECT_EQ(EPERM, errno); - EXPECT_EQ(-1, setgroups(sizeof(src) / sizeof(src[0]), src)); - } else { - EXPECT_EQ(ENOSYS, errno); - } + int n; + if (IsWindows()) return; + uint32_t G[500]; + EXPECT_GT((n = getgroups(ARRAYLEN(G), G)), 0); + if (getuid()) return; // this needs root + EXPECT_SYS(0, 0, setgroups(n, G)); }