diff options
author | Ian Gudger <igudger@google.com> | 2018-12-20 13:47:46 -0800 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-12-20 13:48:52 -0800 |
commit | f6274804e14ece853c952cb71fde73dfb06b733a (patch) | |
tree | 1e1684de8aa6c2d4ddd025a0ef7ff4168ea9f137 /pkg/sentry/syscalls | |
parent | 194ef586fcb1bec049ee8777c2e5f70997de7a87 (diff) |
Make read and write respect SO_RCVTIMEO and SO_SNDTIMEO
PiperOrigin-RevId: 226387521
Change-Id: I0579ab262320fde6c72d2994dd38437f01a99ea5
Diffstat (limited to 'pkg/sentry/syscalls')
-rw-r--r-- | pkg/sentry/syscalls/linux/sys_read.go | 23 | ||||
-rw-r--r-- | pkg/sentry/syscalls/linux/sys_write.go | 23 |
2 files changed, 44 insertions, 2 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_read.go b/pkg/sentry/syscalls/linux/sys_read.go index b6df4d9d4..8105e9b43 100644 --- a/pkg/sentry/syscalls/linux/sys_read.go +++ b/pkg/sentry/syscalls/linux/sys_read.go @@ -15,11 +15,15 @@ package linux import ( + "time" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs" + ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" + "gvisor.googlesource.com/gvisor/pkg/sentry/socket" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" "gvisor.googlesource.com/gvisor/pkg/waiter" @@ -259,6 +263,20 @@ func readv(t *kernel.Task, f *fs.File, dst usermem.IOSequence) (int64, error) { return n, err } + // Sockets support read timeouts. + var haveDeadline bool + var deadline ktime.Time + if s, ok := f.FileOperations.(socket.Socket); ok { + dl := s.RecvTimeout() + if dl < 0 && err == syserror.ErrWouldBlock { + return n, err + } + if dl > 0 { + deadline = t.Kernel().MonotonicClock().Now().Add(time.Duration(dl) * time.Nanosecond) + haveDeadline = true + } + } + // Register for notifications. w, ch := waiter.NewChannelEntry(nil) f.EventRegister(&w, EventMaskRead) @@ -277,7 +295,10 @@ func readv(t *kernel.Task, f *fs.File, dst usermem.IOSequence) (int64, error) { } // Wait for a notification that we should retry. - if err = t.Block(ch); err != nil { + if err = t.BlockWithDeadline(ch, haveDeadline, deadline); err != nil { + if err == syserror.ETIMEDOUT { + err = syserror.ErrWouldBlock + } break } } diff --git a/pkg/sentry/syscalls/linux/sys_write.go b/pkg/sentry/syscalls/linux/sys_write.go index 750a098cd..a5ad7efb2 100644 --- a/pkg/sentry/syscalls/linux/sys_write.go +++ b/pkg/sentry/syscalls/linux/sys_write.go @@ -15,11 +15,15 @@ package linux import ( + "time" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs" + ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" + "gvisor.googlesource.com/gvisor/pkg/sentry/socket" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" "gvisor.googlesource.com/gvisor/pkg/waiter" @@ -263,6 +267,20 @@ func writev(t *kernel.Task, f *fs.File, src usermem.IOSequence) (int64, error) { return n, err } + // Sockets support write timeouts. + var haveDeadline bool + var deadline ktime.Time + if s, ok := f.FileOperations.(socket.Socket); ok { + dl := s.SendTimeout() + if dl < 0 && err == syserror.ErrWouldBlock { + return n, err + } + if dl > 0 { + deadline = t.Kernel().MonotonicClock().Now().Add(time.Duration(dl) * time.Nanosecond) + haveDeadline = true + } + } + // Register for notifications. w, ch := waiter.NewChannelEntry(nil) f.EventRegister(&w, EventMaskWrite) @@ -281,7 +299,10 @@ func writev(t *kernel.Task, f *fs.File, src usermem.IOSequence) (int64, error) { } // Wait for a notification that we should retry. - if err = t.Block(ch); err != nil { + if err = t.BlockWithDeadline(ch, haveDeadline, deadline); err != nil { + if err == syserror.ETIMEDOUT { + err = syserror.ErrWouldBlock + } break } } |