// Copyright 2024 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 file.

package unix

import (
	"runtime"
	"sync"
	"syscall"
	"unsafe"
)

//go:linkname procUname libc_uname

var procUname uintptr

// utsname represents the fields of a struct utsname defined in <sys/utsname.h>.
type utsname struct {
	Sysname  [257]byte
	Nodename [257]byte
	Release  [257]byte
	Version  [257]byte
	Machine  [257]byte
}

// KernelVersion returns major and minor kernel version numbers
// parsed from the syscall.Uname's Version field, or (0, 0) if the
// version can't be obtained or parsed.
func KernelVersion() (major int, minor int) {
	var un utsname
	_, _, errno := rawSyscall6(uintptr(unsafe.Pointer(&procUname)), 1, uintptr(unsafe.Pointer(&un)), 0, 0, 0, 0, 0)
	if errno != 0 {
		return 0, 0
	}

	// The version string is in the form "<version>.<update>.<sru>.<build>.<reserved>"
	// on Solaris: https://blogs.oracle.com/solaris/post/whats-in-a-uname-
	// Therefore, we use the Version field on Solaris when available.
	ver := un.Version[:]
	if runtime.GOOS == "illumos" {
		// Illumos distributions use different formats without a parsable
		// and unified pattern for the Version field while Release level
		// string is guaranteed to be in x.y or x.y.z format regardless of
		// whether the kernel is Solaris or illumos.
		ver = un.Release[:]
	}

	parseNext := func() (n int) {
		for i, c := range ver {
			if c == '.' {
				ver = ver[i+1:]
				return
			}
			if '0' <= c && c <= '9' {
				n = n*10 + int(c-'0')
			}
		}
		ver = nil
		return
	}

	major = parseNext()
	minor = parseNext()

	return
}

// SupportSockNonblockCloexec tests if SOCK_NONBLOCK and SOCK_CLOEXEC are supported
// for socket() system call, returns true if affirmative.
var SupportSockNonblockCloexec = sync.OnceValue(func() bool {
	// First test if socket() supports SOCK_NONBLOCK and SOCK_CLOEXEC directly.
	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, 0)
	if err == nil {
		syscall.Close(s)
		return true
	}
	if err != syscall.EPROTONOSUPPORT && err != syscall.EINVAL {
		// Something wrong with socket(), fall back to checking the kernel version.
		major, minor := KernelVersion()
		if runtime.GOOS == "illumos" {
			return major > 5 || (major == 5 && minor >= 11) // minimal requirement is SunOS 5.11
		}
		return major > 11 || (major == 11 && minor >= 4)
	}
	return false
})

// SupportAccept4 tests whether accept4 system call is available.
var SupportAccept4 = sync.OnceValue(func() bool {
	for {
		// Test if the accept4() is available.
		_, _, err := syscall.Accept4(0, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC)
		if err == syscall.EINTR {
			continue
		}
		return err != syscall.ENOSYS
	}
})

// SupportTCPKeepAliveIdleIntvlCNT determines whether the TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT
// are available by checking the kernel version for Solaris 11.4.
var SupportTCPKeepAliveIdleIntvlCNT = sync.OnceValue(func() bool {
	major, minor := KernelVersion()
	return major > 11 || (major == 11 && minor >= 4)
})
