Skip to content

Commit

Permalink
cmd/go: improve handling of os.DevNull on Windows
Browse files Browse the repository at this point in the history
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 <[email protected]>
Run-TryBot: Damien Neil <[email protected]>
Reviewed-by: Bryan Mills <[email protected]>
  • Loading branch information
neild committed Nov 9, 2022
1 parent 0521a12 commit 575964d
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 3 deletions.
15 changes: 15 additions & 0 deletions src/cmd/go/internal/base/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package base
import (
"os"
"path/filepath"
"runtime"
"strings"
"sync"
)
Expand Down Expand Up @@ -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
}
7 changes: 5 additions & 2 deletions src/cmd/go/internal/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/go/internal/work/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ""
}

Expand Down

0 comments on commit 575964d

Please sign in to comment.