2022-11-19 17:13:52 +08:00

83 lines
2.0 KiB
C++

/**
* @file libimp/platform/posix/system.h
* @author mutouyun (orz@orzz.org)
*/
#pragma once
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "libimp/system.h"
#include "libimp/log.h"
LIBIMP_NAMESPACE_BEG_
namespace sys {
#ifndef ENOERR
#define ENOERR (0)
#endif
/**
* @brief Get the system error code
* https://man7.org/linux/man-pages/man3/errno.3.html
*/
result_code error_code() noexcept {
auto err = errno;
if (err == ENOERR) return {ENOERR};
return {false, std::uint64_t(err)};
}
/**
* @brief Set the system error code
* https://man7.org/linux/man-pages/man3/errno.3.html
*/
void error_code(result_code code) noexcept {
errno = code ? ENOERR : (int)code.value();
}
/**
* @brief Gets a text description of the system error
* https://man7.org/linux/man-pages/man3/strerror_l.3.html
* https://manpages.ubuntu.com/manpages/xenial/en/man3/strerror.3.html
*/
std::string error_str(result_code code) noexcept {
char msg_buf[256] {};
#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE)
LIBIMP_LOG_();
if (::strerror_r((int)code.value(), msg_buf, sizeof(msg_buf)) != 0) {
log.error("failed: strerror_r(code = {}, buf, buf-size = {}). error = {}",
(int)code.value(), sizeof(msg_buf), error_code());
return {};
}
return msg_buf;
#else
return ::strerror_r((int)code.value(), msg_buf, sizeof(msg_buf));
#endif
}
/**
* @brief Gets configuration information at run time
* https://man7.org/linux/man-pages/man2/getpagesize.2.html
* https://man7.org/linux/man-pages/man3/sysconf.3.html
*/
result<std::int64_t> conf(info r) noexcept {
LIBIMP_LOG_();
switch (r) {
case info::page_size: {
auto val = ::sysconf(_SC_PAGESIZE);
if (val >= 0) return (std::int64_t)val;
break;
}
default:
log.error("invalid info = {}", enum_cast(r));
return {};
}
auto err = sys::error();
log.error("info = {}, error = {}", enum_cast(r), err);
return {false, (int)err.value()};
}
} // namespace sys
LIBIMP_NAMESPACE_END_