]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: improve handling of os.DevNull on Windows
authorDamien Neil <dneil@google.com>
Wed, 9 Nov 2022 17:42:04 +0000 (09:42 -0800)
committerDamien Neil <dneil@google.com>
Wed, 9 Nov 2022 22:05:51 +0000 (22:05 +0000)
The "go test" and "go build" commands have special-case behavior when
passed "-o /dev/null". These checks are case-sensitive and assume that
os.DevNull is an absolute path. Windows filesystems are case-insensitive
and os.DevNull is NUL, which is not an absolute path.

CL 145220 changed filepath.IsAbs to report "NUL" as absolute to work
around this issue; that change is being rolled back and a better fix here
is to compare the value of -o against os.DevNull before attempting to
merge it with a base path. Make that fix.

On Windows, accept any capitilization of "NUL" as the null device.

This change doesn't cover every possible name for the null device, such
as "-o //./NUL", but this test is for efficiency rather than correctness.
Accepting just the most common name is fine.

For #56217.

Change-Id: I60b59b671789fc456074d3c8bc755a74ea8d5765
Reviewed-on: https://go-review.googlesource.com/c/go/+/449117
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
src/cmd/go/internal/base/path.go
src/cmd/go/internal/test/test.go
src/cmd/go/internal/work/build.go

index 4d8715ef5fe002a349d83e956eb4493e9c698fe0..ebe4f153ed2a20d9c2b13107687108351082ad54 100644 (file)
@@ -7,6 +7,7 @@ package base
 import (
        "os"
        "path/filepath"
+       "runtime"
        "strings"
        "sync"
 )
@@ -54,3 +55,17 @@ func IsTestFile(file string) bool {
        // We don't cover tests, only the code they test.
        return strings.HasSuffix(file, "_test.go")
 }
+
+// IsNull reports whether the path is a common name for the null device.
+// It returns true for /dev/null on Unix, or NUL (case-insensitive) on Windows.
+func IsNull(path string) bool {
+       if path == os.DevNull {
+               return true
+       }
+       if runtime.GOOS == "windows" {
+               if strings.EqualFold(path, "NUL") {
+                       return true
+               }
+       }
+       return false
+}
index 6ec32dfa1e4b8c1ba1336bbeeedb230ac864c62f..5a5600982941a15b328da17e46656f51062483e1 100644 (file)
@@ -1010,13 +1010,16 @@ func builderTest(b *work.Builder, ctx context.Context, pkgOpts load.PackageOpts,
        if testC || testNeedBinary() {
                // -c or profiling flag: create action to copy binary to ./test.out.
                target := filepath.Join(base.Cwd(), testBinary+cfg.ExeSuffix)
+               isNull := false
                if testO != "" {
                        target = testO
-                       if !filepath.IsAbs(target) {
+                       if base.IsNull(target) {
+                               isNull = true
+                       } else if !filepath.IsAbs(target) {
                                target = filepath.Join(base.Cwd(), target)
                        }
                }
-               if target == os.DevNull {
+               if isNull {
                        runAction = buildAction
                } else {
                        pmain.Target = target
index 98babc0024ee135a49a5dbeb5c3f14b3a87dbb39..848f07029f1c80372a2b2b52b6bb5b4dd82feaea 100644 (file)
@@ -482,7 +482,7 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) {
        pkgs = omitTestOnly(pkgsFilter(pkgs))
 
        // Special case -o /dev/null by not writing at all.
-       if cfg.BuildO == os.DevNull {
+       if base.IsNull(cfg.BuildO) {
                cfg.BuildO = ""
        }