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