Home | History | Annotate | Download | only in rand
      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 rand
      6 
      7 import (
      8 	"internal/syscall/unix"
      9 	"sync"
     10 )
     11 
     12 func init() {
     13 	altGetRandom = getRandomLinux
     14 }
     15 
     16 var (
     17 	once       sync.Once
     18 	useSyscall bool
     19 )
     20 
     21 func pickStrategy() {
     22 	// Test whether we should use the system call or /dev/urandom.
     23 	// We'll fall back to urandom if:
     24 	// - the kernel is too old (before 3.17)
     25 	// - the machine has no entropy available (early boot + no hardware
     26 	//   entropy source?) and we want to avoid blocking later.
     27 	var buf [1]byte
     28 	n, err := unix.GetRandom(buf[:], unix.GRND_NONBLOCK)
     29 	useSyscall = n == 1 && err == nil
     30 }
     31 
     32 func getRandomLinux(p []byte) (ok bool) {
     33 	once.Do(pickStrategy)
     34 	if !useSyscall {
     35 		return false
     36 	}
     37 	n, err := unix.GetRandom(p, 0)
     38 	return n == len(p) && err == nil
     39 }
     40