Go: os: IsNotExist returns true for invalid file names

Created on 12 Dec 2017  路  10Comments  路  Source: golang/go

What version of Go are you using (go version)?

go1.9.2 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (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"

What did you do?

https://play.golang.org/p/7xo02WfeHR

Also, see https://groups.google.com/forum/#!topic/golang-nuts/MZ_u50ZIB_I

What did you expect to see?

file does not exist

What did you see instead?

file exist
stat xxx...xxx: File name too long

FrozenDueToAge NeedsFix

Most helpful comment

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.

All 10 comments

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.

https://play.golang.org/p/BnbP5Lik-l

@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.

Was this page helpful?
0 / 5 - 0 ratings