github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+incompatible/cmds/core/elvish/eval/port.go (about)

     1  package eval
     2  
     3  import (
     4  	"os"
     5  )
     6  
     7  // Port conveys data stream. It always consists of a byte band and a channel band.
     8  type Port struct {
     9  	File      *os.File
    10  	Chan      chan interface{}
    11  	CloseFile bool
    12  	CloseChan bool
    13  }
    14  
    15  // Fork returns a copy of a Port with the Close* flags unset.
    16  func (p *Port) Fork() *Port {
    17  	return &Port{p.File, p.Chan, false, false}
    18  }
    19  
    20  // Close closes a Port.
    21  func (p *Port) Close() {
    22  	if p == nil {
    23  		return
    24  	}
    25  	if p.CloseFile {
    26  		p.File.Close()
    27  	}
    28  	if p.CloseChan {
    29  		close(p.Chan)
    30  	}
    31  }
    32  
    33  var (
    34  	// ClosedChan is a closed channel, suitable for use as placeholder channel input.
    35  	ClosedChan = make(chan interface{})
    36  	// BlackholeChan is channel writes onto which disappear, suitable for use as
    37  	// placeholder channel output.
    38  	BlackholeChan = make(chan interface{})
    39  	// DevNull is /dev/null.
    40  	DevNull *os.File
    41  	// DevNullClosedInput is a port made up from DevNull and ClosedChan,
    42  	// suitable as placeholder input port.
    43  	DevNullClosedChan *Port
    44  )
    45  
    46  func init() {
    47  	close(ClosedChan)
    48  	go func() {
    49  		for range BlackholeChan {
    50  		}
    51  	}()
    52  
    53  	var err error
    54  	DevNull, err = os.Open(os.DevNull)
    55  	if err != nil {
    56  		os.Stderr.WriteString("cannot open " + os.DevNull + ", shell might not function normally\n")
    57  	}
    58  	DevNullClosedChan = &Port{File: DevNull, Chan: ClosedChan}
    59  }