From 9704481224a199506bfb74702c2b3638081d8474 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sun, 21 Jun 2026 01:48:17 +0800 Subject: [PATCH] libc/unistd: add getgroups() Add getgroups() to the C library. NuttX has no supplementary group IDs, so it reports a single group, the effective group ID, and follows POSIX for the gidsetsize == 0 and short-buffer (EINVAL) cases. Signed-off-by: Xiang Xiao --- Documentation/standards/posix.rst | 2 +- include/unistd.h | 2 + libs/libc/unistd/CMakeLists.txt | 1 + libs/libc/unistd/Make.defs | 2 +- libs/libc/unistd/lib_getgroups.c | 85 +++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 libs/libc/unistd/lib_getgroups.c diff --git a/Documentation/standards/posix.rst b/Documentation/standards/posix.rst index 577abf16ce5..cdca6eb748e 100644 --- a/Documentation/standards/posix.rst +++ b/Documentation/standards/posix.rst @@ -1972,7 +1972,7 @@ User and Group: +--------------------------------+---------+ | :c:func:`getgid` | Yes | +--------------------------------+---------+ -| getgroups() | No | +| :c:func:`getgroups` | Yes | +--------------------------------+---------+ | getlogin() | No | +--------------------------------+---------+ diff --git a/include/unistd.h b/include/unistd.h index 6c7f7d1bcf3..63ded5444ac 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -494,6 +494,8 @@ gid_t getegid(void); int setreuid(uid_t ruid, uid_t euid); int setregid(gid_t rgid, gid_t egid); +int getgroups(int, gid_t[]); + int getentropy(FAR void *buffer, size_t length); void sync(void); diff --git a/libs/libc/unistd/CMakeLists.txt b/libs/libc/unistd/CMakeLists.txt index 797ff8aba9e..eb4ca8e5e93 100644 --- a/libs/libc/unistd/CMakeLists.txt +++ b/libs/libc/unistd/CMakeLists.txt @@ -65,6 +65,7 @@ set(SRCS lib_getpgrp.c lib_getpgid.c lib_getsid.c + lib_getgroups.c lib_setpgid.c lib_setsid.c lib_lockf.c diff --git a/libs/libc/unistd/Make.defs b/libs/libc/unistd/Make.defs index e7852230ad7..e3e5ed3a214 100644 --- a/libs/libc/unistd/Make.defs +++ b/libs/libc/unistd/Make.defs @@ -32,7 +32,7 @@ CSRCS += lib_setrlimit.c lib_getrlimit.c lib_setpriority.c lib_getpriority.c CSRCS += lib_futimes.c lib_lutimes.c lib_gethostname.c lib_sethostname.c CSRCS += lib_fchownat.c lib_linkat.c lib_readlinkat.c lib_symlinkat.c CSRCS += lib_unlinkat.c lib_usleep.c lib_getpgrp.c lib_getpgid.c -CSRCS += lib_getsid.c lib_setpgid.c lib_setsid.c +CSRCS += lib_getsid.c lib_getgroups.c lib_setpgid.c lib_setsid.c CSRCS += lib_lockf.c lib_flock.c lib_getpass.c CSRCS += lib_chdir.c lib_fchdir.c lib_confstr.c lib_ulimit.c diff --git a/libs/libc/unistd/lib_getgroups.c b/libs/libc/unistd/lib_getgroups.c new file mode 100644 index 00000000000..53cbc11ba82 --- /dev/null +++ b/libs/libc/unistd/lib_getgroups.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * libs/libc/unistd/lib_getgroups.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: getgroups + * + * Description: + * The getgroups() function returns the supplementary group IDs of the + * calling process in the array grouplist. NuttX does not support + * supplementary group IDs, so the calling process is treated as belonging + * to a single group: its effective group ID. + * + * Input Parameters: + * gidsetsize - The number of elements available in grouplist. + * grouplist - The buffer used to return the group IDs. + * + * Returned Value: + * On success, the number of group IDs is returned. If gidsetsize is zero, + * the total number of group IDs is returned without modifying grouplist. + * On failure, -1 is returned and errno is set appropriately. + * + ****************************************************************************/ + +int getgroups(int gidsetsize, gid_t grouplist[]) +{ + if (gidsetsize < 0) + { + set_errno(EINVAL); + return -1; + } + + /* If gidsetsize is zero, return the number of group IDs without touching + * grouplist. + */ + + if (gidsetsize == 0) + { + return 1; + } + + if (grouplist == NULL) + { + set_errno(EFAULT); + return -1; + } + + /* NuttX has no notion of supplementary group IDs. Report the single + * effective group ID of the calling process. + */ + + grouplist[0] = getegid(); + return 1; +}