go: os: MkdirAll returns error with 'NUL' on Windows

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

go1.10 windows/amd64, go version devel +b63b0f2b75 Tue Mar 27 08:16:50 2018 +0000 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

GOOS=windows GOARCH=amd64

What did you do?

Tried to use os.MkdirAll on “NUL”: os.MkdirAll("NUL", 0777)

What did you expect to see?

no error returned, as is the case with: os.Mkdir("NUL", 0777).

What did you see instead?

An os.PathError: The system cannot find the path specified.

Additional

Similar to https://github.com/golang/go/issues/24482

https://golang.org/src/os/path.go?s=705:716#L24 Is the problem area, since NUL is not considered a directory, MkDirAll returns a PathError. In the Windows command interpreter md NUL and md intermediate\paths\NUL create no paths and return no errors. However md NUL\path\beyond will return an error.

Attn: @alexbrainman

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 23 (22 by maintainers)

Commits related to this issue

Most upvoted comments

I think the only correct change would be to make os.Mkdir("NUL", mode) return an error. From what people say above that call does not do anything, and also does not return an error. That is not ideal, regardless of what the Windows command interpreter does.

It is not the Windows command interpreter, it is Windows CreateDirectory API returns success.

https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createdirectoryw

I built this little test

diff --git a/src/os/path_test.go b/src/os/path_test.go
index 6cb25bcaa7..69fafc8723 100644
--- a/src/os/path_test.go
+++ b/src/os/path_test.go
@@ -126,3 +126,10 @@ func TestMkdirAllAtSlash(t *testing.T) {
        }
        RemoveAll("/_go_os_test")
 }
+
+func TestMkdirDevNull(t *testing.T) {
+       err := MkdirAll(DevNull, 0777)
+       t.Errorf("os.MkdirAll(os.DevNull) error: %q %#v", err, err)
+       err = Mkdir(DevNull, 0777)
+       t.Errorf("os.Mkdir(os.DevNull) error: %q %#v", err, err)
+}

and it outputs this on Linux

$ go test -v -run=TestMkdirDev
=== RUN   TestMkdirDevNull
--- FAIL: TestMkdirDevNull (0.00s)
    path_test.go:132: os.MkdirAll(os.DevNull) error: "mkdir /dev/null: not a directory" &os.PathError{Op:"mkdir", Path:"/dev/null", Err:0x14}
    path_test.go:134: os.Mkdir(os.DevNull) error: "mkdir /dev/null: file exists" &os.PathError{Op:"mkdir", Path:"/dev/null", Err:0x11}
FAIL
exit status 1
FAIL    os      0.006s

and this on Windows

C:\> go test -v -run=TestMkdirDev
=== RUN   TestMkdirDevNull
--- FAIL: TestMkdirDevNull (0.01s)
    path_test.go:132: os.MkdirAll(os.DevNull) error: "mkdir NUL: The system cann
ot find the path specified." &os.PathError{Op:"mkdir", Path:"NUL", Err:0x3}
    path_test.go:134: os.Mkdir(os.DevNull) error: %!q(<nil>) <nil>
FAIL

Err:0x3 is ERROR_PATH_NOT_FOUND. Perhaps os.Mkdir(os.DevNull) should also return ERROR_PATH_NOT_FOUND. ERROR_PATH_NOT_FOUND is even mentioned in https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createdirectoryw

I do not see downsides of changing os.Mkdir(os.DevNull) to return ERROR_PATH_NOT_FOUND.

I will do this change unless others object.

Alex