LibCore: Add syscall wrapper for getgroups()

This wrapper does all the grunt work of figuring out how many extra GIDs
there are, and then returning them nicely wrapped in a Vector<gid_t>.
This commit is contained in:
Andreas Kling 2022-01-01 16:19:51 +01:00
parent f95fc91e4f
commit 1e4117f1e1
2 changed files with 17 additions and 2 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021-2022, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, Kenneth Myhra <kennethmyhra@gmail.com>
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
*
@ -7,6 +7,7 @@
*/
#include <AK/String.h>
#include <AK/Vector.h>
#include <LibCore/System.h>
#include <LibSystem/syscall.h>
#include <stdarg.h>
@ -742,4 +743,18 @@ ErrorOr<Array<int, 2>> pipe2([[maybe_unused]] int flags)
return fds;
}
ErrorOr<Vector<gid_t>> getgroups()
{
int count = ::getgroups(0, nullptr);
if (count < 0)
return Error::from_syscall("getgroups"sv, -errno);
if (count == 0)
return Vector<gid_t> {};
Vector<gid_t> groups;
TRY(groups.try_resize(count));
if (::getgroups(count, groups.data()) < 0)
return Error::from_syscall("getgroups"sv, -errno);
return groups;
}
}

View file

@ -105,5 +105,5 @@ ErrorOr<void> setsockopt(int sockfd, int level, int option, void const* value, s
ErrorOr<void> getsockname(int sockfd, struct sockaddr*, socklen_t*);
ErrorOr<void> getpeername(int sockfd, struct sockaddr*, socklen_t*);
ErrorOr<void> socketpair(int domain, int type, int protocol, int sv[2]);
ErrorOr<Vector<gid_t>> getgroups();
}