github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/rand/random.go (about)

     1  // Copyright 2019 the u-root 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 implements cancelable reads from a cryptographically safe
     6  // random number source.
     7  package rand
     8  
     9  import (
    10  	"context"
    11  )
    12  
    13  // Reader is a cryptographically safe random number source.
    14  var Reader = DefaultReaderWithContext(context.Background())
    15  
    16  // Read blockingly reads from a random number source.
    17  func Read(b []byte) (int, error) {
    18  	return Reader.Read(b)
    19  }
    20  
    21  // ReadContext is a context-aware reader for random numbers.
    22  func ReadContext(ctx context.Context, b []byte) (int, error) {
    23  	return Reader.ReadContext(ctx, b)
    24  }
    25  
    26  // ContextReader is a cancelable io.Reader.
    27  type ContextReader interface {
    28  	// Read behaves like a blocking io.Reader.Read.
    29  	//
    30  	// Read wraps ReadContext with a background context.
    31  	Read(b []byte) (n int, err error)
    32  
    33  	// ReadContext is an io.Reader that blocks until data is available or
    34  	// until ctx is done.
    35  	ReadContext(ctx context.Context, b []byte) (n int, err error)
    36  }
    37  
    38  // contextReader is a cancelable io.Reader.
    39  type contextReader interface {
    40  	ReadContext(context.Context, []byte) (int, error)
    41  }
    42  
    43  // ctxReader takes a contextReader and turns it into a ContextReader.
    44  type ctxReader struct {
    45  	contextReader
    46  	ctx context.Context
    47  }
    48  
    49  func (cr ctxReader) Read(b []byte) (int, error) {
    50  	return cr.contextReader.ReadContext(cr.ctx, b)
    51  }
    52  
    53  // DefaultReaderWithContext returns a context-aware io.Reader.
    54  //
    55  // Because this stores the context, only use this in situations where an
    56  // io.Reader is unavoidable.
    57  func DefaultReaderWithContext(ctx context.Context) ContextReader {
    58  	return ctxReader{
    59  		ctx:           ctx,
    60  		contextReader: defaultContextReader,
    61  	}
    62  }