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 }