#include "os_ops.hpp"
#include <optional>
+#include <vector>
#include <grp.h>
#include <pwd.h>
namespace fs = std::filesystem;
using namespace std::string_literals;
+static std::vector <char> allocate_sysconf_buffer(int sysconf_type)
+{
+ const auto max_buf_size = static_cast <ssize_t> (sysconf(sysconf_type));
+ if (max_buf_size <= 0)
+ throw std::runtime_error("Couldn't acquire buffer size from sysconf");
+
+ std::vector <char> ret;
+ ret.resize(max_buf_size);
+ return ret;
+}
/* TODO: perhaps there should also be a "do_exec" wrapper which would
* accept a child lambda and do the throwing fork and the waitpid */
std::string OS::get_home_dir_by_user_id(const int uid)
{
- auto max_buf_size = static_cast<ssize_t>(sysconf(_SC_GETPW_R_SIZE_MAX));
- if (max_buf_size <= 0)
- throw std::runtime_error("Couldn't acquire buffer size for `getpwuid_r` system call");
-
- std::unique_ptr<char[]> str_buf(new char[max_buf_size]);
- // N.B. `new` throws `std::bad_alloc` exception if it runs out of memory,
- // so there's no need to check if it's successful here
+ auto buffer = allocate_sysconf_buffer(_SC_GETPW_R_SIZE_MAX);
passwd pass_buf;
passwd *pass_ptr = NULL;
- const int ret = getpwuid_r(uid, &pass_buf, str_buf.get(), max_buf_size, &pass_ptr);
+ const int ret = getpwuid_r(uid, &pass_buf, buffer.data(), buffer.size(), &pass_ptr);
if (ret < 0)
throw std::system_error(errno, std::generic_category()
, "Couldn't get home directory for session_uid=" + std::to_string(uid));
int OS::get_gid_from_name(std::string_view group_name)
{
- auto max_grp_buf_size = static_cast<ssize_t>(sysconf(_SC_GETGR_R_SIZE_MAX));
- if (max_grp_buf_size <= 0)
- throw std::runtime_error("Couldn't acquire buffer size for `getgrnam_r` system call");
-
- std::unique_ptr<char[]> str_grp_buf(new char[max_grp_buf_size]);
+ auto buffer = allocate_sysconf_buffer(_SC_GETGR_R_SIZE_MAX);
group pass_grp_buf;
group *pass_grp_ptr = NULL;
- const int ret = getgrnam_r(group_name.data(), &pass_grp_buf, str_grp_buf.get(), max_grp_buf_size, &pass_grp_ptr);
+ const int ret = getgrnam_r(group_name.data(), &pass_grp_buf, buffer.data(), buffer.size(), &pass_grp_ptr);
if (ret < 0)
throw std::system_error(errno, std::generic_category()
,"Couldn't get Unix gid for `"s