summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport/src/getgroups.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-11-17 07:53:01 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-11-20 10:30:22 +0100
commitffa71f1cd0af6682aca1da3b05fed02f64ec7e5b (patch)
tree76fb95010a2698dfff7185b96045587ce9b45ff7 /cpukit/libcsupport/src/getgroups.c
parentlibcsupport: Use POSIX key for getgrent() (diff)
downloadrtems-ffa71f1cd0af6682aca1da3b05fed02f64ec7e5b.tar.bz2
libcsupport: Implement getgroups()
Diffstat (limited to 'cpukit/libcsupport/src/getgroups.c')
-rw-r--r--cpukit/libcsupport/src/getgroups.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/cpukit/libcsupport/src/getgroups.c b/cpukit/libcsupport/src/getgroups.c
index 6bf58a70fe..73a42cee1f 100644
--- a/cpukit/libcsupport/src/getgroups.c
+++ b/cpukit/libcsupport/src/getgroups.c
@@ -10,15 +10,66 @@
#endif
#include <sys/types.h>
+#include <grp.h>
+#include <pwd.h>
+#include <string.h>
#include <unistd.h>
+#include <rtems/seterr.h>
+
/**
* 4.2.3 Get Supplementary IDs, P1003.1b-1993, p. 86
*/
int getgroups(
- int gidsetsize __attribute__((unused)),
- gid_t grouplist[] __attribute__((unused))
+ int gidsetsize,
+ gid_t grouplist[]
)
{
- return 0; /* no supplemental group ids */
+ int rv;
+ struct passwd pwd;
+ struct passwd *pwd_res;
+ char buf[256];
+ gid_t gid;
+ const char *user;
+ struct group *grp;
+
+ rv = getpwuid_r(getuid(), &pwd, &buf[0], sizeof(buf), &pwd_res);
+ if (rv != 0) {
+ return rv;
+ }
+
+ gid = pwd.pw_gid;
+ user = pwd.pw_name;
+
+ setgrent();
+
+ while ((grp = getgrent()) != NULL) {
+ char **mem = &grp->gr_mem[0];
+
+ if (grp->gr_gid == gid) {
+ continue;
+ }
+
+ while (*mem != NULL) {
+ if (strcmp(*mem, user) == 0) {
+ if (rv < gidsetsize) {
+ grouplist[rv] = grp->gr_gid;
+ }
+
+ ++rv;
+
+ break;
+ }
+
+ ++mem;
+ }
+ }
+
+ endgrent();
+
+ if (gidsetsize == 0 || rv <= gidsetsize) {
+ return rv;
+ } else {
+ rtems_set_errno_and_return_minus_one(EINVAL);
+ }
}