* Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
* ubs-engine is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "ubse_os_util.h"
#include <grp.h>
#include <pwd.h>
#include <securec.h>
#include <ubse_logger.h>
#include <ubse_str_util.h>
#include <array>
#include <csignal>
#include <fstream>
#include <iostream>
#include <memory>
#include <regex>
#include <sstream>
#include "ubse_error.h"
#include "ubse_logger.h"
namespace ubse::utils {
UBSE_DEFINE_THIS_MODULE("ubse");
using namespace ubse::log;
using namespace ubse::common::def;
UbseResult UbseOsUtil::GetUserNameById(uid_t uid, std::string& userName)
{
struct passwd pwd;
struct passwd* result = nullptr;
long bufSize = sysconf(_SC_GETPW_R_SIZE_MAX);
if (bufSize == -1) {
bufSize = 16384;
}
std::vector<char> buffer(static_cast<size_t>(bufSize));
auto ret = getpwuid_r(uid, &pwd, buffer.data(), buffer.size(), &result);
if (ret != 0 || result == nullptr) {
return UBSE_ERROR;
}
userName = std::string(pwd.pw_name);
return UBSE_OK;
}
UbseResult UbseOsUtil::Exec(const std::string& cmd, std::string& res)
{
std::array<char, NO_128> buffer{};
res.clear();
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
if (!pipe) {
return UBSE_ERROR;
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
res += buffer.data();
}
int status = pclose(pipe.release());
if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
return UBSE_ERROR;
}
return UBSE_OK;
}
UbseResult UbseOsUtil::GetUidByName(const std::string& username, uid_t& uid)
{
if (username.empty()) {
return UBSE_ERROR_INVAL;
}
struct passwd pwd;
struct passwd* result = nullptr;
long bufSize = sysconf(_SC_GETPW_R_SIZE_MAX);
if (bufSize == -1) {
bufSize = 16384;
}
std::vector<char> buffer(static_cast<size_t>(bufSize));
int ret = getpwnam_r(username.c_str(), &pwd, buffer.data(), buffer.size(), &result);
if (ret != 0 || result == nullptr) {
return UBSE_ERROR;
}
uid = pwd.pw_uid;
return UBSE_OK;
}
UbseResult UbseOsUtil::GetNumaIdByPid(const uint64_t& pid, uint32_t& numaId)
{
auto path = "/proc/" + std::to_string(pid) + "/numa_maps";
std::string line;
std::regex keywordRegex("(/qemu.*N(\\d+)=(\\d+))");
std::regex n1Regex("N(\\d+)=(\\d+)");
std::ifstream file(path);
if (!file.is_open()) {
UBSE_LOG_ERROR << "open " << path << " failed, " << std::strerror(errno);
return UBSE_ERROR;
}
while (std::getline(file, line)) {
std::smatch n1Match;
if (std::regex_search(line, keywordRegex) && std::regex_search(line, n1Match, n1Regex)) {
auto ret = ConvertStrToUint32(n1Match[1], numaId);
if (ret != UBSE_OK) {
UBSE_LOG_ERROR << "Convert numaId=" << n1Match[1] << "failed";
return UBSE_ERROR;
}
UBSE_LOG_INFO << "get numaId=" << numaId << ", by pid=" << pid;
return UBSE_OK;
}
}
file.close();
return UBSE_ERROR;
}
UbseResult UbseOsUtil::ReadFileContent(const std::string& filePath, std::string& res)
{
std::ifstream file(filePath);
if (!file.is_open()) {
return UBSE_ERROR;
}
std::stringstream buffer;
buffer << file.rdbuf();
res = buffer.str();
file.close();
return UBSE_OK;
}
}