github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/internal/syscall/unix/getrandom_netbsd.go (about) 1 // Copyright 2023 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 "sync/atomic" 10 "syscall" 11 "unsafe" 12 ) 13 14 // NetBSD getrandom system call number. 15 const getrandomTrap uintptr = 91 16 17 var getrandomUnsupported atomic.Bool 18 19 // GetRandomFlag is a flag supported by the getrandom system call. 20 type GetRandomFlag uintptr 21 22 // GetRandom calls the getrandom system call. 23 func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { 24 if len(p) == 0 { 25 return 0, nil 26 } 27 if getrandomUnsupported.Load() { 28 return 0, syscall.ENOSYS 29 } 30 // getrandom(2) was added in NetBSD 10.0 31 if getOSRevision() < 1000000000 { 32 getrandomUnsupported.Store(true) 33 return 0, syscall.ENOSYS 34 } 35 r1, _, errno := syscall.Syscall(getrandomTrap, 36 uintptr(unsafe.Pointer(&p[0])), 37 uintptr(len(p)), 38 uintptr(flags)) 39 if errno != 0 { 40 if errno == syscall.ENOSYS { 41 getrandomUnsupported.Store(true) 42 } 43 return 0, errno 44 } 45 return int(r1), nil 46 } 47 48 var ( 49 osrevisionOnce sync.Once 50 osrevision uint32 51 ) 52 53 func getOSRevision() uint32 { 54 osrevisionOnce.Do(func() { osrevision, _ = syscall.SysctlUint32("kern.osrevision") }) 55 return osrevision 56 }