Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions serial_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,33 +85,33 @@ func (p *port) Close() (err error) {
// Read reads from serial port. Port must be opened before calling this method.
// It is blocked until all data received or timeout after p.timeout.
func (p *port) Read(b []byte) (n int, err error) {
var rfds syscall.FdSet
fds := []unix.PollFd{{Fd: int32(p.fd), Events: unix.POLLIN}}
deadline := time.Now().Add(p.timeout)

fd := p.fd
fdset(fd, &rfds)

var tv *syscall.Timeval
if p.timeout > 0 {
timeout := syscall.NsecToTimeval(p.timeout.Nanoseconds())
tv = &timeout
}
for {
// If syscall.Select() returns EINTR (Interrupted system call), retry it
if err = syscallSelect(fd+1, &rfds, nil, nil, tv); err == nil {
break
timeout := -1
if p.timeout > 0 {
timeout = int(deadline.Sub(time.Now()).Milliseconds())
}
if err != syscall.EINTR {
err = fmt.Errorf("serial: could not select: %v", err)
return

n, err := unix.Poll(fds, timeout)
if err != nil {
if errors.Is(err, syscall.EINTR) {
continue
}
return 0, fmt.Errorf("serial: could not poll: %v", err)
}

if n == 0 {
return 0, ErrTimeout
}

if fds[0].Revents&unix.POLLIN == unix.POLLIN {
break
}
}
if !fdisset(fd, &rfds) {
// Timeout
err = ErrTimeout
return
}
n, err = syscall.Read(fd, b)
return

return syscall.Read(p.fd, b)
}

// Write writes data to the serial port.
Expand Down