github.com/sandwichdev/go-internals@v0.0.0-20210605002614-12311ac6b2c5/syscall/unix/getrandom_linux.go (about) 1 // Copyright 2014 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 // GetRandomFlag is a flag supported by the getrandom system call. 16 type GetRandomFlag uintptr 17 18 const ( 19 // GRND_NONBLOCK means return EAGAIN rather than blocking. 20 GRND_NONBLOCK GetRandomFlag = 0x0001 21 22 // GRND_RANDOM means use the /dev/random pool instead of /dev/urandom. 23 GRND_RANDOM GetRandomFlag = 0x0002 24 ) 25 26 // GetRandom calls the Linux getrandom system call. 27 // See https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c6e9d6f38894798696f23c8084ca7edbf16ee895 28 func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { 29 if len(p) == 0 { 30 return 0, nil 31 } 32 if atomic.LoadInt32(&randomUnsupported) != 0 { 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 atomic.StoreInt32(&randomUnsupported, 1) 42 } 43 return 0, errno 44 } 45 return int(r1), nil 46 }