uvw  2.2.0
util.hpp
1 #pragma once
2 
3 
4 #include <string_view>
5 #include <type_traits>
6 #include <algorithm>
7 #include <stdexcept>
8 #include <cstddef>
9 #include <utility>
10 #include <string>
11 #include <vector>
12 #include <memory>
13 #include <array>
14 #include <uv.h>
15 
16 
17 namespace uvw {
18 
19 
20 namespace details {
21 
22 
23 enum class UVHandleType: std::underlying_type_t<uv_handle_type> {
24  UNKNOWN = UV_UNKNOWN_HANDLE,
25  ASYNC = UV_ASYNC,
26  CHECK = UV_CHECK,
27  FS_EVENT = UV_FS_EVENT,
28  FS_POLL = UV_FS_POLL,
29  HANDLE = UV_HANDLE,
30  IDLE = UV_IDLE,
31  PIPE = UV_NAMED_PIPE,
32  POLL = UV_POLL,
33  PREPARE = UV_PREPARE,
34  PROCESS = UV_PROCESS,
35  STREAM = UV_STREAM,
36  TCP = UV_TCP,
37  TIMER = UV_TIMER,
38  TTY = UV_TTY,
39  UDP = UV_UDP,
40  SIGNAL = UV_SIGNAL,
41  FILE = UV_FILE
42 };
43 
44 
45 template<typename T>
46 struct UVTypeWrapper {
47  using Type = T;
48 
49  constexpr UVTypeWrapper(): value{} {}
50  constexpr UVTypeWrapper(Type val): value{val} {}
51 
52  constexpr operator Type() const noexcept { return value; }
53 
54  bool operator==(UVTypeWrapper other) const noexcept {
55  return value == other.value;
56  }
57 
58 private:
59  const Type value;
60 };
61 
62 
63 template<typename T>
64 bool operator==(UVTypeWrapper<T> lhs, UVTypeWrapper<T> rhs) {
65  return !(lhs == rhs);
66 }
67 
68 
69 }
70 
71 
82 template<typename E>
83 class Flags final {
84  using InnerType = std::underlying_type_t<E>;
85 
86  constexpr InnerType toInnerType(E flag) const noexcept { return static_cast<InnerType>(flag); }
87 
88 public:
89  using Type = InnerType;
90 
95  template<E... V>
96  static constexpr Flags<E> from() {
97  return (Flags<E>{} | ... | V);
98  }
99 
104  constexpr Flags(E flag) noexcept: flags{toInnerType(flag)} {}
105 
111  constexpr Flags(Type f): flags{f} {}
112 
116  constexpr Flags(): flags{} {}
117 
118  constexpr Flags(const Flags &f) noexcept: flags{f.flags} { }
119  constexpr Flags(Flags &&f) noexcept: flags{std::move(f.flags)} { }
120 
121  ~Flags() noexcept { static_assert(std::is_enum_v<E>); }
122 
123  constexpr Flags & operator=(const Flags &f) noexcept {
124  flags = f.flags;
125  return *this;
126  }
127 
128  constexpr Flags & operator=(Flags &&f) noexcept {
129  flags = std::move(f.flags);
130  return *this;
131  }
132 
138  constexpr Flags operator|(const Flags &f) const noexcept { return Flags{flags | f.flags}; }
139 
145  constexpr Flags operator|(E flag) const noexcept { return Flags{flags | toInnerType(flag)}; }
146 
152  constexpr Flags operator&(const Flags &f) const noexcept { return Flags{flags & f.flags}; }
153 
159  constexpr Flags operator&(E flag) const noexcept { return Flags{flags & toInnerType(flag)}; }
160 
165  explicit constexpr operator bool() const noexcept { return !(flags == InnerType{}); }
166 
171  constexpr operator Type() const noexcept { return flags; }
172 
173 private:
174  InnerType flags;
175 };
176 
177 
181 struct WinSize {
182  int width;
183  int height;
184 };
185 
186 
187 using HandleType = details::UVHandleType;
189 using HandleCategory = details::UVTypeWrapper<uv_handle_type>;
190 using FileHandle = details::UVTypeWrapper<uv_file>;
191 using OSSocketHandle = details::UVTypeWrapper<uv_os_sock_t>;
192 using OSFileDescriptor = details::UVTypeWrapper<uv_os_fd_t>;
193 using PidType = details::UVTypeWrapper<uv_pid_t>;
195 constexpr FileHandle StdIN{0};
196 constexpr FileHandle StdOUT{1};
197 constexpr FileHandle StdERR{2};
199 using TimeSpec = uv_timespec_t;
200 using Stat = uv_stat_t;
201 using Statfs = uv_statfs_t;
202 using Uid = uv_uid_t;
203 using Gid = uv_gid_t;
205 using TimeVal = uv_timeval_t;
206 using TimeVal64 = uv_timeval64_t;
207 using RUsage = uv_rusage_t;
218 struct Passwd {
219  Passwd(std::shared_ptr<uv_passwd_t> pwd): passwd{pwd} {}
220 
225  std::string username() const noexcept {
226  return ((passwd && passwd->username) ? passwd->username : "");
227  }
228 
233  auto uid() const noexcept {
234  return (passwd ? passwd->uid : decltype(uv_passwd_t::uid){});
235  }
236 
241  auto gid() const noexcept {
242  return (passwd ? passwd->gid : decltype(uv_passwd_t::gid){});
243  }
244 
249  std::string shell() const noexcept {
250  return ((passwd && passwd->shell) ? passwd->shell : "");
251  }
252 
257  std::string homedir() const noexcept {
258  return ((passwd && passwd->homedir) ? passwd->homedir: "");
259  }
260 
265  operator bool() const noexcept {
266  return static_cast<bool>(passwd);
267  }
268 
269 private:
270  std::shared_ptr<uv_passwd_t> passwd;
271 };
272 
273 
283 struct UtsName {
284  UtsName(std::shared_ptr<uv_utsname_t> utsname): utsname{utsname} {}
285 
290  std::string sysname() const noexcept {
291  return utsname ? utsname->sysname : "";
292  }
293 
298  std::string release() const noexcept {
299  return utsname ? utsname->release : "";
300  }
301 
306  std::string version() const noexcept {
307  return utsname ? utsname->version : "";
308  }
309 
314  std::string machine() const noexcept {
315  return utsname ? utsname->machine : "";
316  }
317 
318 private:
319  std::shared_ptr<uv_utsname_t> utsname;
320 };
321 
322 
328 struct IPv4 {};
329 
330 
336 struct IPv6 {};
337 
338 
342 struct Addr {
343  std::string ip;
344  unsigned int port;
345 };
346 
347 
351 struct CPUInfo {
352  using CPUTime = decltype(uv_cpu_info_t::cpu_times);
353 
354  std::string model;
355  int speed;
363  CPUTime times;
364 };
365 
366 
371  std::string name;
372  char physical[6];
373  bool internal;
376 };
377 
378 
379 namespace details {
380 
381 
382 static constexpr std::size_t DEFAULT_SIZE = 128;
383 
384 
385 template<typename>
386 struct IpTraits;
387 
388 
389 template<>
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; }
397 };
398 
399 
400 template<>
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; }
408 };
409 
410 
411 template<typename I>
412 Addr address(const typename details::IpTraits<I>::Type *aptr) noexcept {
413  Addr addr;
414  char name[DEFAULT_SIZE];
415 
416  int err = details::IpTraits<I>::nameFunc(aptr, name, DEFAULT_SIZE);
417 
418  if(0 == err) {
419  addr.port = ntohs(details::IpTraits<I>::sinPort(aptr));
420  addr.ip = std::string{name};
421  }
422 
423  return addr;
424 }
425 
426 
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);
431  Addr addr{};
432 
433  int err = std::forward<F>(f)(handle, reinterpret_cast<sockaddr *>(&ssto), &len);
434 
435  if(0 == err) {
436  typename IpTraits<I>::Type *aptr = reinterpret_cast<typename IpTraits<I>::Type *>(&ssto);
437  addr = address<I>(aptr);
438  }
439 
440  return addr;
441 }
442 
443 
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];
448  std::string str{};
449  auto err = std::forward<F>(f)(args..., buf, &size);
450 
451  if(UV_ENOBUFS == err) {
452  std::unique_ptr<char[]> data{new char[size]};
453  err = std::forward<F>(f)(args..., data.get(), &size);
454 
455  if(0 == err) {
456  str = data.get();
457  }
458  } else if(0 == err) {
459  str.assign(buf, size);
460  }
461 
462  return str;
463 }
464 
465 
466 }
467 
468 
474 struct Utilities {
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*);
479 
483  struct OS {
493  static PidType pid() noexcept {
494  return uv_os_getpid();
495  }
496 
506  static PidType parent() noexcept {
507  return uv_os_getppid();
508  }
509 
520  static std::string homedir() noexcept {
521  return details::tryRead(&uv_os_homedir);
522  }
523 
533  static std::string tmpdir() noexcept {
534  return details::tryRead(&uv_os_tmpdir);
535  }
536 
543  static std::string env(const std::string &name) noexcept {
544  return details::tryRead(&uv_os_getenv, name.c_str());
545  }
546 
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())));
556  }
557 
571  template<typename Func>
572  static std::enable_if_t<std::is_invocable_v<Func, std::string_view, std::string_view>, bool>
573  env(Func func) noexcept {
574  uv_env_item_t *items = nullptr;
575  int count{};
576 
577  const bool ret = (uv_os_environ(&items, &count) == 0);
578 
579  if(ret) {
580  for(int pos = 0; pos < count; ++pos) {
581  func(std::string_view{items[pos].name}, std::string_view{items[pos].value});
582  }
583 
584  uv_os_free_environ(items, count);
585  }
586 
587  return ret;
588  }
589 
594  static std::string hostname() noexcept {
595  return details::tryRead(&uv_os_gethostname);
596  }
597 
607  static UtsName uname() noexcept {
608  auto ptr = std::make_shared<uv_utsname_t>();
609  uv_os_uname(ptr.get());
610  return ptr;
611  }
612 
625  static Passwd passwd() noexcept {
626  auto deleter = [](uv_passwd_t *passwd){
627  uv_os_free_passwd(passwd);
628  delete passwd;
629  };
630 
631  std::shared_ptr<uv_passwd_t> ptr{new uv_passwd_t, std::move(deleter)};
632  uv_os_get_passwd(ptr.get());
633  return ptr;
634  }
635  };
636 
650  static int osPriority(PidType pid) {
651  int prio = 0;
652 
653  if(uv_os_getpriority(pid, &prio)) {
654  prio = UV_PRIORITY_LOW + 1;
655  }
656 
657  return prio;
658  }
659 
675  static bool osPriority(PidType pid, int prio) {
676  return 0 == uv_os_setpriority(pid, prio);
677  }
678 
684  static HandleType guessHandle(HandleCategory category) noexcept {
685  switch(category) {
686  case UV_ASYNC:
687  return HandleType::ASYNC;
688  case UV_CHECK:
689  return HandleType::CHECK;
690  case UV_FS_EVENT:
691  return HandleType::FS_EVENT;
692  case UV_FS_POLL:
693  return HandleType::FS_POLL;
694  case UV_HANDLE:
695  return HandleType::HANDLE;
696  case UV_IDLE:
697  return HandleType::IDLE;
698  case UV_NAMED_PIPE:
699  return HandleType::PIPE;
700  case UV_POLL:
701  return HandleType::POLL;
702  case UV_PREPARE:
703  return HandleType::PREPARE;
704  case UV_PROCESS:
705  return HandleType::PROCESS;
706  case UV_STREAM:
707  return HandleType::STREAM;
708  case UV_TCP:
709  return HandleType::TCP;
710  case UV_TIMER:
711  return HandleType::TIMER;
712  case UV_TTY:
713  return HandleType::TTY;
714  case UV_UDP:
715  return HandleType::UDP;
716  case UV_SIGNAL:
717  return HandleType::SIGNAL;
718  case UV_FILE:
719  return HandleType::FILE;
720  default:
721  return HandleType::UNKNOWN;
722  }
723  }
724 
743  static HandleType guessHandle(FileHandle file) noexcept {
744  HandleCategory category = uv_guess_handle(file);
745  return guessHandle(category);
746  }
747 
748 
756  static std::vector<CPUInfo> cpuInfo() noexcept {
757  std::vector<CPUInfo> cpuinfos;
758 
759  uv_cpu_info_t *infos;
760  int count;
761 
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 });
765  });
766 
767  uv_free_cpu_info(infos, count);
768  }
769 
770  return cpuinfos;
771  }
772 
781  static std::vector<InterfaceAddress> interfaceAddresses() noexcept {
782  std::vector<InterfaceAddress> interfaces;
783 
784  uv_interface_address_t *ifaces{nullptr};
785  int count{0};
786 
787  if(0 == uv_interface_addresses(&ifaces, &count)) {
788  std::for_each(ifaces, ifaces+count, [&interfaces](const auto &iface) {
789  InterfaceAddress interfaceAddress;
790 
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;
794 
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);
801  }
802 
803  interfaces.push_back(std::move(interfaceAddress));
804  });
805 
806  uv_free_interface_addresses(ifaces, count);
807  }
808 
809  return interfaces;
810  }
811 
825  static std::string indexToName(unsigned int index) noexcept {
826  return details::tryRead(&uv_if_indextoname, index);
827  }
828 
839  static std::string indexToIid(unsigned int index) noexcept {
840  return details::tryRead(&uv_if_indextoiid, index);
841  }
842 
866  static bool replaceAllocator(MallocFuncType mallocFunc, ReallocFuncType reallocFunc, CallocFuncType callocFunc, FreeFuncType freeFunc) noexcept {
867  return (0 == uv_replace_allocator(mallocFunc, reallocFunc, callocFunc, freeFunc));
868  }
869 
874  static std::array<double, 3> loadAverage() noexcept {
875  std::array<double, 3> avg;
876  uv_loadavg(avg.data());
877  return avg;
878  }
879 
887  static char ** setupArgs(int argc, char** argv) {
888  return uv_setup_args(argc, argv);
889  }
890 
895  static std::string processTitle() {
896  std::size_t size = details::DEFAULT_SIZE;
897  char buf[details::DEFAULT_SIZE];
898  std::string str{};
899 
900  if(0 == uv_get_process_title(buf, size)) {
901  str.assign(buf, size);
902  }
903 
904  return str;
905  }
906 
912  static bool processTitle(std::string title) {
913  return (0 == uv_set_process_title(title.c_str()));
914  }
915 
920  static uint64_t totalMemory() noexcept {
921  return uv_get_total_memory();
922  }
923 
935  static uint64_t constrainedMemory() noexcept {
936  return uv_get_constrained_memory();
937  }
938 
943  static double uptime() noexcept {
944  double ret;
945 
946  if(0 != uv_uptime(&ret)) {
947  ret = 0;
948  }
949 
950  return ret;
951  }
952 
957  static RUsage rusage() noexcept {
958  RUsage ru;
959  auto err = uv_getrusage(&ru);
960  return err ? RUsage{} : ru;
961  }
962 
973  static uint64_t hrtime() noexcept {
974  return uv_hrtime();
975  }
976 
981  static std::string path() noexcept {
982  return details::tryRead(&uv_exepath);
983  }
984 
989  static std::string cwd() noexcept {
990  return details::tryRead(&uv_cwd);
991  }
992 
998  static bool chdir(const std::string &dir) noexcept {
999  return (0 == uv_chdir(dir.data()));
1000  }
1001 
1008  uv_timeval64_t ret;
1009  uv_gettimeofday(&ret);
1010  return ret;
1011  }
1012 };
1013 
1014 
1015 }
Address representation.
Definition: util.hpp:342
constexpr FileHandle StdERR
Definition: util.hpp:197
auto gid() const noexcept
Gets the gid.
Definition: util.hpp:241
std::string version() const noexcept
Gets the operating system version.
Definition: util.hpp:306
unsigned int port
Definition: util.hpp:344
static Passwd passwd() noexcept
Gets a subset of the password file entry.
Definition: util.hpp:625
static HandleType guessHandle(FileHandle file) noexcept
Gets the type of the stream to be used with the given descriptor.
Definition: util.hpp:743
static std::string hostname() noexcept
Returns the hostname.
Definition: util.hpp:594
static std::string env(const std::string &name) noexcept
Retrieves an environment variable.
Definition: util.hpp:543
static std::vector< InterfaceAddress > interfaceAddresses() noexcept
Gets a set of descriptors of all the available interfaces.
Definition: util.hpp:781
std::string ip
Definition: util.hpp:343
std::string release() const noexcept
Gets the operating system release (like "2.6.28").
Definition: util.hpp:298
uv_timespec_t TimeSpec
Definition: util.hpp:199
static double uptime() noexcept
Gets the current system uptime.
Definition: util.hpp:943
details::UVTypeWrapper< uv_file > FileHandle
Definition: util.hpp:190
static std::string tmpdir() noexcept
Gets the temp directory.
Definition: util.hpp:533
static std::string homedir() noexcept
Gets the current user&#39;s home directory.
Definition: util.hpp:520
uv_rusage_t RUsage
Definition: util.hpp:207
static PidType pid() noexcept
Returns the current process id.
Definition: util.hpp:493
Windows size representation.
Definition: util.hpp:181
details::UVTypeWrapper< uv_os_fd_t > OSFileDescriptor
Definition: util.hpp:192
std::string machine() const noexcept
Gets the hardware identifier.
Definition: util.hpp:314
static int osPriority(PidType pid)
Retrieves the scheduling priority of a process.
Definition: util.hpp:650
constexpr FileHandle StdIN
Definition: util.hpp:195
static char ** setupArgs(int argc, char **argv)
Store the program arguments.
Definition: util.hpp:887
CPU information.
Definition: util.hpp:351
uv_timeval_t TimeVal
Definition: util.hpp:205
std::string username() const noexcept
Gets the username.
Definition: util.hpp:225
constexpr FileHandle StdOUT
Definition: util.hpp:196
Utility class to handle flags.
Definition: util.hpp:83
details::UVTypeWrapper< uv_pid_t > PidType
Definition: util.hpp:193
constexpr Flags operator &(const Flags &f) const noexcept
And operator.
Definition: util.hpp:152
constexpr Flags(E flag) noexcept
Constructs a Flags object from a value of the enum E.
Definition: util.hpp:104
OS dedicated utilities.
Definition: util.hpp:483
constexpr Flags operator|(const Flags &f) const noexcept
Or operator.
Definition: util.hpp:138
static bool osPriority(PidType pid, int prio)
Sets the scheduling priority of a process.
Definition: util.hpp:675
static uint64_t hrtime() noexcept
Gets the current high-resolution real time.
Definition: util.hpp:973
The IPv6 tag.
Definition: util.hpp:336
static TimeVal64 timeOfDay()
Cross-platform implementation of gettimeofday
Definition: util.hpp:1007
static UtsName uname() noexcept
Gets name and information about the current kernel.
Definition: util.hpp:607
static bool replaceAllocator(MallocFuncType mallocFunc, ReallocFuncType reallocFunc, CallocFuncType callocFunc, FreeFuncType freeFunc) noexcept
Override the use of some standard library’s functions.
Definition: util.hpp:866
details::UVTypeWrapper< uv_handle_type > HandleCategory
Definition: util.hpp:189
uv_gid_t Gid
Definition: util.hpp:203
static bool env(const std::string &name, const std::string &value) noexcept
Creates, updates or deletes an environment variable.
Definition: util.hpp:554
static RUsage rusage() noexcept
Gets the resource usage measures for the current process.
Definition: util.hpp:957
uv_uid_t Uid
Definition: util.hpp:202
Interface address.
Definition: util.hpp:370
static uint64_t totalMemory() noexcept
Gets memory information (in bytes).
Definition: util.hpp:920
uv_statfs_t Statfs
Definition: util.hpp:201
int height
Definition: util.hpp:183
auto uid() const noexcept
Gets the uid.
Definition: util.hpp:233
std::string shell() const noexcept
Gets the shell.
Definition: util.hpp:249
static std::string indexToName(unsigned int index) noexcept
IPv6-capable implementation of if_indextoname.
Definition: util.hpp:825
CPUTime times
CPU times.
Definition: util.hpp:363
static std::string cwd() noexcept
Gets the current working directory.
Definition: util.hpp:989
static std::string path() noexcept
Gets the executable path.
Definition: util.hpp:981
details::UVTypeWrapper< uv_os_sock_t > OSSocketHandle
Definition: util.hpp:191
static PidType parent() noexcept
Returns the parent process id.
Definition: util.hpp:506
int width
Definition: util.hpp:182
constexpr Flags()
Constructs an uninitialized Flags object.
Definition: util.hpp:116
std::string name
Definition: util.hpp:371
static HandleType guessHandle(HandleCategory category) noexcept
Gets the type of the handle given a category.
Definition: util.hpp:684
int speed
Definition: util.hpp:355
std::string model
Definition: util.hpp:354
constexpr Flags(Type f)
Constructs a Flags object from an instance of the underlying type of the enum E.
Definition: util.hpp:111
constexpr Flags operator|(E flag) const noexcept
Or operator.
Definition: util.hpp:145
std::string sysname() const noexcept
Gets the operating system name (like "Linux").
Definition: util.hpp:290
static std::vector< CPUInfo > cpuInfo() noexcept
Gets information about the CPUs on the system.
Definition: util.hpp:756
Utility class.
Definition: util.hpp:218
uv_stat_t Stat
Definition: util.hpp:200
static bool chdir(const std::string &dir) noexcept
Changes the current working directory.
Definition: util.hpp:998
constexpr Flags operator &(E flag) const noexcept
And operator.
Definition: util.hpp:159
static std::array< double, 3 > loadAverage() noexcept
Gets the load average.
Definition: util.hpp:874
Utility class.
Definition: util.hpp:283
static constexpr Flags< E > from()
Utility factory method to pack a set of values all at once.
Definition: util.hpp:96
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.
Definition: util.hpp:573
The IPv4 tag.
Definition: util.hpp:328
static bool processTitle(std::string title)
Sets the current process title.
Definition: util.hpp:912
Miscellaneous utilities.
Definition: util.hpp:474
static std::string processTitle()
Gets the title of the current process.
Definition: util.hpp:895
static uint64_t constrainedMemory() noexcept
Gets the amount of memory available to the process (in bytes).
Definition: util.hpp:935
uv_timeval64_t TimeVal64
Definition: util.hpp:206
std::string homedir() const noexcept
Gets the homedir.
Definition: util.hpp:257
static std::string indexToIid(unsigned int index) noexcept
Retrieves a network interface identifier.
Definition: util.hpp:839
uvw default namespace.
Definition: async.hpp:11