github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/crypto/rand/rand_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 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  }