github.com/simpleiot/simpleiot@v0.18.3/test/fifo.go (about) 1 //go:build !windows 2 3 package test 4 5 import ( 6 "fmt" 7 "io" 8 "log" 9 "os" 10 "syscall" 11 ) 12 13 // Fifo uses unix named pipes or fifos to emulate a UART type channel 14 // the A side manages the channel, creates the fifos, cleans up, etc. The 15 // B side only opens the fifos for read/write. Fifo implements the io.ReadWriteCloser interface. 16 // The Close() on the B side does not do anything. 17 type Fifo struct { 18 fread io.ReadCloser 19 fwrite io.WriteCloser 20 a2b string 21 b2a string 22 } 23 24 // NewFifoA creates the A side interface. This must be called first to create the fifo files. 25 func NewFifoA(name string) (*Fifo, error) { 26 ret := &Fifo{} 27 ret.a2b = name + "a2b" 28 ret.b2a = name + "b2a" 29 30 os.Remove(ret.a2b) 31 os.Remove(ret.b2a) 32 33 err := syscall.Mknod(ret.a2b, syscall.S_IFIFO|0666, 0) 34 if err != nil { 35 return nil, fmt.Errorf("Mknod a2b failed: %v", err) 36 } 37 err = syscall.Mknod(ret.b2a, syscall.S_IFIFO|0666, 0) 38 if err != nil { 39 return nil, fmt.Errorf("Mknod b2a failed: %v", err) 40 } 41 42 ret.fread, err = os.OpenFile(ret.b2a, os.O_RDWR, 0600) 43 if err != nil { 44 return nil, fmt.Errorf("Error opening read file: %v", err) 45 } 46 47 ret.fwrite, err = os.OpenFile(ret.a2b, os.O_RDWR, 0600) 48 if err != nil { 49 return nil, fmt.Errorf("Error opening write file: %v", err) 50 } 51 52 return ret, nil 53 } 54 55 // NewFifoB creates the B side interface. This must be called after NewFifoB 56 func NewFifoB(name string) (*Fifo, error) { 57 ret := &Fifo{} 58 59 a2b := name + "a2b" 60 b2a := name + "b2a" 61 62 var err error 63 64 ret.fread, err = os.OpenFile(a2b, os.O_RDWR, 0600) 65 if err != nil { 66 return nil, fmt.Errorf("Error opening read file: %v", err) 67 } 68 69 ret.fwrite, err = os.OpenFile(b2a, os.O_RDWR, 0600) 70 if err != nil { 71 return nil, fmt.Errorf("Error opening write file: %v", err) 72 } 73 74 return ret, nil 75 } 76 77 func (f *Fifo) Read(b []byte) (int, error) { 78 return f.fread.Read(b) 79 } 80 81 func (f *Fifo) Write(b []byte) (int, error) { 82 return f.fwrite.Write(b) 83 } 84 85 // Close and delete fifos 86 func (f *Fifo) Close() error { 87 if err := f.fwrite.Close(); err != nil { 88 log.Println("Error closing write file") 89 } 90 91 if err := f.fread.Close(); err != nil { 92 log.Println("Error closing read file") 93 } 94 95 if f.a2b != "" { 96 os.Remove(f.a2b) 97 } 98 99 if f.b2a != "" { 100 os.Remove(f.b2a) 101 } 102 103 return nil 104 }