tinybox

Owner: IIIlllIIIllI URL: git@github.com:nyangkosense/tinybox.git

testing posix compliant

Commit 138cea346f3e238ce43c41add3ce104a7c735d65 by SM <seb.michalk@gmail.com> on 2025-09-24 10:29:33 +0200
diff --git a/tinybox/fdset_posix.go b/tinybox/fdset_posix.go
new file mode 100644
index 0000000..b9e50e0
--- /dev/null
+++ b/tinybox/fdset_posix.go
@@ -0,0 +1,32 @@
+//go:build linux || darwin || freebsd || netbsd || openbsd || dragonfly
+
+package tb
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+func setFd(set *syscall.FdSet, fd int) {
+	if fd < 0 {
+		return
+	}
+	bytes := unsafe.Slice((*byte)(unsafe.Pointer(set)), int(unsafe.Sizeof(*set)))
+	idx := fd / 8
+	if idx >= len(bytes) {
+		return
+	}
+	bytes[idx] |= 1 << (uint(fd) % 8)
+}
+
+func fdIsSet(set *syscall.FdSet, fd int) bool {
+	if fd < 0 {
+		return false
+	}
+	bytes := unsafe.Slice((*byte)(unsafe.Pointer(set)), int(unsafe.Sizeof(*set)))
+	idx := fd / 8
+	if idx >= len(bytes) {
+		return false
+	}
+	return bytes[idx]&(1<<(uint(fd)%8)) != 0
+}
diff --git a/tinybox/select_bsd.go b/tinybox/select_bsd.go
new file mode 100644
index 0000000..f8decbc
--- /dev/null
+++ b/tinybox/select_bsd.go
@@ -0,0 +1,16 @@
+//go:build darwin || freebsd || netbsd || openbsd || dragonfly
+
+package tb
+
+import "syscall"
+
+func selectRead(fd int, set *syscall.FdSet, tv *syscall.Timeval) (int, error) {
+	err := syscall.Select(fd+1, set, nil, nil, tv)
+	if err != nil {
+		return 0, err
+	}
+	if fdIsSet(set, fd) {
+		return 1, nil
+	}
+	return 0, nil
+}
diff --git a/tinybox/select_linux.go b/tinybox/select_linux.go
new file mode 100644
index 0000000..37f92d9
--- /dev/null
+++ b/tinybox/select_linux.go
@@ -0,0 +1,9 @@
+//go:build linux
+
+package tb
+
+import "syscall"
+
+func selectRead(fd int, set *syscall.FdSet, tv *syscall.Timeval) (int, error) {
+	return syscall.Select(fd+1, set, nil, nil, tv)
+}
diff --git a/tinybox/tb.go b/tinybox/tb.go
index 22535c2..70f9a39 100644
--- a/tinybox/tb.go
+++ b/tinybox/tb.go
@@ -36,26 +36,6 @@ import (
 )
 
 const (
-	TCGETS     = 0x5401
-	TCSETS     = 0x5402
-	TIOCGWINSZ = 0x5413
-	ICANON     = 0x2
-	ECHO       = 0x8
-	ISIG       = 0x1
-	IEXTEN     = 0x8000
-	BRKINT     = 0x2
-	ICRNL      = 0x100
-	INPCK      = 0x10
-	ISTRIP     = 0x20
-	IXON       = 0x400
-	OPOST      = 0x1
-	CS8        = 0x30
-	VMIN       = 6
-	VTIME      = 5
-	F_GETFL    = 3
-	F_SETFL    = 4
-	O_NONBLOCK = 0x800
-
 	ESC = "\033"
 	BEL = "\x07"
 
@@ -112,12 +92,7 @@ var (
 	resetColorSeq     = []byte(ResetColor)
 )
 
-type termios struct {
-	Iflag, Oflag, Cflag, Lflag uint32
-	Line                       uint8
-	Cc                         [32]uint8
-	Ispeed, Ospeed             uint32
-}
+type termios = syscall.Termios
 
 type winsize struct {
 	Row, Col, Xpixel, Ypixel uint16
@@ -288,10 +263,13 @@ func queryTermSize() (int, int, error) {
 	fd := int(syscall.Stdin)
 
 	fdSet := &syscall.FdSet{}
-	fdSet.Bits[fd/64] |= 1 << (uint(fd) % 64)
+	setFd(fdSet, fd)
 	tv := syscall.Timeval{Sec: 1, Usec: 0}
 
-	n := syscall.Select(fd+1, fdSet, nil, nil, &tv)
+	n, err := selectRead(fd, fdSet, &tv)
+	if err != nil {
+		return 80, 24, err
+	}
 	if n <= 0 {
 		return 80, 24, fmt.Errorf("timeout")
 	}
@@ -672,14 +650,17 @@ func PollEventTimeout(timeout time.Duration) (Event, error) {
 
 	fd := int(syscall.Stdin)
 	fdSet := &syscall.FdSet{}
-	fdSet.Bits[fd/64] |= 1 << (uint(fd) % 64)
+	setFd(fdSet, fd)
 
 	tv := syscall.Timeval{
 		Sec:  int64(timeout / time.Second),
 		Usec: int64((timeout % time.Second) / time.Microsecond),
 	}
 
-	n := syscall.Select(fd+1, fdSet, nil, nil, &tv)
+	n, err := selectRead(fd, fdSet, &tv)
+	if err != nil {
+		return Event{}, err
+	}
 	if n <= 0 {
 		return Event{}, fmt.Errorf("timeout")
 	}
@@ -1071,10 +1052,13 @@ func GetCursorPos() (x, y int) {
 	fd := int(syscall.Stdin)
 
 	fdSet := &syscall.FdSet{}
-	fdSet.Bits[fd/64] |= 1 << (uint(fd) % 64)
+	setFd(fdSet, fd)
 	tv := syscall.Timeval{Sec: 1, Usec: 0} // 1 second timeout
 
-	n := syscall.Select(fd+1, fdSet, nil, nil, &tv)
+	n, err := selectRead(fd, fdSet, &tv)
+	if err != nil {
+		return 0, 0
+	}
 	if n <= 0 {
 		return 0, 0
 	}
diff --git a/tinybox/termios_bsd.go b/tinybox/termios_bsd.go
new file mode 100644
index 0000000..59ccf0d
--- /dev/null
+++ b/tinybox/termios_bsd.go
@@ -0,0 +1,27 @@
+//go:build darwin || freebsd || netbsd || openbsd || dragonfly
+
+package tb
+
+import "syscall"
+
+const (
+	TCGETS     = syscall.TIOCGETA
+	TCSETS     = syscall.TIOCSETA
+	TIOCGWINSZ = syscall.TIOCGWINSZ
+	ICANON     = syscall.ICANON
+	ECHO       = syscall.ECHO
+	ISIG       = syscall.ISIG
+	IEXTEN     = syscall.IEXTEN
+	BRKINT     = syscall.BRKINT
+	ICRNL      = syscall.ICRNL
+	INPCK      = syscall.INPCK
+	ISTRIP     = syscall.ISTRIP
+	IXON       = syscall.IXON
+	OPOST      = syscall.OPOST
+	CS8        = syscall.CS8
+	VMIN       = syscall.VMIN
+	VTIME      = syscall.VTIME
+	F_GETFL    = syscall.F_GETFL
+	F_SETFL    = syscall.F_SETFL
+	O_NONBLOCK = syscall.O_NONBLOCK
+)
diff --git a/tinybox/termios_linux.go b/tinybox/termios_linux.go
new file mode 100644
index 0000000..3b56cb3
--- /dev/null
+++ b/tinybox/termios_linux.go
@@ -0,0 +1,27 @@
+//go:build linux
+
+package tb
+
+import "syscall"
+
+const (
+	TCGETS     = syscall.TCGETS
+	TCSETS     = syscall.TCSETS
+	TIOCGWINSZ = syscall.TIOCGWINSZ
+	ICANON     = syscall.ICANON
+	ECHO       = syscall.ECHO
+	ISIG       = syscall.ISIG
+	IEXTEN     = syscall.IEXTEN
+	BRKINT     = syscall.BRKINT
+	ICRNL      = syscall.ICRNL
+	INPCK      = syscall.INPCK
+	ISTRIP     = syscall.ISTRIP
+	IXON       = syscall.IXON
+	OPOST      = syscall.OPOST
+	CS8        = syscall.CS8
+	VMIN       = syscall.VMIN
+	VTIME      = syscall.VTIME
+	F_GETFL    = syscall.F_GETFL
+	F_SETFL    = syscall.F_SETFL
+	O_NONBLOCK = syscall.O_NONBLOCK
+)