aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbutl/buildfile1
-rw-r--r--libbutl/uuid-openbsd.cxx80
2 files changed, 81 insertions, 0 deletions
diff --git a/libbutl/buildfile b/libbutl/buildfile
index a7b20f3..4dd952c 100644
--- a/libbutl/buildfile
+++ b/libbutl/buildfile
@@ -39,6 +39,7 @@ lib{butl}: cxx{uuid-linux}: include = ($tclass == 'linux')
lib{butl}: cxx{uuid-macos}: include = ($tclass == 'macos')
lib{butl}: cxx{uuid-windows}: include = $windows
lib{butl}: cxx{uuid-freebsd}: include = ($tsys == 'freebsd' || $tsys == 'netbsd')
+lib{butl}: cxx{uuid-openbsd}: include = ($tsys == 'openbsd')
# GCC prior to version 6 has flaky `#pragma GCC diagnostic` so we have to
# disable certain warnings outright.
diff --git a/libbutl/uuid-openbsd.cxx b/libbutl/uuid-openbsd.cxx
new file mode 100644
index 0000000..b64436b
--- /dev/null
+++ b/libbutl/uuid-openbsd.cxx
@@ -0,0 +1,80 @@
+// file : libbutl/uuid-openbsd.cxx -*- C++ -*-
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BUILD2_BOOTSTRAP
+
+#include <libbutl/uuid.hxx>
+
+#include <uuid.h>
+
+#include <errno.h>
+
+#include <cassert>
+#include <cstring> // memcpy()
+#include <system_error>
+
+using namespace std;
+
+namespace butl
+{
+ void
+ uuid_throw_weak (); // uuid.cxx
+
+ uuid uuid_system_generator::
+ generate (bool strong)
+ {
+ // The OpenBSD uuid_*() (<uuid.h>, uuid_compare(3)) API generates version
+ // 4 UUIDs (i.e. randomly generated) at least from version 6.4. For now we
+ // will assume that only random ones are strong.
+ //
+ // Here we assume uuid_t has the same definition as in FreeBSD/NetBSD (it
+ // is defined in <sys/uuid.h>).
+ //
+ uuid_t d;
+ uint32_t s;
+ uuid_create (&d, &s);
+
+ // None of the uuid_s_* errors seem plausible for this function so let's
+ // return the generic "not supported" error code.
+ //
+ if (s != uuid_s_ok)
+ throw system_error (ENOSYS, system_category ());
+
+ uuid r;
+
+ // This is effectively just memcpy() but let's reference the member names
+ // in case anything changes on either side.
+ //
+ r.time_low = d.time_low;
+ r.time_mid = d.time_mid;
+ r.time_hiv = d.time_hi_and_version;
+ r.clock_seq_hir = d.clock_seq_hi_and_reserved;
+ r.clock_seq_low = d.clock_seq_low;
+ memcpy (r.node, d.node, 6);
+
+ assert (r.variant () == uuid_variant::dce); // Sanity check.
+
+ if (strong)
+ {
+ switch (r.version ())
+ {
+ case uuid_version::random: break;
+ default: uuid_throw_weak ();
+ }
+ }
+
+ return r;
+ }
+
+ void uuid_system_generator::
+ initialize ()
+ {
+ }
+
+ void uuid_system_generator::
+ terminate ()
+ {
+ }
+}
+
+#endif // BUILD2_BOOTSTRAP