Go version
go version go1.22.0 darwin/amd64
Output of go env
in your module/workspace:
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/Users/mikeschinkel/Library/Caches/go-build'
GOENV='/Users/mikeschinkel/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/mikeschinkel/go/gopath/pkg/mod'
GONOPROXY='github.com/newclarity/*'
GONOSUMDB='github.com/newclarity/*'
GOOS='darwin'
GOPATH='/Users/mikeschinkel/go/gopath'
GOPRIVATE='github.com/newclarity/*'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/mikeschinkel/go/go1.22.0'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/mikeschinkel/go/go1.22.0/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.22.0'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/fg/1dfmwyrx3wxbhj5lbdqpt7bw0000gn/T/go-build1267079162=/tmp/go-build -gno-record-gcc-switches -fno-common'
What did you do?
Call scanner.Scan()
on a closed file handle:
fh, _ := os.Open(f.Filepath())
fh.Close() // This by accident, long story
scanner = bufio.NewScanner(fh)
for scanner.Scan() {
print("Never printed")
}
if err := scanner.Err(); err != nil {
print("Never saw an error")
}
What did you see happen?
scanner.Err()
did not set an error telling me the file was already closed.
What did you expect to see?
An error to be set after the call to s.r.Read()
within scanner.Scan
when s.r.Read()
returns an err that the file is already closed.
I would love to submit a PR for this with just a little guidance.
Should I just set the error to fs.ErrClosed
or do I create a new error bufio.ErrFileClosed
here and set that instead when fs.ErrClosed
occurs?
Also, if I need to return a new error then for performance reasons should I use err==fs.ErrClosed
or do I need to use errors.Is(err,fs.ErrClosed)
for robustness?
If you want me to submit a PR for this and you give me this guidance I will be happy to follow the contributors guidelines and submit a PR. I have already signed the contributor license agreement.
Comment From: gabyhelp
Related Issues
- bufio: Scanner.Err() checks for io.EOF directly #58670 (closed)
- bufio: unexpected behavior of (*Scanner).Scan(), (*Scanner).Bytes() after ErrTooLong #65257
- affected/package: bufio.Scanner #60855 (closed)
- os/file: more helpful message when trying to read from closed file #17320 (closed)
- bufio: Scanner.Scan() behavior changed for empty reader #66946 (closed)
- os: missing conversion of internal/poll.ErrFileClosing to fs.ErrClosed in os.File.Stat() #66665 (closed)
- Advance bufio.Scanner when ErrTooLong is set. #26431 (closed)
- bufio: Scanner.Scan panics on poorly behaved io.Reader during an error #38053 (closed)
- os: missing conversion of internal/poll.ErrFileClosing to fs.ErrClosed #58622 (closed)
- bufio: Reader.Read may return io.EOF even when it has data buffered #32693 (closed)
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: ianlancetaylor
I can't recreate the problem. When I run this program:
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
f, err := os.Open("/")
if err != nil {
log.Fatal(err)
}
f.Close()
s := bufio.NewScanner(f)
for s.Scan() {
log.Fatal("impossible")
}
fmt.Printf("error: %v\n", s.Err())
}
I get
error: read /: file already closed
Comment From: mikeschinkel
@ianlancetaylor — My bad. I was running into some other problems evidently and when I did not see the error being immediately checked after the read I made an incorrect assumption. But debugging through it I now see that the err is checked later.
Sorry for the trouble.
Comment From: ianlancetaylor
Thanks for following up.