Skip to content

Commit 6a673bf

Browse files
committed
Transparently handle EINTR during Read
This has been observed in particular on MacOS, in this case just retry the call without throwing the error back to the user. Related to: arduino/arduino-cli#504 arduino/arduino-pro-ide#157
1 parent d1a463e commit 6a673bf

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

Diff for: serial_unix.go

+18-9
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import (
1515
"sync"
1616
"unsafe"
1717

18-
"golang.org/x/sys/unix"
1918
"go.bug.st/serial/unixutils"
19+
"golang.org/x/sys/unix"
2020
)
2121

2222
type unixPort struct {
@@ -51,22 +51,31 @@ func (port *unixPort) Close() error {
5151
return nil
5252
}
5353

54-
func (port *unixPort) Read(p []byte) (n int, err error) {
54+
func (port *unixPort) Read(p []byte) (int, error) {
5555
port.closeLock.RLock()
5656
defer port.closeLock.RUnlock()
5757
if !port.opened {
5858
return 0, &PortError{code: PortClosed}
5959
}
6060

6161
fds := unixutils.NewFDSet(port.handle, port.closeSignal.ReadFD())
62-
res, err := unixutils.Select(fds, nil, fds, -1)
63-
if err != nil {
64-
return 0, err
65-
}
66-
if res.IsReadable(port.closeSignal.ReadFD()) {
67-
return 0, &PortError{code: PortClosed}
62+
for {
63+
res, err := unixutils.Select(fds, nil, fds, -1)
64+
if err == unix.EINTR {
65+
continue
66+
}
67+
if err != nil {
68+
return 0, err
69+
}
70+
if res.IsReadable(port.closeSignal.ReadFD()) {
71+
return 0, &PortError{code: PortClosed}
72+
}
73+
n, err := unix.Read(port.handle, p)
74+
if err == unix.EINTR {
75+
continue
76+
}
77+
return n, err
6878
}
69-
return unix.Read(port.handle, p)
7079
}
7180

7281
func (port *unixPort) Write(p []byte) (n int, err error) {

0 commit comments

Comments
 (0)