Skip to content

Commit a9d7319

Browse files
committed
Add bsd support
1 parent 2cd7184 commit a9d7319

File tree

4 files changed

+134
-22
lines changed

4 files changed

+134
-22
lines changed

serial_bsd.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// +build freebsd openbsd netbsd
2+
3+
package serial
4+
5+
import (
6+
"fmt"
7+
"syscall"
8+
"unsafe"
9+
)
10+
11+
var baudRates = map[int]uint32{
12+
50: syscall.B50,
13+
75: syscall.B75,
14+
110: syscall.B110,
15+
134: syscall.B134,
16+
150: syscall.B150,
17+
200: syscall.B200,
18+
300: syscall.B300,
19+
600: syscall.B600,
20+
1200: syscall.B1200,
21+
1800: syscall.B1800,
22+
2400: syscall.B2400,
23+
4800: syscall.B4800,
24+
9600: syscall.B9600,
25+
19200: syscall.B19200,
26+
38400: syscall.B38400,
27+
57600: syscall.B57600,
28+
115200: syscall.B115200,
29+
230400: syscall.B230400,
30+
460800: syscall.B460800,
31+
}
32+
33+
var charSizes = map[int]uint32{
34+
5: syscall.CS5,
35+
6: syscall.CS6,
36+
7: syscall.CS7,
37+
8: syscall.CS8,
38+
}
39+
40+
// syscallSelect is a wapper for syscall.Select that only returns error.
41+
func syscallSelect(n int, r *syscall.FdSet, w *syscall.FdSet, e *syscall.FdSet, tv *syscall.Timeval) error {
42+
return syscall.Select(n, r, w, e, tv)
43+
}
44+
45+
// tcsetattr sets terminal file descriptor parameters.
46+
// See man tcsetattr(3).
47+
func tcsetattr(fd int, termios *syscall.Termios) (err error) {
48+
r, _, errno := syscall.Syscall(uintptr(syscall.SYS_IOCTL),
49+
uintptr(fd), uintptr(syscall.TIOCSETA), uintptr(unsafe.Pointer(termios)))
50+
if errno != 0 {
51+
err = errno
52+
return
53+
}
54+
if r != 0 {
55+
err = fmt.Errorf("tcsetattr failed %v", r)
56+
}
57+
return
58+
}
59+
60+
// tcgetattr gets terminal file descriptor parameters.
61+
// See man tcgetattr(3).
62+
func tcgetattr(fd int, termios *syscall.Termios) (err error) {
63+
r, _, errno := syscall.Syscall(uintptr(syscall.SYS_IOCTL),
64+
uintptr(fd), uintptr(syscall.TIOCGETA), uintptr(unsafe.Pointer(termios)))
65+
if errno != 0 {
66+
err = errno
67+
return
68+
}
69+
if r != 0 {
70+
err = fmt.Errorf("tcgetattr failed %v", r)
71+
return
72+
}
73+
return
74+
}
75+
76+
// fdget returns index and offset of fd in fds.
77+
func fdget(fd int, fds *syscall.FdSet) (index, offset int) {
78+
index = fd / (syscall.FD_SETSIZE / len(fds.X__fds_bits)) % len(fds.X__fds_bits)
79+
offset = fd % (syscall.FD_SETSIZE / len(fds.X__fds_bits))
80+
return
81+
}
82+
83+
// fdset implements FD_SET macro.
84+
func fdset(fd int, fds *syscall.FdSet) {
85+
idx, pos := fdget(fd, fds)
86+
fds.X__fds_bits[idx] = 1 << uint(pos)
87+
}
88+
89+
// fdisset implements FD_ISSET macro.
90+
func fdisset(fd int, fds *syscall.FdSet) bool {
91+
idx, pos := fdget(fd, fds)
92+
return fds.X__fds_bits[idx]&(1<<uint(pos)) != 0
93+
}

