github.com/fisco-bcos/crypto@v0.0.0-20200202032121-bd8ab0b5d4f1/internal/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(randomTrap, 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 }