1
2
3
4
5 package unix
6
7 import (
8 "runtime"
9 "sync"
10 "syscall"
11 "unsafe"
12 )
13
14
15
16 var procUname uintptr
17
18
19 type utsname struct {
20 Sysname [257]byte
21 Nodename [257]byte
22 Release [257]byte
23 Version [257]byte
24 Machine [257]byte
25 }
26
27
28
29
30 func KernelVersion() (major int, minor int) {
31 var un utsname
32 _, _, errno := rawSyscall6(uintptr(unsafe.Pointer(&procUname)), 1, uintptr(unsafe.Pointer(&un)), 0, 0, 0, 0, 0)
33 if errno != 0 {
34 return 0, 0
35 }
36
37
38
39
40 ver := un.Version[:]
41 if runtime.GOOS == "illumos" {
42
43
44
45
46 ver = un.Release[:]
47 }
48
49 parseNext := func() (n int) {
50 for i, c := range ver {
51 if c == '.' {
52 ver = ver[i+1:]
53 return
54 }
55 if '0' <= c && c <= '9' {
56 n = n*10 + int(c-'0')
57 }
58 }
59 ver = nil
60 return
61 }
62
63 major = parseNext()
64 minor = parseNext()
65
66 return
67 }
68
69
70
71 var SupportSockNonblockCloexec = sync.OnceValue(func() bool {
72
73 s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, 0)
74 if err == nil {
75 syscall.Close(s)
76 return true
77 }
78 if err != syscall.EPROTONOSUPPORT && err != syscall.EINVAL {
79
80 if runtime.GOOS == "illumos" {
81 return KernelVersionGE(5, 11)
82 }
83 return KernelVersionGE(11, 4)
84 }
85 return false
86 })
87
88
89 var SupportAccept4 = sync.OnceValue(func() bool {
90 for {
91
92 _, _, err := syscall.Accept4(0, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC)
93 if err == syscall.EINTR {
94 continue
95 }
96 return err != syscall.ENOSYS
97 }
98 })
99
100
101
102 var SupportTCPKeepAliveIdleIntvlCNT = sync.OnceValue(func() bool {
103 return KernelVersionGE(11, 4)
104 })
105
View as plain text