23 enum class UVHandleType: std::underlying_type_t<uv_handle_type> {
24 UNKNOWN = UV_UNKNOWN_HANDLE,
27 FS_EVENT = UV_FS_EVENT,
46 struct UVTypeWrapper {
49 constexpr UVTypeWrapper(): value{} {}
50 constexpr UVTypeWrapper(Type val): value{val} {}
52 constexpr
operator Type() const noexcept {
return value; }
54 bool operator==(UVTypeWrapper other)
const noexcept {
55 return value == other.value;
64 bool operator==(UVTypeWrapper<T> lhs, UVTypeWrapper<T> rhs) {
84 using InnerType = std::underlying_type_t<E>;
86 constexpr InnerType toInnerType(E flag)
const noexcept {
return static_cast<InnerType
>(flag); }
89 using Type = InnerType;
104 constexpr
Flags(E flag) noexcept: flags{toInnerType(flag)} {}
111 constexpr
Flags(Type f): flags{f} {}
118 constexpr
Flags(
const Flags &f) noexcept: flags{f.flags} { }
119 constexpr
Flags(
Flags &&f) noexcept: flags{std::move(f.flags)} { }
121 ~
Flags() noexcept { static_assert(std::is_enum_v<E>); }
123 constexpr
Flags & operator=(
const Flags &f) noexcept {
128 constexpr
Flags & operator=(
Flags &&f) noexcept {
129 flags = std::move(f.flags);
165 explicit constexpr
operator bool() const noexcept {
return !(flags == InnerType{}); }
171 constexpr
operator Type() const noexcept {
return flags; }
187 using HandleType = details::UVHandleType;
193 using PidType = details::UVTypeWrapper<uv_pid_t>;
219 Passwd(std::shared_ptr<uv_passwd_t> pwd): passwd{pwd} {}
226 return ((passwd && passwd->username) ? passwd->username :
"");
233 auto uid() const noexcept {
234 return (passwd ? passwd->uid : decltype(uv_passwd_t::uid){});
241 auto gid() const noexcept {
242 return (passwd ? passwd->gid : decltype(uv_passwd_t::gid){});
249 std::string
shell() const noexcept {
250 return ((passwd && passwd->shell) ? passwd->shell :
"");
258 return ((passwd && passwd->homedir) ? passwd->homedir:
"");
265 operator bool() const noexcept {
266 return static_cast<bool>(passwd);
270 std::shared_ptr<uv_passwd_t> passwd;
284 UtsName(std::shared_ptr<uv_utsname_t> utsname): utsname{utsname} {}
291 return utsname ? utsname->sysname :
"";
299 return utsname ? utsname->release :
"";
307 return utsname ? utsname->version :
"";
315 return utsname ? utsname->machine :
"";
319 std::shared_ptr<uv_utsname_t> utsname;
352 using CPUTime = decltype(uv_cpu_info_t::cpu_times);
382 static constexpr std::size_t DEFAULT_SIZE = 128;
390 struct IpTraits<IPv4> {
391 using Type = sockaddr_in;
392 using AddrFuncType = int(*)(
const char *, int, Type *);
393 using NameFuncType = int(*)(
const Type *,
char *, std::size_t);
394 static constexpr AddrFuncType addrFunc = &uv_ip4_addr;
395 static constexpr NameFuncType nameFunc = &uv_ip4_name;
396 static constexpr
auto sinPort(
const Type *addr) {
return addr->sin_port; }
401 struct IpTraits<IPv6> {
402 using Type = sockaddr_in6;
403 using AddrFuncType = int(*)(
const char *, int, Type *);
404 using NameFuncType = int(*)(
const Type *,
char *, std::size_t);
405 static constexpr AddrFuncType addrFunc = &uv_ip6_addr;
406 static constexpr NameFuncType nameFunc = &uv_ip6_name;
407 static constexpr
auto sinPort(
const Type *addr) {
return addr->sin6_port; }
412 Addr address(
const typename details::IpTraits<I>::Type *aptr) noexcept {
414 char name[DEFAULT_SIZE];
416 int err = details::IpTraits<I>::nameFunc(aptr, name, DEFAULT_SIZE);
419 addr.
port = ntohs(details::IpTraits<I>::sinPort(aptr));
420 addr.
ip = std::string{name};
427 template<
typename I,
typename F,
typename H>
428 Addr address(F &&f,
const H *handle) noexcept {
429 sockaddr_storage ssto;
430 int len =
sizeof(ssto);
433 int err = std::forward<F>(f)(handle, reinterpret_cast<sockaddr *>(&ssto), &len);
436 typename IpTraits<I>::Type *aptr =
reinterpret_cast<typename IpTraits<I>::Type *
>(&ssto);
437 addr = address<I>(aptr);
444 template<
typename F,
typename... Args>
445 std::string tryRead(F &&f, Args&&... args) noexcept {
446 std::size_t size = DEFAULT_SIZE;
447 char buf[DEFAULT_SIZE];
449 auto err = std::forward<F>(f)(args..., buf, &size);
451 if(UV_ENOBUFS == err) {
452 std::unique_ptr<char[]> data{
new char[size]};
453 err = std::forward<F>(f)(args..., data.get(), &size);
458 }
else if(0 == err) {
459 str.assign(buf, size);
475 using MallocFuncType =
void*(*)(size_t);
476 using ReallocFuncType =
void*(*)(
void*, size_t);
477 using CallocFuncType =
void*(*)(size_t, size_t);
478 using FreeFuncType = void(*)(
void*);
494 return uv_os_getpid();
507 return uv_os_getppid();
521 return details::tryRead(&uv_os_homedir);
534 return details::tryRead(&uv_os_tmpdir);
543 static std::string
env(
const std::string &name) noexcept {
544 return details::tryRead(&uv_os_getenv, name.c_str());
554 static bool env(
const std::string &name,
const std::string &value) noexcept {
555 return (0 == (value.empty() ? uv_os_unsetenv(name.c_str()) : uv_os_setenv(name.c_str(), value.c_str())));
571 template<
typename Func>
572 static std::enable_if_t<std::is_invocable_v<Func, std::string_view, std::string_view>,
bool>
574 uv_env_item_t *items =
nullptr;
577 const bool ret = (uv_os_environ(&items, &count) == 0);
580 for(
int pos = 0; pos < count; ++pos) {
581 func(std::string_view{items[pos].name}, std::string_view{items[pos].value});
584 uv_os_free_environ(items, count);
595 return details::tryRead(&uv_os_gethostname);
608 auto ptr = std::make_shared<uv_utsname_t>();
609 uv_os_uname(ptr.get());
626 auto deleter = [](uv_passwd_t *passwd){
627 uv_os_free_passwd(passwd);
631 std::shared_ptr<uv_passwd_t> ptr{
new uv_passwd_t, std::move(deleter)};
632 uv_os_get_passwd(ptr.get());
653 if(uv_os_getpriority(pid, &prio)) {
654 prio = UV_PRIORITY_LOW + 1;
676 return 0 == uv_os_setpriority(pid, prio);
687 return HandleType::ASYNC;
689 return HandleType::CHECK;
691 return HandleType::FS_EVENT;
693 return HandleType::FS_POLL;
695 return HandleType::HANDLE;
697 return HandleType::IDLE;
699 return HandleType::PIPE;
701 return HandleType::POLL;
703 return HandleType::PREPARE;
705 return HandleType::PROCESS;
707 return HandleType::STREAM;
709 return HandleType::TCP;
711 return HandleType::TIMER;
713 return HandleType::TTY;
715 return HandleType::UDP;
717 return HandleType::SIGNAL;
719 return HandleType::FILE;
721 return HandleType::UNKNOWN;
745 return guessHandle(category);
756 static std::vector<CPUInfo>
cpuInfo() noexcept {
757 std::vector<CPUInfo> cpuinfos;
759 uv_cpu_info_t *infos;
762 if(0 == uv_cpu_info(&infos, &count)) {
763 std::for_each(infos, infos+count, [&cpuinfos](
const auto &info) {
764 cpuinfos.push_back({ info.model, info.speed, info.cpu_times });
767 uv_free_cpu_info(infos, count);
782 std::vector<InterfaceAddress> interfaces;
784 uv_interface_address_t *ifaces{
nullptr};
787 if(0 == uv_interface_addresses(&ifaces, &count)) {
788 std::for_each(ifaces, ifaces+count, [&interfaces](
const auto &iface) {
791 interfaceAddress.
name = iface.name;
792 std::copy(iface.phys_addr, (iface.phys_addr+6), interfaceAddress.
physical);
793 interfaceAddress.
internal = iface.is_internal == 0 ? false :
true;
795 if(iface.address.address4.sin_family == AF_INET) {
796 interfaceAddress.
address = details::address<IPv4>(&iface.address.address4);
797 interfaceAddress.
netmask = details::address<IPv4>(&iface.netmask.netmask4);
798 }
else if(iface.address.address4.sin_family == AF_INET6) {
799 interfaceAddress.
address = details::address<IPv6>(&iface.address.address6);
800 interfaceAddress.
netmask = details::address<IPv6>(&iface.netmask.netmask6);
803 interfaces.push_back(std::move(interfaceAddress));
806 uv_free_interface_addresses(ifaces, count);
826 return details::tryRead(&uv_if_indextoname, index);
840 return details::tryRead(&uv_if_indextoiid, index);
866 static bool replaceAllocator(MallocFuncType mallocFunc, ReallocFuncType reallocFunc, CallocFuncType callocFunc, FreeFuncType freeFunc) noexcept {
867 return (0 == uv_replace_allocator(mallocFunc, reallocFunc, callocFunc, freeFunc));
875 std::array<double, 3> avg;
876 uv_loadavg(avg.data());
888 return uv_setup_args(argc, argv);
896 std::size_t size = details::DEFAULT_SIZE;
897 char buf[details::DEFAULT_SIZE];
900 if(0 == uv_get_process_title(buf, size)) {
901 str.assign(buf, size);
913 return (0 == uv_set_process_title(title.c_str()));
921 return uv_get_total_memory();
936 return uv_get_constrained_memory();
946 if(0 != uv_uptime(&ret)) {
959 auto err = uv_getrusage(&ru);
960 return err ?
RUsage{} : ru;
981 static std::string
path() noexcept {
982 return details::tryRead(&uv_exepath);
989 static std::string
cwd() noexcept {
990 return details::tryRead(&uv_cwd);
998 static bool chdir(
const std::string &dir) noexcept {
999 return (0 == uv_chdir(dir.data()));
1009 uv_gettimeofday(&ret);
constexpr FileHandle StdERR
auto gid() const noexcept
Gets the gid.
std::string version() const noexcept
Gets the operating system version.
static Passwd passwd() noexcept
Gets a subset of the password file entry.
static HandleType guessHandle(FileHandle file) noexcept
Gets the type of the stream to be used with the given descriptor.
static std::string hostname() noexcept
Returns the hostname.
static std::string env(const std::string &name) noexcept
Retrieves an environment variable.
static std::vector< InterfaceAddress > interfaceAddresses() noexcept
Gets a set of descriptors of all the available interfaces.
std::string release() const noexcept
Gets the operating system release (like "2.6.28").
static double uptime() noexcept
Gets the current system uptime.
details::UVTypeWrapper< uv_file > FileHandle
static std::string tmpdir() noexcept
Gets the temp directory.
static std::string homedir() noexcept
Gets the current user's home directory.
static PidType pid() noexcept
Returns the current process id.
Windows size representation.
details::UVTypeWrapper< uv_os_fd_t > OSFileDescriptor
std::string machine() const noexcept
Gets the hardware identifier.
static int osPriority(PidType pid)
Retrieves the scheduling priority of a process.
constexpr FileHandle StdIN
static char ** setupArgs(int argc, char **argv)
Store the program arguments.
std::string username() const noexcept
Gets the username.
constexpr FileHandle StdOUT
Utility class to handle flags.
details::UVTypeWrapper< uv_pid_t > PidType
constexpr Flags operator &(const Flags &f) const noexcept
And operator.
constexpr Flags(E flag) noexcept
Constructs a Flags object from a value of the enum E.
constexpr Flags operator|(const Flags &f) const noexcept
Or operator.
static bool osPriority(PidType pid, int prio)
Sets the scheduling priority of a process.
static uint64_t hrtime() noexcept
Gets the current high-resolution real time.
static TimeVal64 timeOfDay()
Cross-platform implementation of gettimeofday
static UtsName uname() noexcept
Gets name and information about the current kernel.
static bool replaceAllocator(MallocFuncType mallocFunc, ReallocFuncType reallocFunc, CallocFuncType callocFunc, FreeFuncType freeFunc) noexcept
Override the use of some standard library’s functions.
details::UVTypeWrapper< uv_handle_type > HandleCategory
static bool env(const std::string &name, const std::string &value) noexcept
Creates, updates or deletes an environment variable.
static RUsage rusage() noexcept
Gets the resource usage measures for the current process.
static uint64_t totalMemory() noexcept
Gets memory information (in bytes).
auto uid() const noexcept
Gets the uid.
std::string shell() const noexcept
Gets the shell.
static std::string indexToName(unsigned int index) noexcept
IPv6-capable implementation of if_indextoname.
static std::string cwd() noexcept
Gets the current working directory.
static std::string path() noexcept
Gets the executable path.
details::UVTypeWrapper< uv_os_sock_t > OSSocketHandle
static PidType parent() noexcept
Returns the parent process id.
constexpr Flags()
Constructs an uninitialized Flags object.
static HandleType guessHandle(HandleCategory category) noexcept
Gets the type of the handle given a category.
constexpr Flags(Type f)
Constructs a Flags object from an instance of the underlying type of the enum E.
constexpr Flags operator|(E flag) const noexcept
Or operator.
std::string sysname() const noexcept
Gets the operating system name (like "Linux").
static std::vector< CPUInfo > cpuInfo() noexcept
Gets information about the CPUs on the system.
static bool chdir(const std::string &dir) noexcept
Changes the current working directory.
constexpr Flags operator &(E flag) const noexcept
And operator.
static std::array< double, 3 > loadAverage() noexcept
Gets the load average.
static constexpr Flags< E > from()
Utility factory method to pack a set of values all at once.
static std::enable_if_t< std::is_invocable_v< Func, std::string_view, std::string_view >, bool > env(Func func) noexcept
Retrieves all environment variables and iterates them.
static bool processTitle(std::string title)
Sets the current process title.
static std::string processTitle()
Gets the title of the current process.
static uint64_t constrainedMemory() noexcept
Gets the amount of memory available to the process (in bytes).
std::string homedir() const noexcept
Gets the homedir.
static std::string indexToIid(unsigned int index) noexcept
Retrieves a network interface identifier.