uvw  2.11.0
util.h
1 #ifndef UVW_UTIL_INCLUDE_H
2 #define UVW_UTIL_INCLUDE_H
3 
4 
5 #include <string_view>
6 #include <type_traits>
7 #include <cstddef>
8 #include <utility>
9 #include <string>
10 #include <vector>
11 #include <memory>
12 #include <array>
13 #include <uv.h>
14 
15 
16 namespace uvw {
17 
18 
19 namespace details {
20 
21 
22 enum class UVHandleType: std::underlying_type_t<uv_handle_type> {
23  UNKNOWN = UV_UNKNOWN_HANDLE,
24  ASYNC = UV_ASYNC,
25  CHECK = UV_CHECK,
26  FS_EVENT = UV_FS_EVENT,
27  FS_POLL = UV_FS_POLL,
28  HANDLE = UV_HANDLE,
29  IDLE = UV_IDLE,
30  PIPE = UV_NAMED_PIPE,
31  POLL = UV_POLL,
32  PREPARE = UV_PREPARE,
33  PROCESS = UV_PROCESS,
34  STREAM = UV_STREAM,
35  TCP = UV_TCP,
36  TIMER = UV_TIMER,
37  TTY = UV_TTY,
38  UDP = UV_UDP,
39  SIGNAL = UV_SIGNAL,
40  FILE = UV_FILE
41 };
42 
43 
44 template<typename T>
45 struct UVTypeWrapper {
46  using Type = T;
47 
48  constexpr UVTypeWrapper(): value{} {}
49  constexpr UVTypeWrapper(Type val): value{val} {}
50 
51  constexpr operator Type() const noexcept { return value; }
52 
53  bool operator==(UVTypeWrapper other) const noexcept {
54  return value == other.value;
55  }
56 
57 private:
58  const Type value;
59 };
60 
61 
62 template<typename T>
63 bool operator==(UVTypeWrapper<T> lhs, UVTypeWrapper<T> rhs) {
64  return !(lhs == rhs);
65 }
66 
67 
68 }
69 
70 
81 template<typename E>
82 class Flags final {
83  using InnerType = std::underlying_type_t<E>;
84 
85  constexpr InnerType toInnerType(E flag) const noexcept { return static_cast<InnerType>(flag); }
86 
87 public:
88  using Type = InnerType;
89 
94  template<E... V>
95  static constexpr Flags<E> from() {
96  return (Flags<E>{} | ... | V);
97  }
98 
103  constexpr Flags(E flag) noexcept: flags{toInnerType(flag)} {}
104 
110  constexpr Flags(Type f): flags{f} {}
111 
115  constexpr Flags(): flags{} {}
116 
117  constexpr Flags(const Flags &f) noexcept: flags{f.flags} { }
118  constexpr Flags(Flags &&f) noexcept: flags{std::move(f.flags)} { }
119 
120  ~Flags() noexcept { static_assert(std::is_enum_v<E>); }
121 
122  constexpr Flags & operator=(const Flags &f) noexcept {
123  flags = f.flags;
124  return *this;
125  }
126 
127  constexpr Flags & operator=(Flags &&f) noexcept {
128  flags = std::move(f.flags);
129  return *this;
130  }
131 
137  constexpr Flags operator|(const Flags &f) const noexcept { return Flags{flags | f.flags}; }
138 
144  constexpr Flags operator|(E flag) const noexcept { return Flags{flags | toInnerType(flag)}; }
145 
151  constexpr Flags operator&(const Flags &f) const noexcept { return Flags{flags & f.flags}; }
152 
158  constexpr Flags operator&(E flag) const noexcept { return Flags{flags & toInnerType(flag)}; }
159 
164  explicit constexpr operator bool() const noexcept { return !(flags == InnerType{}); }
165 
170  constexpr operator Type() const noexcept { return flags; }
171 
172 private:
173  InnerType flags;
174 };
175 
176 
180 struct WinSize {
181  int width;
182  int height;
183 };
184 
185 
186 using HandleType = details::UVHandleType;
188 using HandleCategory = details::UVTypeWrapper<uv_handle_type>;
189 using FileHandle = details::UVTypeWrapper<uv_file>;
190 using OSSocketHandle = details::UVTypeWrapper<uv_os_sock_t>;
191 using OSFileDescriptor = details::UVTypeWrapper<uv_os_fd_t>;
192 using PidType = details::UVTypeWrapper<uv_pid_t>;
194 constexpr FileHandle StdIN{0};
195 constexpr FileHandle StdOUT{1};
196 constexpr FileHandle StdERR{2};
198 using TimeSpec = uv_timespec_t;
199 using Stat = uv_stat_t;
200 using Statfs = uv_statfs_t;
201 using Uid = uv_uid_t;
202 using Gid = uv_gid_t;
204 using TimeVal = uv_timeval_t;
205 using TimeVal64 = uv_timeval64_t;
206 using RUsage = uv_rusage_t;
217 struct Passwd {
218  Passwd(std::shared_ptr<uv_passwd_t> pwd);
219 
224  std::string username() const noexcept;
225 
230  decltype(uv_passwd_t::uid) uid() const noexcept;
231 
236  decltype(uv_passwd_t::gid) gid() const noexcept;
237 
242  std::string shell() const noexcept;
243 
248  std::string homedir() const noexcept;
249 
254  operator bool() const noexcept;
255 
256 private:
257  std::shared_ptr<uv_passwd_t> passwd;
258 };
259 
260 
270 struct UtsName {
271  UtsName(std::shared_ptr<uv_utsname_t> utsname);
272 
277  std::string sysname() const noexcept;
278 
283  std::string release() const noexcept;
284 
289  std::string version() const noexcept;
290 
295  std::string machine() const noexcept;
296 
297 private:
298  std::shared_ptr<uv_utsname_t> utsname;
299 };
300 
301 
307 struct IPv4 {};
308 
309 
315 struct IPv6 {};
316 
317 
321 struct Addr {
322  std::string ip;
323  unsigned int port;
324 };
325 
326 
330 struct CPUInfo {
331  using CPUTime = decltype(uv_cpu_info_t::cpu_times);
332 
333  std::string model;
334  int speed;
342  CPUTime times;
343 };
344 
345 
350  std::string name;
351  char physical[6];
352  bool internal;
355 };
356 
357 
358 namespace details {
359 
360 
361 static constexpr std::size_t DEFAULT_SIZE = 128;
362 
363 
364 template<typename>
365 struct IpTraits;
366 
367 
368 template<>
369 struct IpTraits<IPv4> {
370  using Type = sockaddr_in;
371  using AddrFuncType = int(*)(const char *, int, Type *);
372  using NameFuncType = int(*)(const Type *, char *, std::size_t);
373  inline static const AddrFuncType addrFunc = &uv_ip4_addr;
374  inline static const NameFuncType nameFunc = &uv_ip4_name;
375  static constexpr auto sinPort(const Type *addr) { return addr->sin_port; }
376 };
377 
378 
379 template<>
380 struct IpTraits<IPv6> {
381  using Type = sockaddr_in6;
382  using AddrFuncType = int(*)(const char *, int, Type *);
383  using NameFuncType = int(*)(const Type *, char *, std::size_t);
384  inline static const AddrFuncType addrFunc = &uv_ip6_addr;
385  inline static const NameFuncType nameFunc = &uv_ip6_name;
386  static constexpr auto sinPort(const Type *addr) { return addr->sin6_port; }
387 };
388 
389 
390 template<typename I>
391 Addr address(const typename details::IpTraits<I>::Type *aptr) noexcept {
392  Addr addr{};
393  char name[DEFAULT_SIZE];
394 
395  int err = details::IpTraits<I>::nameFunc(aptr, name, DEFAULT_SIZE);
396 
397  if(0 == err) {
398  addr.port = ntohs(details::IpTraits<I>::sinPort(aptr));
399  addr.ip = std::string{name};
400  }
401 
402  return addr;
403 }
404 
405 
406 template<typename I, typename F, typename H>
407 Addr address(F &&f, const H *handle) noexcept {
408  sockaddr_storage ssto;
409  int len = sizeof(ssto);
410  Addr addr{};
411 
412  int err = std::forward<F>(f)(handle, reinterpret_cast<sockaddr *>(&ssto), &len);
413 
414  if(0 == err) {
415  typename IpTraits<I>::Type *aptr = reinterpret_cast<typename IpTraits<I>::Type *>(&ssto);
416  addr = address<I>(aptr);
417  }
418 
419  return addr;
420 }
421 
422 
423 template<typename F, typename... Args>
424 std::string tryRead(F &&f, Args&&... args) noexcept {
425  std::size_t size = DEFAULT_SIZE;
426  char buf[DEFAULT_SIZE];
427  std::string str{};
428  auto err = std::forward<F>(f)(args..., buf, &size);
429 
430  if(UV_ENOBUFS == err) {
431  std::unique_ptr<char[]> data{new char[size]};
432  err = std::forward<F>(f)(args..., data.get(), &size);
433 
434  if(0 == err) {
435  str = data.get();
436  }
437  } else if(0 == err) {
438  str.assign(buf, size);
439  }
440 
441  return str;
442 }
443 
444 
445 }
446 
447 
453 struct Utilities {
454  using MallocFuncType = void*(*)(size_t);
455  using ReallocFuncType = void*(*)(void*, size_t);
456  using CallocFuncType = void*(*)(size_t, size_t);
457  using FreeFuncType = void(*)(void*);
458 
462  struct OS {
472  static PidType pid() noexcept;
473 
483  static PidType parent() noexcept;
484 
495  static std::string homedir() noexcept;
496 
506  static std::string tmpdir() noexcept;
507 
514  static std::string env(const std::string &name) noexcept;
515 
523  static bool env(const std::string &name, const std::string &value) noexcept;
524 
538  template<typename Func>
539  static std::enable_if_t<std::is_invocable_v<Func, std::string_view, std::string_view>, bool>
540  env(Func func) noexcept {
541  uv_env_item_t *items = nullptr;
542  int count{};
543 
544  const bool ret = (uv_os_environ(&items, &count) == 0);
545 
546  if(ret) {
547  for(int pos = 0; pos < count; ++pos) {
548  func(std::string_view{items[pos].name}, std::string_view{items[pos].value});
549  }
550 
551  uv_os_free_environ(items, count);
552  }
553 
554  return ret;
555  }
556 
561  static std::string hostname() noexcept;
562 
572  static UtsName uname() noexcept;
573 
586  static Passwd passwd() noexcept;
587  };
588 
602  static int osPriority(PidType pid);
603 
619  static bool osPriority(PidType pid, int prio);
620 
626  static HandleType guessHandle(HandleCategory category) noexcept;
627 
646  static HandleType guessHandle(FileHandle file) noexcept;
647 
655  static std::vector<CPUInfo> cpuInfo() noexcept;
656 
665  static std::vector<InterfaceAddress> interfaceAddresses() noexcept;
666 
680  static std::string indexToName(unsigned int index) noexcept;
681 
692  static std::string indexToIid(unsigned int index) noexcept;
693 
717  static bool replaceAllocator(MallocFuncType mallocFunc, ReallocFuncType reallocFunc, CallocFuncType callocFunc, FreeFuncType freeFunc) noexcept;
718 
723  static std::array<double, 3> loadAverage() noexcept;
724 
732  static char ** setupArgs(int argc, char** argv);
733 
738  static std::string processTitle();
739 
745  static bool processTitle(const std::string &title);
746 
751  static uint64_t totalMemory() noexcept;
752 
764  static uint64_t constrainedMemory() noexcept;
765 
770  static double uptime() noexcept;
771 
776  static RUsage rusage() noexcept;
777 
788  static uint64_t hrtime() noexcept;
789 
794  static std::string path() noexcept;
795 
800  static std::string cwd() noexcept;
801 
807  static bool chdir(const std::string &dir) noexcept;
808 
814  static TimeVal64 timeOfDay() noexcept;
815 
820  static void sleep(unsigned int msec) noexcept;
821 };
822 
823 
828 template<class... Func>
829 struct Overloaded: Func... {
830  using Func::operator()...;
831 };
832 
833 
838 template<class... Func>
839 Overloaded(Func...) -> Overloaded<Func...>;
840 
841 
842 }
843 
844 
845 #ifndef UVW_AS_LIB
846 #include "util.cpp"
847 #endif
848 
849 
850 #endif // UVW_UTIL_INCLUDE_H
Utility class to handle flags.
Definition: util.h:82
constexpr Flags()
Constructs an uninitialized Flags object.
Definition: util.h:115
static constexpr Flags< E > from()
Utility factory method to pack a set of values all at once.
Definition: util.h:95
constexpr Flags operator|(const Flags &f) const noexcept
Or operator.
Definition: util.h:137
constexpr Flags(Type f)
Constructs a Flags object from an instance of the underlying type of the enum E.
Definition: util.h:110
constexpr Flags operator|(E flag) const noexcept
Or operator.
Definition: util.h:144
constexpr Flags operator&(const Flags &f) const noexcept
And operator.
Definition: util.h:151
constexpr Flags(E flag) noexcept
Constructs a Flags object from a value of the enum E.
Definition: util.h:103
constexpr Flags operator&(E flag) const noexcept
And operator.
Definition: util.h:158
uvw default namespace.
Definition: async.h:10
uv_uid_t Uid
Definition: util.h:201
details::UVTypeWrapper< uv_file > FileHandle
Definition: util.h:189
uv_statfs_t Statfs
Definition: util.h:200
details::UVTypeWrapper< uv_os_sock_t > OSSocketHandle
Definition: util.h:190
constexpr FileHandle StdIN
Definition: util.h:194
uv_timespec_t TimeSpec
Definition: util.h:198
uv_timeval_t TimeVal
Definition: util.h:204
uv_gid_t Gid
Definition: util.h:202
constexpr FileHandle StdOUT
Definition: util.h:195
uv_rusage_t RUsage
Definition: util.h:206
details::UVTypeWrapper< uv_handle_type > HandleCategory
Definition: util.h:188
details::UVTypeWrapper< uv_pid_t > PidType
Definition: util.h:192
constexpr FileHandle StdERR
Definition: util.h:196
uv_stat_t Stat
Definition: util.h:199
details::UVTypeWrapper< uv_os_fd_t > OSFileDescriptor
Definition: util.h:191
Overloaded(Func...) -> Overloaded< Func... >
Deduction guide.
uv_timeval64_t TimeVal64
Definition: util.h:205
Address representation.
Definition: util.h:321
unsigned int port
Definition: util.h:323
std::string ip
Definition: util.h:322
CPU information.
Definition: util.h:330
CPUTime times
CPU times.
Definition: util.h:342
std::string model
Definition: util.h:333
int speed
Definition: util.h:334
The IPv4 tag.
Definition: util.h:307
The IPv6 tag.
Definition: util.h:315
Interface address.
Definition: util.h:349
std::string name
Definition: util.h:350
Helper type for visitors.
Definition: util.h:829
Utility class.
Definition: util.h:217
std::string homedir() const noexcept
Gets the homedir.
std::string username() const noexcept
Gets the username.
decltype(uv_passwd_t::gid) gid() const noexcept
Gets the gid.
decltype(uv_passwd_t::uid) uid() const noexcept
Gets the uid.
std::string shell() const noexcept
Gets the shell.
OS dedicated utilities.
Definition: util.h:462
static std::string hostname() noexcept
Returns the hostname.
static PidType pid() noexcept
Returns the current process id.
Miscellaneous utilities.
Definition: util.h:453
Utility class.
Definition: util.h:270
std::string sysname() const noexcept
Gets the operating system name (like "Linux").
Windows size representation.
Definition: util.h:180
int height
Definition: util.h:182
int width
Definition: util.h:181