github.com/insolar/x-crypto@v0.0.0-20191031140942-75fab8a325f6/rand/internal/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 randomTrap == 0 { 30 return 0, syscall.ENOSYS 31 } 32 if len(p) == 0 { 33 return 0, nil 34 } 35 if atomic.LoadInt32(&randomUnsupported) != 0 { 36 return 0, syscall.ENOSYS 37 } 38 r1, _, errno := syscall.Syscall(randomTrap, 39 uintptr(unsafe.Pointer(&p[0])), 40 uintptr(len(p)), 41 uintptr(flags)) 42 if errno != 0 { 43 if errno == syscall.ENOSYS { 44 atomic.StoreInt32(&randomUnsupported, 1) 45 } 46 return 0, errno 47 } 48 return int(r1), nil 49 }