BuildSystem: Move all userpace libraries under the userspace directory

As the number of libraries is increasing, root directory starts to
expand. This adds better organization for libraries
This commit is contained in:
2024-06-18 13:14:35 +03:00
parent 1b5a01a6c9
commit c69919738b
157 changed files with 46 additions and 30 deletions

View File

@@ -0,0 +1,162 @@
#include <BAN/StringView.h>
#include <BAN/Vector.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
static struct stat s_group_st;
static char* s_group_mmap = nullptr;
static int s_group_fd = -1;
static struct group s_group;
id_t parse_id(BAN::StringView string)
{
id_t id = 0;
for (char c : string)
{
if (!isdigit(c))
return -1;
id = (id * 10) + (c - '0');
}
return id;
}
static bool open_group_file()
{
if (s_group_fd == -1)
s_group_fd = open("/etc/group", O_RDONLY);
if (s_group_fd == -1)
return false;
if (fstat(s_group_fd, &s_group_st) == -1)
return false;
if (s_group_mmap == nullptr || s_group_mmap == MAP_FAILED)
s_group_mmap = (char*)mmap(nullptr, s_group_st.st_size, PROT_READ, MAP_PRIVATE, s_group_fd, 0);
if (s_group_mmap == MAP_FAILED)
return false;
s_group.gr_name = nullptr;
s_group.gr_mem = nullptr;
return true;
}
struct group* fill_group(const BAN::Vector<BAN::StringView>& parts)
{
if (parts.size() != 4)
return nullptr;
if (s_group.gr_name)
{
free(s_group.gr_name);
s_group.gr_name = nullptr;
}
if (s_group.gr_mem)
{
for (size_t i = 0; s_group.gr_mem && s_group.gr_mem[i]; i++)
free(s_group.gr_mem[i]);
free(s_group.gr_mem);
s_group.gr_mem = nullptr;
}
auto groups_or_error = parts[3].split(',');
if (groups_or_error.is_error())
return nullptr;
auto groups = groups_or_error.release_value();
s_group.gr_gid = parse_id(parts[2]);
if (s_group.gr_gid == -1)
return nullptr;
s_group.gr_name = (char*)malloc(parts[0].size() + 1);
if (s_group.gr_name == nullptr)
return nullptr;
memcpy(s_group.gr_name, parts[0].data(), parts[0].size());
s_group.gr_name[parts[0].size()] = '\0';
s_group.gr_mem = (char**)malloc((groups.size() + 1) * sizeof(char*));
if (s_group.gr_mem == nullptr)
return nullptr;
for (size_t i = 0; i < groups.size(); i++)
{
s_group.gr_mem[i] = (char*)malloc(groups[i].size() + 1);
if (s_group.gr_mem[i] == nullptr)
{
for (size_t j = 0; j < i; j++)
free(s_group.gr_mem[j]);
free(s_group.gr_mem);
s_group.gr_mem = nullptr;
return nullptr;
}
memcpy(s_group.gr_mem[i], groups[i].data(), groups[i].size());
s_group.gr_mem[i][groups[i].size()] = '\0';
}
s_group.gr_mem[groups.size()] = nullptr;
return &s_group;
}
struct group* getgrnam(const char* name)
{
if (s_group_mmap == nullptr || s_group_mmap == MAP_FAILED)
if (!open_group_file())
return nullptr;
off_t start = 0;
off_t end = 0;
while (start < s_group_st.st_size)
{
while (end < s_group_st.st_size && s_group_mmap[end] != '\n')
end++;
BAN::StringView line(s_group_mmap + start, end - start);
start = ++end;
auto parts_or_error = line.split(':', true);
if (parts_or_error.is_error())
return nullptr;
auto parts = parts_or_error.release_value();
if (parts.size() == 4 && parts[0] == name)
return fill_group(parts);
}
return nullptr;
}
struct group* getgrgid(gid_t gid)
{
if (s_group_mmap == nullptr || s_group_mmap == MAP_FAILED)
if (!open_group_file())
return nullptr;
off_t start = 0;
off_t end = 0;
while (start < s_group_st.st_size)
{
while (end < s_group_st.st_size && s_group_mmap[end] != '\n')
end++;
BAN::StringView line(s_group_mmap + start, end - start);
start = ++end;
auto parts_or_error = line.split(':', true);
if (parts_or_error.is_error())
return nullptr;
auto parts = parts_or_error.release_value();
if (parts.size() == 4 && parse_id(parts[2]) == gid)
return fill_group(parts);
}
return nullptr;
}