diff options
Diffstat (limited to 'software/vendor/go.bug.st/serial/unixutils')
-rw-r--r-- | software/vendor/go.bug.st/serial/unixutils/pipe.go | 82 | ||||
-rw-r--r-- | software/vendor/go.bug.st/serial/unixutils/select.go | 101 |
2 files changed, 183 insertions, 0 deletions
diff --git a/software/vendor/go.bug.st/serial/unixutils/pipe.go b/software/vendor/go.bug.st/serial/unixutils/pipe.go new file mode 100644 index 0000000..748de34 --- /dev/null +++ b/software/vendor/go.bug.st/serial/unixutils/pipe.go @@ -0,0 +1,82 @@ +// +// Copyright 2014-2023 Cristian Maglie. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// + +//go:build linux || darwin || freebsd || openbsd + +package unixutils + +import ( + "fmt" + "syscall" +) + +// Pipe represents a unix-pipe +type Pipe struct { + opened bool + rd int + wr int +} + +// Open creates a new pipe +func (p *Pipe) Open() error { + fds := []int{0, 0} + if err := syscall.Pipe(fds); err != nil { + return err + } + p.rd = fds[0] + p.wr = fds[1] + p.opened = true + return nil +} + +// ReadFD returns the file handle for the read side of the pipe. +func (p *Pipe) ReadFD() int { + if !p.opened { + return -1 + } + return p.rd +} + +// WriteFD returns the flie handle for the write side of the pipe. +func (p *Pipe) WriteFD() int { + if !p.opened { + return -1 + } + return p.wr +} + +// Write to the pipe the content of data. Returns the numbre of bytes written. +func (p *Pipe) Write(data []byte) (int, error) { + if !p.opened { + return 0, fmt.Errorf("Pipe not opened") + } + return syscall.Write(p.wr, data) +} + +// Read from the pipe into the data array. Returns the number of bytes read. +func (p *Pipe) Read(data []byte) (int, error) { + if !p.opened { + return 0, fmt.Errorf("Pipe not opened") + } + return syscall.Read(p.rd, data) +} + +// Close the pipe +func (p *Pipe) Close() error { + if !p.opened { + return fmt.Errorf("Pipe not opened") + } + err1 := syscall.Close(p.rd) + err2 := syscall.Close(p.wr) + p.opened = false + if err1 != nil { + return err1 + } + if err2 != nil { + return err2 + } + return nil +} diff --git a/software/vendor/go.bug.st/serial/unixutils/select.go b/software/vendor/go.bug.st/serial/unixutils/select.go new file mode 100644 index 0000000..9f0e214 --- /dev/null +++ b/software/vendor/go.bug.st/serial/unixutils/select.go @@ -0,0 +1,101 @@ +// +// Copyright 2014-2023 Cristian Maglie. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// + +//go:build linux || darwin || freebsd || openbsd + +package unixutils + +import ( + "time" + + "github.com/creack/goselect" +) + +// FDSet is a set of file descriptors suitable for a select call +type FDSet struct { + set goselect.FDSet + max uintptr +} + +// NewFDSet creates a set of file descriptors suitable for a Select call. +func NewFDSet(fds ...int) *FDSet { + s := &FDSet{} + s.Add(fds...) + return s +} + +// Add adds the file descriptors passed as parameter to the FDSet. +func (s *FDSet) Add(fds ...int) { + for _, fd := range fds { + f := uintptr(fd) + s.set.Set(f) + if f > s.max { + s.max = f + } + } +} + +// FDResultSets contains the result of a Select operation. +type FDResultSets struct { + readable *goselect.FDSet + writeable *goselect.FDSet + errors *goselect.FDSet +} + +// IsReadable test if a file descriptor is ready to be read. +func (r *FDResultSets) IsReadable(fd int) bool { + return r.readable.IsSet(uintptr(fd)) +} + +// IsWritable test if a file descriptor is ready to be written. +func (r *FDResultSets) IsWritable(fd int) bool { + return r.writeable.IsSet(uintptr(fd)) +} + +// IsError test if a file descriptor is in error state. +func (r *FDResultSets) IsError(fd int) bool { + return r.errors.IsSet(uintptr(fd)) +} + +// Select performs a select system call, +// file descriptors in the rd set are tested for read-events, +// file descriptors in the wd set are tested for write-events and +// file descriptors in the er set are tested for error-events. +// The function will block until an event happens or the timeout expires. +// The function return an FDResultSets that contains all the file descriptor +// that have a pending read/write/error event. +func Select(rd, wr, er *FDSet, timeout time.Duration) (*FDResultSets, error) { + max := uintptr(0) + res := &FDResultSets{} + if rd != nil { + // fdsets are copied so the parameters are left untouched + copyOfRd := rd.set + res.readable = ©OfRd + // Determine max fd. + max = rd.max + } + if wr != nil { + // fdsets are copied so the parameters are left untouched + copyOfWr := wr.set + res.writeable = ©OfWr + // Determine max fd. + if wr.max > max { + max = wr.max + } + } + if er != nil { + // fdsets are copied so the parameters are left untouched + copyOfEr := er.set + res.errors = ©OfEr + // Determine max fd. + if er.max > max { + max = er.max + } + } + + err := goselect.Select(int(max+1), res.readable, res.writeable, res.errors, timeout) + return res, err +} |