1 // Copyright 2024 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 5 package unix
6 7 import (
8 "sync"
9 "syscall"
10 )
11 12 // KernelVersion returns major and minor kernel version numbers
13 // parsed from the syscall.Sysctl("kern.osrelease")'s value,
14 // or (0, 0) if the version can't be obtained or parsed.
15 func KernelVersion() (major, minor int) {
16 release, err := syscall.Sysctl("kern.osrelease")
17 if err != nil {
18 return 0, 0
19 }
20 21 parseNext := func() (n int) {
22 for i, c := range release {
23 if c == '.' {
24 release = release[i+1:]
25 return
26 }
27 if '0' <= c && c <= '9' {
28 n = n*10 + int(c-'0')
29 }
30 }
31 release = ""
32 return
33 }
34 35 major = parseNext()
36 minor = parseNext()
37 38 return
39 }
40 41 // SupportCopyFileRange reports whether the kernel supports the copy_file_range(2).
42 // This function will examine both the kernel version and the availability of the system call.
43 var SupportCopyFileRange = sync.OnceValue(func() bool {
44 // The copy_file_range() function first appeared in FreeBSD 13.0.
45 major, _ := KernelVersion()
46 _, err := CopyFileRange(0, nil, 0, nil, 0, 0)
47 return major >= 13 && err != syscall.ENOSYS
48 })
49