Implement getgroups
This commit is contained in:
@@ -611,10 +611,52 @@ impl Pal for Sys {
|
||||
redox_rt::sys::posix_getresugid().rgid as gid_t
|
||||
}
|
||||
|
||||
fn getgroups(list: Out<[gid_t]>) -> Result<c_int> {
|
||||
// TODO
|
||||
todo_skip!(0, "getgroups({}, {:p}): not implemented", list.len(), list);
|
||||
Err(Errno(ENOSYS))
|
||||
fn getgroups(mut list: Out<[gid_t]>) -> Result<c_int> {
|
||||
// FIXME: this operation doesn't scale when group/passwd file grows
|
||||
|
||||
let uid = Self::geteuid();
|
||||
let pwd = crate::header::pwd::getpwuid(uid);
|
||||
|
||||
if pwd.is_null() {
|
||||
return Err(Errno(ENOENT));
|
||||
}
|
||||
|
||||
let username = unsafe { CStr::from_ptr((*pwd).pw_name) };
|
||||
let username = username.to_bytes_with_nul();
|
||||
let mut count = 0;
|
||||
|
||||
unsafe {
|
||||
use crate::header::grp;
|
||||
grp::setgrent();
|
||||
|
||||
while let Some(grp) = grp::getgrent().as_ref() {
|
||||
let mut i = 0;
|
||||
let mut found = false;
|
||||
|
||||
while !(*grp.gr_mem.offset(i)).is_null() {
|
||||
let member = CStr::from_ptr(*grp.gr_mem.offset(i));
|
||||
if member.to_bytes_with_nul() == username {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if found {
|
||||
if !list.is_empty() && (count as usize) < list.len() {
|
||||
list.index(count).write(grp.gr_gid);
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
grp::endgrent();
|
||||
}
|
||||
|
||||
if !list.is_empty() && (count as usize) > list.len() {
|
||||
return Err(Errno(EINVAL));
|
||||
}
|
||||
|
||||
Ok(count as i32)
|
||||
}
|
||||
|
||||
fn getpagesize() -> usize {
|
||||
|
||||
@@ -305,6 +305,7 @@ VARIED_NAMES=\
|
||||
pthread/timeout \
|
||||
pthread/tls \
|
||||
grp/getgrouplist \
|
||||
grp/getgroups \
|
||||
grp/getgrgid_r \
|
||||
grp/getgrnam_r \
|
||||
grp/gr_iter \
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <grp.h>
|
||||
|
||||
int main() {
|
||||
gid_t primary_gid = getegid();
|
||||
struct group *pg = getgrgid(primary_gid);
|
||||
|
||||
printf("getegid: %u (%s)\n", primary_gid, pg ? pg->gr_name : "?");
|
||||
|
||||
int count = getgroups(0, NULL);
|
||||
gid_t *list = malloc(sizeof(gid_t) * count);
|
||||
getgroups(count, list);
|
||||
|
||||
printf("getgroups: %d\n", count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
struct group *sg = getgrgid(list[i]);
|
||||
|
||||
printf(" - %u (%s)\n", list[i], sg ? sg->gr_name : "?");
|
||||
}
|
||||
|
||||
free(list);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user