summaryrefslogtreecommitdiff
path: root/software/vendor/go.bug.st/serial/unixutils/select.go
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2024-05-30 16:00:32 +0200
committerxengineering <me@xengineering.eu>2024-05-30 16:00:32 +0200
commitb8ef4d11fe0d00ce0884ccf982675845b20c3ce9 (patch)
tree3beb57ff849ed74569ce325225bc819791c25a6a /software/vendor/go.bug.st/serial/unixutils/select.go
parenteab833271eeaa8d54991c11eccec9445f662a191 (diff)
downloadiot-core-b8ef4d11fe0d00ce0884ccf982675845b20c3ce9.tar
iot-core-b8ef4d11fe0d00ce0884ccf982675845b20c3ce9.tar.zst
iot-core-b8ef4d11fe0d00ce0884ccf982675845b20c3ce9.zip
software: Implement serial port detection
Diffstat (limited to 'software/vendor/go.bug.st/serial/unixutils/select.go')
-rw-r--r--software/vendor/go.bug.st/serial/unixutils/select.go101
1 files changed, 101 insertions, 0 deletions
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 = &copyOfRd
+ // Determine max fd.
+ max = rd.max
+ }
+ if wr != nil {
+ // fdsets are copied so the parameters are left untouched
+ copyOfWr := wr.set
+ res.writeable = &copyOfWr
+ // 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 = &copyOfEr
+ // 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
+}