powerd++  0.4.4
sysctl.hpp
Go to the documentation of this file.
1 
7 #ifndef _POWERDXX_SYS_SYSCTL_HPP_
8 #define _POWERDXX_SYS_SYSCTL_HPP_
9 
10 #include "error.hpp" /* sys::sc_error */
11 
12 #include <memory> /* std::unique_ptr */
13 
14 #include <cassert> /* assert() */
15 
16 #include <sys/types.h> /* sysctl() */
17 #include <sys/sysctl.h> /* sysctl() */
18 
19 namespace sys {
20 
32 namespace ctl {
33 
37 struct error {};
38 
42 typedef int mib_t;
43 
58 inline void sysctl_raw(mib_t const * name, u_int const namelen,
59  void * const oldp, size_t * const oldlenp,
60  void const * const newp, size_t const newlen) {
61  if (sysctl(name, namelen, oldp, oldlenp, newp, newlen) == -1) {
62  throw sc_error<error>{errno};
63  }
64 }
65 
78 template <size_t MibDepth>
79 void sysctl_get(mib_t const (& mib)[MibDepth], void * const oldp, size_t & oldlen) {
80  sysctl_raw(mib, MibDepth, oldp, &oldlen, nullptr, 0);
81 }
82 
95 template <size_t MibDepth>
96 void sysctl_set(mib_t const (& mib)[MibDepth], void const * const newp,
97  size_t const newlen) {
98  sysctl_raw(mib, MibDepth, nullptr, nullptr, newp, newlen);
99 }
100 
123 template <size_t MibDepth>
124 class Sysctl {
125  private:
129  mib_t mib[MibDepth];
130 
131  public:
148  template <typename... Tail>
149  constexpr Sysctl(mib_t const head, Tail const... tail) noexcept :
150  mib{head, tail...} {
151  static_assert(MibDepth == sizeof...(Tail) + 1,
152  "MIB depth mismatch");
153  }
154 
161  size_t size() const
162  {
163  size_t len = 0;
164  sysctl_get(this->mib, nullptr, len);
165  return len;
166  }
167 
179  void get(void * const buf, size_t const bufsize) const {
180  auto len = bufsize;
181  sysctl_get(this->mib, buf, len);
182  }
183 
197  template <typename T>
198  void get(T & value) const {
199  get(&value, sizeof(T));
200  }
201 
217  template <typename T>
218  std::unique_ptr<T[]> get() const {
219  auto const len = size();
220  auto result = std::unique_ptr<T[]>(new T[len / sizeof(T)]);
221  get(result.get(), len);
222  return result;
223  }
224 
233  void set(void const * const buf, size_t const bufsize) {
234  sysctl_set(this->mib, buf, bufsize);
235  }
236 
245  template <typename T>
246  void set(T const & value) {
247  set(&value, sizeof(T));
248  }
249 };
250 
259 template <>
260 class Sysctl<0> {
261  private:
265  mib_t mib[CTL_MAXNAME];
266 
270  size_t depth;
271 
272  public:
278  constexpr Sysctl() : mib{}, depth{0} {}
279 
289  Sysctl(char const * const name) : depth{CTL_MAXNAME} {
290  if (sysctlnametomib(name, this->mib, &this->depth) == -1) {
291  throw sc_error<error>{errno};
292  }
293  assert(this->depth <= CTL_MAXNAME && "MIB depth exceeds limit");
294  }
295 
299  size_t size() const
300  {
301  size_t len = 0;
302  sysctl_raw(this->mib, this->depth, nullptr, &len, nullptr, 0);
303  return len;
304  }
305 
309  void get(void * const buf, size_t const bufsize) const {
310  auto len = bufsize;
311  sysctl_raw(this->mib, this->depth, buf, &len, nullptr, 0);
312  }
313 
317  template <typename T>
318  void get(T & value) const {
319  get(&value, sizeof(T));
320  }
321 
325  template <typename T>
326  std::unique_ptr<T[]> get() const {
327  size_t const len = size();
328  auto result = std::unique_ptr<T[]>(new T[len / sizeof(T)]);
329  get(result.get(), len);
330  return result;
331  }
332 
336  void set(void const * const buf, size_t const bufsize) {
337  sysctl_raw(this->mib, this->depth, nullptr, nullptr, buf, bufsize);
338  }
339 
343  template <typename T>
344  void set(T const & value) {
345  set(&value, sizeof(T));
346  }
347 };
348 
355 template <typename ... ArgTs>
356 Sysctl(mib_t const, ArgTs const ...) -> Sysctl<(1 + sizeof...(ArgTs))>;
357 
361 Sysctl(char const * const) -> Sysctl<0>;
362 
366 Sysctl() -> Sysctl<0>;
367 
387 template <typename T, class SysctlT>
388 class Sync {
389  private:
393  SysctlT sysctl;
394 
395  public:
403  constexpr Sync() {}
404 
411  constexpr Sync(SysctlT const & sysctl) noexcept : sysctl{sysctl} {}
412 
422  Sync & operator =(T const & value) {
423  this->sysctl.set(value);
424  return *this;
425  }
426 
433  operator T () const {
434  T value;
435  this->sysctl.get(value);
436  return value;
437  }
438 };
439 
456 template <typename T, size_t MibDepth = 0>
458 
487 template <typename T, class SysctlT>
488 class Once {
489  private:
493  T value;
494 
495  public:
507  Once(T const & value, SysctlT const & sysctl) noexcept {
508  try {
509  sysctl.get(this->value);
510  } catch (sc_error<error>) {
511  this->value = value;
512  }
513  }
514 
521  operator T const &() const {
522  return this->value;
523  }
524 };
525 
539 template <typename T, size_t MibDepth = 0>
541 
542 } /* namespace ctl */
543 } /* namespace sys */
544 
545 #endif /* _POWERDXX_SYS_SYSCTL_HPP_ */
sys::ctl::Sync
This is a wrapper around Sysctl that allows semantically transparent use of a sysctl.
Definition: sysctl.hpp:388
sys::ctl::Once::value
T value
The sysctl value read upon construction.
Definition: sysctl.hpp:493
sys::ctl::Sysctl< 0 >::set
void set(void const *const buf, size_t const bufsize)
Update the the sysctl value with the given buffer.
Definition: sysctl.hpp:336
sys::ctl::Sysctl< 0 >::get
std::unique_ptr< T[]> get() const
Retrieve an array from the sysctl address.
Definition: sysctl.hpp:326
sys::ctl::Sysctl< 0 >::Sysctl
constexpr Sysctl()
The default constructor.
Definition: sysctl.hpp:278
sys::ctl::sysctl_get
void sysctl_get(mib_t const (&mib)[MibDepth], void *const oldp, size_t &oldlen)
Returns a sysctl() value to a buffer.
Definition: sysctl.hpp:79
sys::sc_error
Can be thrown by syscall function wrappers if the function returned with an error.
Definition: error.hpp:26
sys::ctl::Once::Once
Once(T const &value, SysctlT const &sysctl) noexcept
The constructor tries to read and store the requested sysctl.
Definition: sysctl.hpp:507
sys
Wrappers around native system interfaces.
sys::ctl::sysctl_raw
void sysctl_raw(mib_t const *name, u_int const namelen, void *const oldp, size_t *const oldlenp, void const *const newp, size_t const newlen)
A wrapper around the sysctl() function.
Definition: sysctl.hpp:58
sys::ctl::Sync::Sync
constexpr Sync()
The default constructor.
Definition: sysctl.hpp:403
sys::ctl::error
The domain error type.
Definition: sysctl.hpp:37
sys::ctl::Sysctl::get
std::unique_ptr< T[]> get() const
Retrieve an array from the sysctl address.
Definition: sysctl.hpp:218
sys::ctl::Sysctl< 0 >::size
size_t size() const
The size of the sysctl.
Definition: sysctl.hpp:299
sysctlnametomib
int sysctlnametomib(const char *name, int *mibp, size_t *sizep)
Intercept calls to sysctlnametomib().
Definition: libloadplay.cpp:1708
sys::ctl::Sysctl::set
void set(void const *const buf, size_t const bufsize)
Update the the sysctl value with the given buffer.
Definition: sysctl.hpp:233
sys::ctl::Sysctl< 0 >::get
void get(T &value) const
Update the given value with a value retreived from the sysctl.
Definition: sysctl.hpp:318
sys::ctl::Sysctl::get
void get(void *const buf, size_t const bufsize) const
Update the given buffer with a value retrieved from the sysctl.
Definition: sysctl.hpp:179
sys::ctl::Sysctl< 0 >::set
void set(T const &value)
Update the the sysctl value with the given value.
Definition: sysctl.hpp:344
sys::ctl::Sysctl< 0 >::Sysctl
Sysctl(char const *const name)
Initialise the MIB address from a character string.
Definition: sysctl.hpp:289
sys::ctl::Sysctl::size
size_t size() const
The size of the sysctl.
Definition: sysctl.hpp:161
sys::ctl::Sysctl
Represents a sysctl MIB address.
Definition: sysctl.hpp:124
sys::ctl::Sysctl::get
void get(T &value) const
Update the given value with a value retreived from the sysctl.
Definition: sysctl.hpp:198
sys::ctl::Sysctl< 0 >::depth
size_t depth
The MIB depth.
Definition: sysctl.hpp:270
sys::ctl::Sysctl::mib
mib_t mib[MibDepth]
Stores the MIB address.
Definition: sysctl.hpp:129
sys::ctl::Sysctl::set
void set(T const &value)
Update the the sysctl value with the given value.
Definition: sysctl.hpp:246
sys::ctl::Sysctl< 0 >::get
void get(void *const buf, size_t const bufsize) const
Update the given buffer with a value retrieved from the sysctl.
Definition: sysctl.hpp:309
sys::ctl::Sysctl::Sysctl
constexpr Sysctl(mib_t const head, Tail const ... tail) noexcept
Initialise the MIB address directly.
Definition: sysctl.hpp:149
sysctl
int sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen)
Functions to intercept.
Definition: libloadplay.cpp:1655
sys::ctl::Sync::Sync
constexpr Sync(SysctlT const &sysctl) noexcept
The constructor copies the given Sysctl instance.
Definition: sysctl.hpp:411
sys::ctl::Sysctl
Sysctl(mib_t const, ArgTs const ...) -> Sysctl<(1+sizeof...(ArgTs))>
Create a Sysctl from a set of predefined MIBs.
sys::ctl::Once
A read once representation of a Sysctl.
Definition: sysctl.hpp:488
sys::ctl::mib_t
int mib_t
Management Information Base identifier type (see sysctl(3)).
Definition: sysctl.hpp:42
sys::ctl::Sync::sysctl
SysctlT sysctl
A sysctl to represent.
Definition: sysctl.hpp:393
sys::ctl::Sync::operator=
Sync & operator=(T const &value)
Transparently assiges values of type T to the represented Sysctl instance.
Definition: sysctl.hpp:422
sys::ctl::sysctl_set
void sysctl_set(mib_t const (&mib)[MibDepth], void const *const newp, size_t const newlen)
Sets a sysctl() value.
Definition: sysctl.hpp:96
error.hpp
Provides system call error handling.