summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/link/rawfile/rawfile_unsafe.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/tcpip/link/rawfile/rawfile_unsafe.go')
-rw-r--r--pkg/tcpip/link/rawfile/rawfile_unsafe.go31
1 files changed, 25 insertions, 6 deletions
diff --git a/pkg/tcpip/link/rawfile/rawfile_unsafe.go b/pkg/tcpip/link/rawfile/rawfile_unsafe.go
index ba92aedbc..591cb4279 100644
--- a/pkg/tcpip/link/rawfile/rawfile_unsafe.go
+++ b/pkg/tcpip/link/rawfile/rawfile_unsafe.go
@@ -19,6 +19,7 @@
package rawfile
import (
+ "os"
"unsafe"
"golang.org/x/sys/unix"
@@ -105,7 +106,7 @@ func BlockingRead(fd int, b []byte) (int, tcpip.Error) {
event := PollEvent{
FD: int32(fd),
- Events: 1, // POLLIN
+ Events: unix.POLLIN,
}
_, e = BlockingPoll(&event, 1, nil)
@@ -119,21 +120,39 @@ func BlockingRead(fd int, b []byte) (int, tcpip.Error) {
// stores the data in a list of iovecs buffers. If no data is available, it will
// block in a poll() syscall until the file descriptor becomes readable.
func BlockingReadv(fd int, iovecs []unix.Iovec) (int, tcpip.Error) {
+ return BlockingReadvWithCancel(fd, iovecs, nil)
+}
+
+func BlockingReadvWithCancel(fd int, iovecs []unix.Iovec, cancel *os.File) (int, tcpip.Error) {
for {
n, _, e := unix.RawSyscall(unix.SYS_READV, uintptr(fd), uintptr(unsafe.Pointer(&iovecs[0])), uintptr(len(iovecs)))
if e == 0 {
return int(n), nil
}
- event := PollEvent{
- FD: int32(fd),
- Events: 1, // POLLIN
+ var cancelFd uintptr = 0
+ nfds := 1
+
+ if cancel != nil {
+ cancelFd = cancel.Fd()
+ nfds += 1
}
- _, e = BlockingPoll(&event, 1, nil)
+ events := []PollEvent{{
+ FD: int32(fd),
+ Events: unix.POLLIN,
+ },{
+ FD: int32(cancelFd),
+ Events: unix.POLLIN,
+ }}
+
+ _, e = BlockingPoll(&events[0], nfds, nil)
if e != 0 && e != unix.EINTR {
return 0, TranslateErrno(e)
}
+ if nfds > 1 && events[1].Revents == unix.POLLIN {
+ return 0, &tcpip.ErrAborted{}
+ }
}
}
@@ -157,7 +176,7 @@ func BlockingRecvMMsg(fd int, msgHdrs []MMsgHdr) (int, tcpip.Error) {
event := PollEvent{
FD: int32(fd),
- Events: 1, // POLLIN
+ Events: unix.POLLIN,
}
if _, e := BlockingPoll(&event, 1, nil); e != 0 && e != unix.EINTR {