os: add deadline methods for File type

Add SetDeadline, SetReadDeadline, and SetWriteDeadline methods to os.File,
just as they exist today for the net package.

Fixes #22114

Change-Id: I4d390d739169b991175baba676010897dc8568fa
Reviewed-on: https://go-review.googlesource.com/71770
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
Ian Lance Taylor 2017-10-17 13:57:34 -07:00
parent 1126d1483f
commit 187957d370
11 changed files with 734 additions and 11 deletions

View file

@ -6,6 +6,7 @@ package os
import (
"errors"
"internal/poll"
)
// Portable analogs of some common system call errors.
@ -15,8 +16,13 @@ var (
ErrExist = errors.New("file already exists")
ErrNotExist = errors.New("file does not exist")
ErrClosed = errors.New("file already closed")
ErrNoDeadline = poll.ErrNoDeadline
)
type timeout interface {
Timeout() bool
}
// PathError records an error and the operation and file path that caused it.
type PathError struct {
Op string
@ -26,6 +32,12 @@ type PathError struct {
func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }
// Timeout reports whether this error represents a timeout.
func (e *PathError) Timeout() bool {
t, ok := e.Err.(timeout)
return ok && t.Timeout()
}
// SyscallError records an error from a specific system call.
type SyscallError struct {
Syscall string
@ -34,6 +46,12 @@ type SyscallError struct {
func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Err.Error() }
// Timeout reports whether this error represents a timeout.
func (e *SyscallError) Timeout() bool {
t, ok := e.Err.(timeout)
return ok && t.Timeout()
}
// NewSyscallError returns, as an error, a new SyscallError
// with the given system call name and error details.
// As a convenience, if err is nil, NewSyscallError returns nil.
@ -65,6 +83,13 @@ func IsPermission(err error) bool {
return isPermission(err)
}
// IsTimeout returns a boolean indicating whether the error is known
// to report that a timeout occurred.
func IsTimeout(err error) bool {
terr, ok := underlyingError(err).(timeout)
return ok && terr.Timeout()
}
// underlyingError returns the underlying error for known os error types.
func underlyingError(err error) error {
switch err := err.(type) {