// Copyright 2018 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 ( "sync/atomic" "syscall" "unsafe" ) var randomUnsupported int32 // atomic // FreeBSD getrandom system call number. const randomTrap uintptr = 563 // GetRandomFlag is a flag supported by the getrandom system call. type GetRandomFlag uintptr const ( // GRND_NONBLOCK means return EAGAIN rather than blocking. GRND_NONBLOCK GetRandomFlag = 0x0001 // GRND_RANDOM is only set for portability purpose, no-op on FreeBSD. GRND_RANDOM GetRandomFlag = 0x0002 ) // GetRandom calls the FreeBSD getrandom system call. func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { if len(p) == 0 { return 0, nil } if atomic.LoadInt32(&randomUnsupported) != 0 { return 0, syscall.ENOSYS } r1, _, errno := syscall.Syscall(randomTrap, uintptr(unsafe.Pointer(&p[0])), uintptr(len(p)), uintptr(flags)) if errno != 0 { if errno == syscall.ENOSYS { atomic.StoreInt32(&randomUnsupported, 1) } return 0, errno } return int(r1), nil }