serial_darwin.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,22 @@ func tcgetattr(fd int, termios *syscall.Termios) (err error) {
6969
}
7070
return
7171
}
72+
73+
// fdget returns index and offset of fd in fds.
74+
func fdget(fd int, fds *syscall.FdSet) (index, offset int) {
75+
index = fd / (syscall.FD_SETSIZE / len(fds.Bits)) % len(fds.Bits)
76+
offset = fd % (syscall.FD_SETSIZE / len(fds.Bits))
77+
return
78+
}
79+
80+
// fdset implements FD_SET macro.
81+
func fdset(fd int, fds *syscall.FdSet) {
82+
idx, pos := fdget(fd, fds)
83+
fds.Bits[idx] = 1 << uint(pos)
84+
}
85+
86+
// fdisset implements FD_ISSET macro.
87+
func fdisset(fd int, fds *syscall.FdSet) bool {
88+
idx, pos := fdget(fd, fds)
89+
return fds.Bits[idx]&(1<<uint(pos)) != 0
90+
}

serial_linux.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,22 @@ func tcgetattr(fd int, termios *syscall.Termios) (err error) {
8282
}
8383
return
8484
}
85+
86+
// fdget returns index and offset of fd in fds.
87+
func fdget(fd int, fds *syscall.FdSet) (index, offset int) {
88+
index = fd / (syscall.FD_SETSIZE / len(fds.Bits)) % len(fds.Bits)
89+
offset = fd % (syscall.FD_SETSIZE / len(fds.Bits))
90+
return
91+
}
92+
93+
// fdset implements FD_SET macro.
94+
func fdset(fd int, fds *syscall.FdSet) {
95+
idx, pos := fdget(fd, fds)
96+
fds.Bits[idx] = 1 << uint(pos)
97+
}
98+
99+
// fdisset implements FD_ISSET macro.
100+
func fdisset(fd int, fds *syscall.FdSet) bool {
101+
idx, pos := fdget(fd, fds)
102+
return fds.Bits[idx]&(1<<uint(pos)) != 0
103+
}

serial_posix.go

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// +build darwin linux
1+
// +build darwin linux freebsd openbsd netbsd
22

33
package serial
44

@@ -64,7 +64,7 @@ func (p *port) Read(b []byte) (n int, err error) {
6464
var rfds syscall.FdSet
6565

6666
fd := p.fd
67-
fdSet(fd, &rfds)
67+
fdset(fd, &rfds)
6868

6969
var tv *syscall.Timeval
7070
if p.timeout > 0 {
@@ -81,7 +81,7 @@ func (p *port) Read(b []byte) (n int, err error) {
8181
return
8282
}
8383
}
84-
if !fdIsSet(fd, &rfds) {
84+
if !fdisset(fd, &rfds) {
8585
// Timeout
8686
err = ErrTimeout
8787
return
@@ -203,22 +203,3 @@ func newTermios(c *Config) (termios *syscall.Termios, err error) {
203203
// Both are unused as NDELAY is we utilized when opening device.
204204
return
205205
}
206-
207-
// fdGet returns index and offset of fd in fds.
208-
func fdGet(fd int, fds *syscall.FdSet) (index, offset int) {
209-
index = fd / (syscall.FD_SETSIZE / len(fds.Bits)) % len(fds.Bits)
210-
offset = fd % (syscall.FD_SETSIZE / len(fds.Bits))
211-
return
212-
}
213-
214-
// fdSet implements FD_SET macro.
215-
func fdSet(fd int, fds *syscall.FdSet) {
216-
idx, pos := fdGet(fd, fds)
217-
fds.Bits[idx] = 1 << uint(pos)
218-
}
219-
220-
// fdIsSet implements FD_ISSET macro.
221-
func fdIsSet(fd int, fds *syscall.FdSet) bool {
222-
idx, pos := fdGet(fd, fds)
223-
return fds.Bits[idx]&(1<<uint(pos)) != 0
224-
}

0 commit comments

Comments
 (0)