diff --git a/uname/LICENSE.BSD b/uname/LICENSE.BSD new file mode 100644 index 0000000..2a7cf70 --- /dev/null +++ b/uname/LICENSE.BSD @@ -0,0 +1,27 @@ +Copyright 2009 The Go Authors. + +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. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +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 COPYRIGHT +OWNER 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. diff --git a/uname/go.mod b/uname/go.mod new file mode 100644 index 0000000..1e8bd9e --- /dev/null +++ b/uname/go.mod @@ -0,0 +1,3 @@ +module github.com/moby/sys/uname + +go 1.18 diff --git a/uname/kernel_version_ge.go b/uname/kernel_version_ge.go new file mode 100644 index 0000000..78e2ff0 --- /dev/null +++ b/uname/kernel_version_ge.go @@ -0,0 +1,11 @@ +// Copyright 2025 The uname Authors. + +package uname + +// KernelVersionGE checks if the running kernel version +// is greater than or equal to the provided version. +func KernelVersionGE(x, y int) bool { + xx, yy := KernelVersion() + + return xx > x || (xx == x && yy >= y) +} diff --git a/uname/kernel_version_ge_test.go b/uname/kernel_version_ge_test.go new file mode 100644 index 0000000..4d53950 --- /dev/null +++ b/uname/kernel_version_ge_test.go @@ -0,0 +1,64 @@ +// Copyright 2025 The uname Authors. + +package uname + +import ( + "testing" +) + +func TestKernelVersionGE(t *testing.T) { + major, minor := KernelVersion() + t.Logf("Running on kernel %d.%d", major, minor) + + tests := []struct { + name string + x, y int + want bool + }{ + { + name: "current version equals itself", + x: major, + y: minor, + want: true, + }, + { + name: "older major version", + x: major - 1, + y: 0, + want: true, + }, + { + name: "same major, older minor version", + x: major, + y: minor - 1, + want: true, + }, + { + name: "newer major version", + x: major + 1, + y: 0, + want: false, + }, + { + name: "same major, newer minor version", + x: major, + y: minor + 1, + want: false, + }, + { + name: "min version (0.0)", + x: 0, + y: 0, + want: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := KernelVersionGE(tt.x, tt.y) + if got != tt.want { + t.Errorf("KernelVersionGE(%d, %d): got %v, want %v", tt.x, tt.y, got, tt.want) + } + }) + } +} diff --git a/uname/kernel_version_linux.go b/uname/kernel_version_linux.go new file mode 100644 index 0000000..6b0bb01 --- /dev/null +++ b/uname/kernel_version_linux.go @@ -0,0 +1,40 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.BSD file. + +package uname + +import ( + "syscall" +) + +// KernelVersion returns major and minor kernel version numbers +// parsed from the [syscall.Uname] Release field, or (0, 0) if +// the version can't be obtained or parsed. +func KernelVersion() (major, minor int) { + var uname syscall.Utsname + if err := syscall.Uname(&uname); err != nil { + return + } + + var ( + values [2]int + value, vi int + ) + for _, c := range uname.Release { + if '0' <= c && c <= '9' { + value = (value * 10) + int(c-'0') + } else { + // Note that we're assuming N.N.N here. + // If we see anything else, we are likely to mis-parse it. + values[vi] = value + vi++ + if vi >= len(values) { + break + } + value = 0 + } + } + + return values[0], values[1] +} diff --git a/uname/kernel_version_other.go b/uname/kernel_version_other.go new file mode 100644 index 0000000..e190481 --- /dev/null +++ b/uname/kernel_version_other.go @@ -0,0 +1,11 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.BSD file. + +//go:build !linux + +package uname + +func KernelVersion() (major int, minor int) { + return 0, 0 +} diff --git a/uname/kernel_version_test.go b/uname/kernel_version_test.go new file mode 100644 index 0000000..c38fa45 --- /dev/null +++ b/uname/kernel_version_test.go @@ -0,0 +1,27 @@ +// Copyright 2025 The uname Authors. +package uname + +import ( + "runtime" + "testing" +) + +func TestKernelVersion(t *testing.T) { + x, y := KernelVersion() + t.Logf("KernelVersion: %d.%d (GOOS: %s)", x, y, runtime.GOOS) + switch runtime.GOOS { + case "linux": + // Go requires Linux >= 2.x. + if x < 2 { + t.Errorf("want major >= 2, got %d", x) + } + // Sanity check. + if y < 0 { + t.Errorf("want minor >= 0, got %d", y) + } + default: + if x != 0 || y != 0 { + t.Fatalf("want 0.0, got %d.%d", x, y) + } + } +}