From 8c1d78873d105280e3d7d9bff52052064ba526f2 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 5 May 2020 14:30:22 +0200
Subject: [PATCH] system/KernelVersion: new library

---
 src/system/KernelVersion.cxx | 71 ++++++++++++++++++++++++++++++++++++
 src/system/KernelVersion.hxx | 58 +++++++++++++++++++++++++++++
 src/system/meson.build       |  1 +
 3 files changed, 130 insertions(+)
 create mode 100644 src/system/KernelVersion.cxx
 create mode 100644 src/system/KernelVersion.hxx

diff --git a/src/system/KernelVersion.cxx b/src/system/KernelVersion.cxx
new file mode 100644
index 000000000..52da082cf
--- /dev/null
+++ b/src/system/KernelVersion.cxx
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020 CM4all GmbH
+ * All rights reserved.
+ *
+ * author: Max Kellermann <mk@cm4all.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "KernelVersion.hxx"
+
+#include <sys/utsname.h>
+#include <stdio.h>
+
+gcc_const
+static KernelVersionCode
+GetKernelVersionCode() noexcept
+{
+	struct utsname u;
+	if (uname(&u) != 0)
+		return {};
+
+	unsigned major, minor, patch;
+	switch (sscanf(u.release, "%u.%u.%u", &major, &minor, &patch)) {
+	case 1:
+		minor = patch = 0;
+		break;
+
+	case 2:
+		patch = 0;
+		break;
+
+	case 3:
+		break;
+
+	default:
+		return {};
+	}
+
+	return {major, minor, patch};
+}
+
+bool
+IsKernelVersionOrNewer(KernelVersionCode v) noexcept
+{
+	static const auto kernel_version_code = GetKernelVersionCode();
+	return kernel_version_code >= v;
+}
diff --git a/src/system/KernelVersion.hxx b/src/system/KernelVersion.hxx
new file mode 100644
index 000000000..51710787e
--- /dev/null
+++ b/src/system/KernelVersion.hxx
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2020 CM4all GmbH
+ * All rights reserved.
+ *
+ * author: Max Kellermann <mk@cm4all.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "util/Compiler.h"
+
+class KernelVersionCode {
+	unsigned value = 0;
+
+public:
+	constexpr KernelVersionCode() noexcept = default;
+
+	constexpr KernelVersionCode(unsigned major,
+				    unsigned minor=0,
+				    unsigned patch=0) noexcept
+		:value((major << 16) | (minor << 8) | patch) {}
+
+	constexpr bool operator>=(KernelVersionCode other) const noexcept {
+		return value >= other.value;
+	}
+};
+
+/**
+ * Is the currently running Linux kernel at least the given version?
+ */
+gcc_const
+bool
+IsKernelVersionOrNewer(KernelVersionCode v) noexcept;
diff --git a/src/system/meson.build b/src/system/meson.build
index 509783463..e9ee888b1 100644
--- a/src/system/meson.build
+++ b/src/system/meson.build
@@ -6,6 +6,7 @@ system_sources = [
 
 if host_machine.system() == 'linux'
   system_sources += [
+    'KernelVersion.cxx',
     'EventFD.cxx',
     'SignalFD.cxx',
     'EpollFD.cxx',