mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 07:44:59 +00:00
LibC: Implement getgrgid_r()
and getgrnam_r()
We currently don't have those 2 functions so let's add them
This commit is contained in:
parent
3dfd8defa9
commit
3c52c25515
4 changed files with 125 additions and 0 deletions
|
@ -5,6 +5,7 @@ set(TEST_SOURCES
|
||||||
TestEnvironment.cpp
|
TestEnvironment.cpp
|
||||||
TestIo.cpp
|
TestIo.cpp
|
||||||
TestLibCExec.cpp
|
TestLibCExec.cpp
|
||||||
|
TestLibCGrp.cpp
|
||||||
TestLibCDirEnt.cpp
|
TestLibCDirEnt.cpp
|
||||||
TestLibCInodeWatcher.cpp
|
TestLibCInodeWatcher.cpp
|
||||||
TestLibCMkTemp.cpp
|
TestLibCMkTemp.cpp
|
||||||
|
|
102
Tests/LibC/TestLibCGrp.cpp
Normal file
102
Tests/LibC/TestLibCGrp.cpp
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2023, the SerenityOS developers.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <AK/ByteString.h>
|
||||||
|
#include <AK/HashTable.h>
|
||||||
|
#include <LibTest/Macros.h>
|
||||||
|
#include <LibTest/TestCase.h>
|
||||||
|
#include <grp.h>
|
||||||
|
|
||||||
|
void check_correctness(struct group* gr);
|
||||||
|
|
||||||
|
void check_correctness(struct group* gr)
|
||||||
|
{
|
||||||
|
EXPECT_NE(gr, nullptr);
|
||||||
|
EXPECT_EQ(gr->gr_gid, (gid_t)3);
|
||||||
|
EXPECT_EQ(gr->gr_name, "phys"sv);
|
||||||
|
EXPECT_EQ(gr->gr_passwd, "x"sv);
|
||||||
|
|
||||||
|
HashTable<ByteString> members;
|
||||||
|
for (char** mem = gr->gr_mem; *mem; ++mem) {
|
||||||
|
members.set(ByteString(*mem));
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(true, members.contains("window"sv));
|
||||||
|
EXPECT_EQ(true, members.contains("anon"sv));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE(getgrid_returns_correct_value)
|
||||||
|
{
|
||||||
|
// From Base/etc/group
|
||||||
|
// phys:x:3:window,anon
|
||||||
|
struct group* gr = getgrgid(3);
|
||||||
|
|
||||||
|
check_correctness(gr);
|
||||||
|
|
||||||
|
gr = getgrgid(99999);
|
||||||
|
EXPECT_EQ(gr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE(getgrid_r_uses_provided_buffer)
|
||||||
|
{
|
||||||
|
// From Base/etc/group
|
||||||
|
// phys:x:3:window,anon
|
||||||
|
|
||||||
|
struct group g;
|
||||||
|
struct group* res;
|
||||||
|
AK::Array<char, 1024> buffer;
|
||||||
|
|
||||||
|
setgrent();
|
||||||
|
int rc = getgrgid_r(3, &g, buffer.data(), buffer.size(), &res);
|
||||||
|
endgrent();
|
||||||
|
EXPECT_EQ(rc, 0);
|
||||||
|
check_correctness(&g);
|
||||||
|
EXPECT_EQ(res, &g);
|
||||||
|
|
||||||
|
auto is_pointer_in_range = [&buffer](void* ptr) {
|
||||||
|
return (buffer.data() <= ptr) && (ptr < buffer.data() + buffer.size());
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPECT(is_pointer_in_range(g.gr_mem));
|
||||||
|
EXPECT(is_pointer_in_range(g.gr_name));
|
||||||
|
|
||||||
|
char** mem = g.gr_mem;
|
||||||
|
for (; *mem; ++mem) {
|
||||||
|
EXPECT(is_pointer_in_range(mem));
|
||||||
|
EXPECT(is_pointer_in_range(*mem));
|
||||||
|
}
|
||||||
|
EXPECT(is_pointer_in_range(mem));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE(getgrname_r_uses_provided_buffer)
|
||||||
|
{
|
||||||
|
// From Base/etc/group
|
||||||
|
// phys:x:3:window,anon
|
||||||
|
|
||||||
|
struct group g;
|
||||||
|
struct group* res;
|
||||||
|
AK::Array<char, 1024> buffer;
|
||||||
|
setgrent();
|
||||||
|
int rc = getgrnam_r("phys", &g, buffer.data(), buffer.size(), &res);
|
||||||
|
endgrent();
|
||||||
|
EXPECT_EQ(rc, 0);
|
||||||
|
check_correctness(&g);
|
||||||
|
EXPECT_EQ(res, &g);
|
||||||
|
|
||||||
|
auto is_pointer_in_range = [&buffer](void* ptr) {
|
||||||
|
return (buffer.data() <= ptr) && (ptr < buffer.data() + buffer.size());
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPECT(is_pointer_in_range(g.gr_mem));
|
||||||
|
EXPECT(is_pointer_in_range(g.gr_name));
|
||||||
|
|
||||||
|
char** mem = g.gr_mem;
|
||||||
|
for (; *mem; ++mem) {
|
||||||
|
EXPECT(is_pointer_in_range(mem));
|
||||||
|
EXPECT(is_pointer_in_range(*mem));
|
||||||
|
}
|
||||||
|
EXPECT(is_pointer_in_range(mem));
|
||||||
|
}
|
|
@ -6,7 +6,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Format.h>
|
#include <AK/Format.h>
|
||||||
|
#include <AK/Forward.h>
|
||||||
#include <AK/ScopeGuard.h>
|
#include <AK/ScopeGuard.h>
|
||||||
|
#include <AK/StringView.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <errno_codes.h>
|
#include <errno_codes.h>
|
||||||
|
@ -53,6 +55,16 @@ struct group* getgrgid(gid_t gid)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getgrgid_r(gid_t gid, struct group* group_buf, char* buffer, size_t buffer_size, struct group** group_entry_ptr)
|
||||||
|
{
|
||||||
|
while (0 == getgrent_r(group_buf, buffer, buffer_size, group_entry_ptr)) {
|
||||||
|
if (group_buf->gr_gid == gid) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
struct group* getgrnam(char const* name)
|
struct group* getgrnam(char const* name)
|
||||||
{
|
{
|
||||||
setgrent();
|
setgrent();
|
||||||
|
@ -63,6 +75,14 @@ struct group* getgrnam(char const* name)
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
int getgrnam_r(char const* name, struct group* group_buf, char* buffer, size_t buffer_size, struct group** group_entry_ptr)
|
||||||
|
{
|
||||||
|
while (0 == getgrent_r(group_buf, buffer, buffer_size, group_entry_ptr)) {
|
||||||
|
if (!strcmp(group_buf->gr_name, name))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
static bool parse_grpdb_entry(char* buffer, size_t buffer_size, struct group& group_entry)
|
static bool parse_grpdb_entry(char* buffer, size_t buffer_size, struct group& group_entry)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,9 @@ int getgrent_r(struct group* group_buf, char* buffer, size_t buffer_size, struct
|
||||||
void setgrent(void);
|
void setgrent(void);
|
||||||
void endgrent(void);
|
void endgrent(void);
|
||||||
struct group* getgrnam(char const* name);
|
struct group* getgrnam(char const* name);
|
||||||
|
int getgrnam_r(char const* name, struct group* group_buf, char* buffer, size_t buffer_size, struct group** group_entry_ptr);
|
||||||
struct group* getgrgid(gid_t);
|
struct group* getgrgid(gid_t);
|
||||||
|
int getgrgid_r(gid_t gid, struct group* group_buf, char* buffer, size_t buffer_size, struct group** group_entry_ptr);
|
||||||
int putgrent(const struct group*, FILE*);
|
int putgrent(const struct group*, FILE*);
|
||||||
|
|
||||||
int initgroups(char const* user, gid_t);
|
int initgroups(char const* user, gid_t);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue