os.Stat and os.IsNotExist on Windows

802 views
Skip to first unread message

Petr Shevtsov

unread,
Dec 11, 2017, 11:05:27 AM12/11/17
to golang-nuts
Greetings, gophers!

I've spotted rather strange behavior of os.IsNotExist on Windows.

This snippet[1]

fi, err := os.Stat(s)
if os.IsNotExist(err) {
fmt.Println("Not a file")
return
}
mode := fi.Mode()
if mode.IsRegular() {
fmt.Println("File")
}

works perfectly on Linux but panics on Windows.

This happens because of os.Stat returns an error "CreateFile http://example.com/: The filename, directory name, or volume label syntax is incorrect." (errno 123[2]) for such input, but os.IsNotExist(err) returns false.

Is this a bug in os.IsNotExist[3] or such behavior is intentional?


[3] actually in isNotExit function in os/error_windows.go

--
Petr Shevtsov

Ian Lance Taylor

unread,
Dec 11, 2017, 1:08:01 PM12/11/17
to Petr Shevtsov, golang-nuts
On Mon, Dec 11, 2017 at 1:27 AM, Petr Shevtsov <petr.s...@gmail.com> wrote:
>
> I've spotted rather strange behavior of os.IsNotExist on Windows.
>
> This snippet[1]
>
> s := "http://example.com/"
> fi, err := os.Stat(s)
> if os.IsNotExist(err) {
> fmt.Println("Not a file")
> return
> }
> mode := fi.Mode()
> if mode.IsRegular() {
> fmt.Println("File")
> }
>
> works perfectly on Linux but panics on Windows.
>
> This happens because of os.Stat returns an error "CreateFile
> http://example.com/: The filename, directory name, or volume label syntax is
> incorrect." (errno 123[2]) for such input, but os.IsNotExist(err) returns
> false.
>
> Is this a bug in os.IsNotExist[3] or such behavior is intentional?

This sounds like a bug, although it may not be easy to fix. Please
open an bug report at https://golang.org/issue. Thanks.

Ian

Taru Karttunen

unread,
Dec 12, 2017, 7:24:01 AM12/12/17
to Ian Lance Taylor, Petr Shevtsov, golang-nuts
On 11.12 10:07, Ian Lance Taylor wrote:
> On Mon, Dec 11, 2017 at 1:27 AM, Petr Shevtsov <petr.s...@gmail.com> wrote:
> > s := "http://example.com/"
> > fi, err := os.Stat(s)
> > if os.IsNotExist(err) {
> >
> > Is this a bug in os.IsNotExist[3] or such behavior is intentional?
>
> This sounds like a bug, although it may not be easy to fix. Please
> open an bug report at https://golang.org/issue. Thanks.

Isn't this just case of a path that is valid on Linux and invalid on
Windows? Invalid paths don't match IsNotExist on Linux either (e.g.
ENAMETOOLONG).

- Taru Karttunen

Manlio Perillo

unread,
Dec 12, 2017, 8:33:43 AM12/12/17
to golang-nuts

Manlio Perillo

unread,
Dec 12, 2017, 8:34:47 AM12/12/17
to golang-nuts
Il giorno lunedì 11 dicembre 2017 17:05:27 UTC+1, Petr Shevtsov ha scritto:
Greetings, gophers!

I've spotted rather strange behavior of os.IsNotExist on Windows.

This snippet[1]

fi, err := os.Stat(s)
if os.IsNotExist(err) {
fmt.Println("Not a file")
return
}
mode := fi.Mode()
if mode.IsRegular() {
fmt.Println("File")
}

works perfectly on Linux but panics on Windows.


Note that your code is incorrect, since you access fi when os.Stat returns a non nil error.

> [...]


Manlio Perillo

Manlio Perillo

unread,
Dec 12, 2017, 9:32:55 AM12/12/17
to golang-nuts
I have opened the bug #23105.

See also #18974.

Currently on UNIX systems isNotExist only checks for ENOENT, but what about ELOOP, ENAMETOOLONG and ENOTDIR?
EACCESS and EOVERFLOW are more subtle, but probably the problem is trying to use os.IsNotExist after calling os.Stat to check if a file does not exist.

To check if a file does not exist the correct way is, IMHO, to check if os.Stat returns an error; this is what Python os.path.exists do.


Manlio 
Reply all
Reply to author
Forward
0 new messages