[1/2] posix/group_member: Add group_member2 with error return.

Message ID 20231012153508.2057768-2-josimmon@redhat.com
State Superseded
Headers
Series posix: Add group_member2 and deprecate group_member |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 fail Testing failed
linaro-tcwg-bot/tcwg_glibc_check--master-arm fail Testing failed

Commit Message

Joe Simmons-Talbott Oct. 12, 2023, 3:34 p.m. UTC
  Because group_member doesn't return an error status and we are trying to
get rid of alloca usage.  Add a new group_member2 which returns -1 and
sets errno on error.  The old group_member will be deprecated in a later
change.
---
 include/unistd.h          |  1 +
 posix/Makefile            |  1 +
 posix/group_member.c      | 32 +++++++++++++++++++++++++++++
 posix/tst-group_member2.c | 42 +++++++++++++++++++++++++++++++++++++++
 posix/unistd.h            |  3 +++
 5 files changed, 79 insertions(+)
 create mode 100644 posix/tst-group_member2.c
  

Patch

diff --git a/include/unistd.h b/include/unistd.h
index e241603b81..39d5bda372 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -131,6 +131,7 @@  extern __gid_t __getegid (void) attribute_hidden;
 extern int __getgroups (int __size, __gid_t __list[]) attribute_hidden;
 libc_hidden_proto (__getpgid)
 extern int __group_member (__gid_t __gid) attribute_hidden;
+extern int __group_member2 (__gid_t __gid) attribute_hidden;
 extern int __setuid (__uid_t __uid);
 extern int __setreuid (__uid_t __ruid, __uid_t __euid);
 extern int __setgid (__gid_t __gid);
diff --git a/posix/Makefile b/posix/Makefile
index c36b9d981e..b46ff3259c 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -294,6 +294,7 @@  tests := \
   tst-glob_symlinks \
   tst-gnuglob \
   tst-gnuglob64 \
+  tst-group_member2 \
   tst-mmap \
   tst-mmap-offset \
   tst-nanosleep \
diff --git a/posix/group_member.c b/posix/group_member.c
index 22422b1f9f..6064eb7264 100644
--- a/posix/group_member.c
+++ b/posix/group_member.c
@@ -16,6 +16,8 @@ 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <errno.h>
+#include <scratch_buffer.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -47,3 +49,33 @@  __group_member (gid_t gid)
   return 0;
 }
 weak_alias (__group_member, group_member)
+
+int
+__group_member2 (gid_t gid)
+{
+  int n;
+  gid_t *groups;
+  struct scratch_buffer buf;
+  scratch_buffer_init (&buf);
+
+  n = __getgroups (0, NULL);
+  if (!scratch_buffer_set_array_size (&buf, n, sizeof (*groups)))
+    {
+      errno = ENOMEM;
+      return -1;
+    }
+  groups = buf.data;
+
+  n = __getgroups (n, groups);
+
+  while (n-- > 0)
+    if (groups[n] == gid)
+      {
+        scratch_buffer_free (&buf);
+        return 1;
+      }
+
+  scratch_buffer_free (&buf);
+  return 0;
+}
+weak_alias (__group_member2, group_member2)
diff --git a/posix/tst-group_member2.c b/posix/tst-group_member2.c
new file mode 100644
index 0000000000..4a360c71da
--- /dev/null
+++ b/posix/tst-group_member2.c
@@ -0,0 +1,42 @@ 
+/* Basic tests for group_memmber2.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <alloca.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <support/check.h>
+
+static int do_test (void)
+{
+  int n;
+  gid_t *groups;
+
+  n = getgroups (0, NULL);
+  groups = alloca (n * sizeof (*groups));
+  n = getgroups (n, groups);
+
+  while (n-- > 0)
+    TEST_COMPARE (1, group_member2 (groups[n]));
+
+  return EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
+
diff --git a/posix/unistd.h b/posix/unistd.h
index 0477527a60..96816b186d 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -713,6 +713,9 @@  extern int getgroups (int __size, __gid_t __list[]) __THROW __wur
 #ifdef	__USE_GNU
 /* Return nonzero iff the calling process is in group GID.  */
 extern int group_member (__gid_t __gid) __THROW;
+/* Return nonzero iff the calling process is in group GID.  Return
+   -1 on error and set errno.  */
+extern int group_member2 (__gid_t __gid) __THROW;
 #endif
 
 /* Set the user ID of the calling process to UID.