Simplify our trivial initgroups(), and add a test.

initgroups() is just a call to getgrouplist() followed by a call to
setgroups(). The tricky part is memory allocation. OpenBSD allocates an
NGROUPS_MAX-sized array of gid_t on the stack. FreeBSD allocates a
sysconf(_SC_NGROUPS_MAX)-sized array of gid_t on the heap. bionic had a
mix where it would try a 2-element stack array but fall back to a heap
allocation, which sounds reasonable if you want to avoid a 256KiB
(64Ki*4 bytes) allocation on either stack or heap. But that constant 2?
That's weird in two ways... It's really small (musl has an NGROUPS_MAX
of 32 unlike the Linux kernel's 64Ki, but 32 is still a lot larger than
2), but at the same time it's too big --- bionic's getgrouplist() always
returns a single element.

So although the FreeBSD "what the hell, let's just allocate 256KiB on
the heap" implementation would have been fine, there's really no point,
and anyone who's trying to understand initgroups() on Android really
needs to read getgroupslist() anyway, so let's just have the most
trivial implementation -- a single-element array -- and let's have it
right next to getgroupslist() in the same file as all the other <grp.h>
functions.

Also add a trivial smoke test. You mostly won't have permission to do
anything interesting with initgroups(), and it's basically unused save
for privilege dropping tcpdump and strace, but we may as well make an
effort. (I tested tcpdump before and after too.)

Test: treehugger
Change-Id: I67fe02e309ed1dbefc490c01733738363ca606be
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index 600693c..82ee7ba 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -609,6 +609,8 @@
 }
 
 // All users are in just one group, the one passed in.
+// In practice, id(1) will show you in a lot more groups, because adbd
+// adds you to a lot of supplementary groups when dropping privileges.
 int getgrouplist(const char* /*user*/, gid_t group, gid_t* groups, int* ngroups) {
   if (*ngroups < 1) {
     *ngroups = 1;
@@ -618,6 +620,12 @@
   return (*ngroups = 1);
 }
 
+// See getgrouplist() to understand why we don't call it.
+int initgroups(const char* /*user*/, gid_t group) {
+  gid_t groups[] = {group};
+  return setgroups(1, groups);
+}
+
 char* getlogin() { // NOLINT: implementing bad function.
   passwd *pw = getpwuid(getuid()); // NOLINT: implementing bad function in terms of bad function.
   return pw ? pw->pw_name : nullptr;