...

Source file src/pkg/internal/syscall/unix/getrandom_linux.go

     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	}
    47	

View as plain text