Extract sysconf buffer allocation 47/322547/3
authorMichal Bloch <m.bloch@samsung.com>
Wed, 9 Apr 2025 16:20:58 +0000 (18:20 +0200)
committerMichal Bloch <m.bloch@samsung.com>
Fri, 11 Apr 2025 16:38:50 +0000 (18:38 +0200)
Change-Id: I931eca869f4b6354c25c5faa0b56362e069839d4

src/service/src/os_ops.cpp

index 92bce5032cc65b1fd8682c9f7c9eb5f27aa641e5..0b96f93acef31cc6916d406a2ada45b624f30f32 100644 (file)
@@ -23,6 +23,7 @@
 #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 */
@@ -63,17 +74,11 @@ void OS::throw_if_child_failed(int child_pid, std::string_view message_on_fail)
 
 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));
@@ -87,15 +92,11 @@ std::string OS::get_home_dir_by_user_id(const int 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