github.com/icodeface/tls@v0.0.0-20230910023335-34df9250cd12/internal/syscall/unix/getrandom_freebsd.go (about) 1 // Copyright 2018 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/atomic" 9 "syscall" 10 "unsafe" 11 ) 12 13 var randomUnsupported int32 // atomic 14 15 // FreeBSD getrandom system call number. 16 const randomTrap uintptr = 563 17 18 // GetRandomFlag is a flag supported by the getrandom system call. 19 type GetRandomFlag uintptr 20 21 const ( 22 // GRND_NONBLOCK means return EAGAIN rather than blocking. 23 GRND_NONBLOCK GetRandomFlag = 0x0001 24 25 // GRND_RANDOM is only set for portability purpose, no-op on FreeBSD. 26 GRND_RANDOM GetRandomFlag = 0x0002 27 ) 28 29 // GetRandom calls the FreeBSD getrandom system call. 30 func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { 31 if len(p) == 0 { 32 return 0, nil 33 } 34 if atomic.LoadInt32(&randomUnsupported) != 0 { 35 return 0, syscall.ENOSYS 36 } 37 r1, _, errno := syscall.Syscall(randomTrap, 38 uintptr(unsafe.Pointer(&p[0])), 39 uintptr(len(p)), 40 uintptr(flags)) 41 if errno != 0 { 42 if errno == syscall.ENOSYS { 43 atomic.StoreInt32(&randomUnsupported, 1) 44 } 45 return 0, errno 46 } 47 return int(r1), nil 48 }