go version)?go1.9.2 linux/amd64
Yes
go env)?GOARCH="amd64"
GOBIN="/home/manlio/.local/bin"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/manlio/.local/lib/go:/home/manlio/code/src/go"
GORACE=""
GOROOT="/usr/lib/go"
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build134836490=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
https://play.golang.org/p/7xo02WfeHR
Also, see https://groups.google.com/forum/#!topic/golang-nuts/MZ_u50ZIB_I
file does not exist
file exist
stat xxx...xxx: File name too long
This is probably a duplicate of #18974
@perillo I don't think it's a dup. #18974 was about ENOTDIR. This is about ENAMETOOLONG. I think it would be reasonable for IsNotExist to return true for ENAMETOOLONG; if we see that error, we know for sure that the file does not exist.
Responding to ENAMETOOLONG probably warrants a different approach than with ENOENT/ErrNotExist. I don't think it should be covered by IsNotExist. I always thought of the latter as "a syscall returned ENOENT(or a Go function returned an error with similar semantics)". ENAMETOOLONG doesn't match that pattern.
The code looks very misleading to me: just because IsNotExist returns false on an error returned from stat, you can't conclude that the file exists. The call might've also hit some wildly different error.
Shouldn't the issue title read false instead of true?
@slrz Upon reflection, I think you're right. One could imagine a deep set of directories, a/b/c/d where let's assume that each letter is actually 255 characters long. Then opening a/b/c/d/e might fail with ENAMETOOLONG, whereas os.Chdir("a/b/c") followed by opening d/e might succeed. At least, that is my current understanding. If that is indeed possible, then I agree that ENAMETOOLONG does not necessarily mean that the file does not exist.
I don't think this should be fixed. non-nil err does not mean file not exists.
@mattn https://play.golang.org/p/MPqPCmPcjE
The linux man(3) page about errno defines ENAMETOOLONG as "Filename too long"
but the man(2) page about stat defines it as "pathname is too long"
From https://en.wikipedia.org/wiki/Filename and https://en.wikipedia.org/wiki/Path_(computing) it seems that pathname and filename are equivalent, so I don't understand why in my code os.Stat returns ENOENT instead of ENAMETOOLONG.
ENAMETOOLONG means the kernel refuses to deal with your input, and thus provides no information on whether a file exists or not.
@perillo, you need to handle your errors, of which IsNotExist is just one scenario. @mattn's example https://play.golang.org/p/BnbP5Lik-l is the right way to do it (apart from unnecessary nesting).
As far as I can tell, there is no bug here.
Please don't change the functionality of os.IsNotExist for ENAMETOOLONG or the various Windows cases.
Sounds like we don't want to change anything here and there's no bug.
Most helpful comment
Responding to
ENAMETOOLONGprobably warrants a different approach than withENOENT/ErrNotExist. I don't think it should be covered byIsNotExist. I always thought of the latter as "a syscall returnedENOENT(or a Go function returned an error with similar semantics)".ENAMETOOLONGdoesn't match that pattern.The code looks very misleading to me: just because
IsNotExistreturns false on an error returned from stat, you can't conclude that the file exists. The call might've also hit some wildly different error.