diff --git a/go.mod b/go.mod index 61d0d6d..c390509 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module go.bug.st/serial go 1.17 require ( - github.com/creack/goselect v0.1.2 github.com/stretchr/testify v1.8.4 golang.org/x/sys v0.17.0 ) diff --git a/go.sum b/go.sum index 43d4dac..0edbc1d 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0= -github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/serial_unix.go b/serial_unix.go index 54e55a8..fb100cd 100644 --- a/serial_unix.go +++ b/serial_unix.go @@ -280,12 +280,12 @@ func nativeOpen(portName string, mode *Mode) (*unixPort, error) { port.acquireExclusiveAccess() // This pipe is used as a signal to cancel blocking Read - pipe := &unixutils.Pipe{} - if err := pipe.Open(); err != nil { + if pipe, err := unixutils.NewPipe(); err != nil { port.Close() return nil, &PortError{code: InvalidSerialPort, causedBy: fmt.Errorf("error opening signaling pipe: %w", err)} + } else { + port.closeSignal = pipe } - port.closeSignal = pipe return port, nil } diff --git a/unixutils/pipe.go b/unixutils/pipe.go index f54c916..96023d0 100644 --- a/unixutils/pipe.go +++ b/unixutils/pipe.go @@ -10,7 +10,8 @@ package unixutils import ( "fmt" - "syscall" + + "golang.org/x/sys/unix" ) // Pipe represents a unix-pipe @@ -20,16 +21,17 @@ type Pipe struct { wr int } -// Open creates a new pipe -func (p *Pipe) Open() error { +// NewPipe creates a new pipe +func NewPipe() (*Pipe, error) { fds := []int{0, 0} - if err := syscall.Pipe(fds); err != nil { - return err + if err := unix.Pipe(fds); err != nil { + return nil, err } - p.rd = fds[0] - p.wr = fds[1] - p.opened = true - return nil + return &Pipe{ + rd: fds[0], + wr: fds[1], + opened: true, + }, nil } // ReadFD returns the file handle for the read side of the pipe. @@ -53,7 +55,7 @@ func (p *Pipe) Write(data []byte) (int, error) { if !p.opened { return 0, fmt.Errorf("Pipe not opened") } - return syscall.Write(p.wr, data) + return unix.Write(p.wr, data) } // Read from the pipe into the data array. Returns the number of bytes read. @@ -61,7 +63,7 @@ func (p *Pipe) Read(data []byte) (int, error) { if !p.opened { return 0, fmt.Errorf("Pipe not opened") } - return syscall.Read(p.rd, data) + return unix.Read(p.rd, data) } // Close the pipe @@ -69,8 +71,8 @@ func (p *Pipe) Close() error { if !p.opened { return fmt.Errorf("Pipe not opened") } - err1 := syscall.Close(p.rd) - err2 := syscall.Close(p.wr) + err1 := unix.Close(p.rd) + err2 := unix.Close(p.wr) p.opened = false if err1 != nil { return err1 diff --git a/unixutils/select.go b/unixutils/select.go index 42cacc3..46b2b83 100644 --- a/unixutils/select.go +++ b/unixutils/select.go @@ -11,13 +11,13 @@ package unixutils import ( "time" - "github.com/creack/goselect" + "golang.org/x/sys/unix" ) // FDSet is a set of file descriptors suitable for a select call type FDSet struct { - set goselect.FDSet - max uintptr + set unix.FdSet + max int } // NewFDSet creates a set of file descriptors suitable for a Select call. @@ -30,34 +30,33 @@ func NewFDSet(fds ...int) *FDSet { // 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 + s.set.Set(fd) + if fd > s.max { + s.max = fd } } } // FDResultSets contains the result of a Select operation. type FDResultSets struct { - readable *goselect.FDSet - writeable *goselect.FDSet - errors *goselect.FDSet + readable *unix.FdSet + writeable *unix.FdSet + errors *unix.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)) + return r.readable.IsSet(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)) + return r.writeable.IsSet(fd) } // IsError test if a file descriptor is in error state. func (r *FDResultSets) IsError(fd int) bool { - return r.errors.IsSet(uintptr(fd)) + return r.errors.IsSet(fd) } // Select performs a select system call, @@ -68,7 +67,7 @@ func (r *FDResultSets) IsError(fd int) bool { // 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) + max := 0 res := &FDResultSets{} if rd != nil { // fdsets are copied so the parameters are left untouched @@ -96,6 +95,12 @@ func Select(rd, wr, er *FDSet, timeout time.Duration) (*FDResultSets, error) { } } - err := goselect.Select(int(max+1), res.readable, res.writeable, res.errors, timeout) + var err error + if timeout != -1 { + t := unix.NsecToTimeval(timeout.Nanoseconds()) + _, err = unix.Select(max+1, res.readable, res.writeable, res.errors, &t) + } else { + _, err = unix.Select(max+1, res.readable, res.writeable, res.errors, nil) + } return res, err }