diff --git a/src/os/deadline_test.go b/src/os/deadline_test.go new file mode 100644 index 0000000000..03097e46ef --- /dev/null +++ b/src/os/deadline_test.go @@ -0,0 +1,50 @@ +//go:build posix && !baremetal && !js + +package os_test + +import ( + "errors" + . "os" + "testing" +) + +func TestDeadlines(t *testing.T) { + // Create a handle to a known-good, existing file + f, err := Open("/dev/null") + if err != nil { + t.Fatal(err) + } + + if err := f.SetDeadline(0); err == nil { + if err != nil { + t.Errorf("wanted nil, got %v", err) + } + } + + if err := f.SetDeadline(1); err == nil { + if !errors.Is(err, ErrNotImplemented) { + t.Errorf("wanted ErrNotImplemented, got %v", err) + } + } + + if err := f.SetReadDeadline(1); err == nil { + if !errors.Is(err, ErrNotImplemented) { + t.Errorf("wanted ErrNotImplemented, got %v", err) + } + } + + if err := f.SetWriteDeadline(1); err == nil { + if !errors.Is(err, ErrNotImplemented) { + t.Errorf("wanted ErrNotImplemented, got %v", err) + } + } + + // Closed files must return an error + f.Close() + + if err := f.SetDeadline(0); err == nil { + if err != ErrClosed { + t.Errorf("wanted ErrClosed, got %v", err) + } + } +} diff --git a/src/os/file.go b/src/os/file.go index 7c3c0db125..b47bf748a7 100644 --- a/src/os/file.go +++ b/src/os/file.go @@ -257,12 +257,29 @@ func (f *File) SyscallConn() (conn syscall.RawConn, err error) { return } +// SetDeadline sets the read and write deadlines for a File. +// Calls to SetDeadline for files that do not support deadlines will return ErrNoDeadline +// This stub always returns ErrNoDeadline. +// A zero value for t means I/O operations will not time out. +func (f *File) SetDeadline(t time.Time) error { + if f.handle == nil { + return ErrClosed + } + return f.setDeadline(t) +} + // SetReadDeadline sets the deadline for future Read calls and any // currently-blocked Read call. func (f *File) SetReadDeadline(t time.Time) error { return f.setReadDeadline(t) } +// SetWriteDeadline sets the deadline for any future Write calls and any +// currently-blocked Write call. +func (f *File) SetWriteDeadline(t time.Time) error { + return f.setWriteDeadline(t) +} + // fd is an internal interface that is used to try a type assertion in order to // call the Fd() method of the underlying file handle if it is implemented. type fd interface { diff --git a/src/os/file_posix.go b/src/os/file_posix.go index e36a6b1cd7..a10ff49196 100644 --- a/src/os/file_posix.go +++ b/src/os/file_posix.go @@ -4,12 +4,35 @@ import ( "time" ) +//TODO: re-implement the ErrNoDeadline error in the correct code path + // Chtimes is a stub, not yet implemented func Chtimes(name string, atime time.Time, mtime time.Time) error { return ErrNotImplemented } +// setDeadline sets the read and write deadline. +func (f *File) setDeadline(t time.Time) error { + if t.IsZero() { + return nil + } + return ErrNotImplemented +} + // setReadDeadline sets the read deadline, not yet implemented -func (f *File) setReadDeadline(_ time.Time) error { +// A zero value for t means Read will not time out. +func (f *File) setReadDeadline(t time.Time) error { + if t.IsZero() { + return nil + } + return ErrNotImplemented +} + +// setWriteDeadline sets the write deadline, not yet implemented +// A zero value for t means Read will not time out. +func (f *File) setWriteDeadline(t time.Time) error { + if t.IsZero() { + return nil + } return ErrNotImplemented }