diff options
-rw-r--r-- | src/os/file_anyos.go | 7 | ||||
-rw-r--r-- | src/os/file_anyos_test.go | 19 |
2 files changed, 25 insertions, 1 deletions
diff --git a/src/os/file_anyos.go b/src/os/file_anyos.go index 593512cb5..33445e79f 100644 --- a/src/os/file_anyos.go +++ b/src/os/file_anyos.go @@ -1,6 +1,6 @@ //go:build !baremetal && !js && !wasm_unknown && !nintendoswitch -// Portions copyright 2009 The Go Authors. All rights reserved. +// Portions copyright 2009-2024 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -97,6 +97,11 @@ type unixFileHandle uintptr // read and any error encountered. At end of file, Read returns 0, io.EOF. func (f unixFileHandle) Read(b []byte) (n int, err error) { n, err = syscall.Read(syscallFd(f), b) + // In case of EISDIR, n == -1. + // This breaks the assumption that n always represent the number of read bytes. + if err == syscall.EISDIR { + n = 0 + } err = handleSyscallError(err) if n == 0 && len(b) > 0 && err == nil { err = io.EOF diff --git a/src/os/file_anyos_test.go b/src/os/file_anyos_test.go index c7d6e50ac..97f8ea13e 100644 --- a/src/os/file_anyos_test.go +++ b/src/os/file_anyos_test.go @@ -185,3 +185,22 @@ func TestClose(t *testing.T) { } } } + +func TestReadOnDir(t *testing.T) { + name := TempDir() + "/_os_test_TestReadOnDir" + defer Remove(name) + f, err := OpenFile(name, O_RDWR|O_CREATE, 0644) + if err != nil { + t.Errorf("OpenFile %s: %s", name, err) + return + } + var buf [32]byte + n, err := f.Read(buf[:]) + if err == nil { + t.Errorf("Error expected") + return + } + if n != 0 { + t.Errorf("Wrong read bytes: %s", err) + } +} |