github.com/shijuvar/go@v0.0.0-20141209052335-e8f13700b70c/src/internal/syscall/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 syscall 6 7 import ( 8 "runtime" 9 "sync/atomic" 10 stdsyscall "syscall" 11 "unsafe" 12 ) 13 14 var randomTrap = map[string]uintptr{ 15 "386": 355, 16 "amd64": 318, 17 "arm": 384, 18 }[runtime.GOARCH] 19 20 var randomUnsupported int32 // atomic 21 22 // GetRandomFlag is a flag supported by the getrandom system call. 23 type GetRandomFlag uintptr 24 25 const ( 26 // GRND_NONBLOCK means return EAGAIN rather than blocking. 27 GRND_NONBLOCK GetRandomFlag = 0x0001 28 29 // GRND_RANDOM means use the /dev/random pool instead of /dev/urandom. 30 GRND_RANDOM GetRandomFlag = 0x0002 31 ) 32 33 // GetRandom calls the Linux getrandom system call. 34 // See https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c6e9d6f38894798696f23c8084ca7edbf16ee895 35 func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { 36 if randomTrap == 0 { 37 return 0, stdsyscall.ENOSYS 38 } 39 if len(p) == 0 { 40 return 0, nil 41 } 42 if atomic.LoadInt32(&randomUnsupported) != 0 { 43 return 0, stdsyscall.ENOSYS 44 } 45 r1, _, errno := stdsyscall.Syscall(randomTrap, 46 uintptr(unsafe.Pointer(&p[0])), 47 uintptr(len(p)), 48 uintptr(flags)) 49 if errno != 0 { 50 if errno == stdsyscall.ENOSYS { 51 atomic.StoreInt32(&randomUnsupported, 1) 52 } 53 return 0, errno 54 } 55 return int(r1), nil 56 }