]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: in 'go build -o', allow the destination file to exist if it is empty
authorBryan C. Mills <bcmills@google.com>
Mon, 11 Nov 2019 17:41:01 +0000 (12:41 -0500)
committerBryan C. Mills <bcmills@google.com>
Mon, 11 Nov 2019 20:16:49 +0000 (20:16 +0000)
This allows the target of 'go build' to be a filename constructed
using ioutil.TempFile or similar, without racily deleting the file
before rebuilding it.

Updates #32407
Updates #28387

Change-Id: I4c5072830a02b93f0c4186b50bffa9de00257afe
Reviewed-on: https://go-review.googlesource.com/c/go/+/206477
Run-TryBot: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Jay Conrod <jayconrod@google.com>
src/cmd/go/internal/work/exec.go
src/cmd/go/testdata/script/test_compile_tempfile.txt [new file with mode: 0644]

index a50de513f59bc0af78526338cb7adb7ace05e29d..c8849b49facd70b4c275a6095cf6e9806d500bc0 100644 (file)
@@ -1610,12 +1610,12 @@ func (b *Builder) copyFile(dst, src string, perm os.FileMode, force bool) error
 
        // Be careful about removing/overwriting dst.
        // Do not remove/overwrite if dst exists and is a directory
-       // or a non-object file.
+       // or a non-empty non-object file.
        if fi, err := os.Stat(dst); err == nil {
                if fi.IsDir() {
                        return fmt.Errorf("build output %q already exists and is a directory", dst)
                }
-               if !force && fi.Mode().IsRegular() && !isObject(dst) {
+               if !force && fi.Mode().IsRegular() && fi.Size() != 0 && !isObject(dst) {
                        return fmt.Errorf("build output %q already exists and is not an object file", dst)
                }
        }
diff --git a/src/cmd/go/testdata/script/test_compile_tempfile.txt b/src/cmd/go/testdata/script/test_compile_tempfile.txt
new file mode 100644 (file)
index 0000000..9124108
--- /dev/null
@@ -0,0 +1,11 @@
+[short] skip
+
+# Ensure that the target of 'go build -o' can be an existing, empty file so that
+# its name can be reserved using ioutil.TempFile or the 'mktemp` command.
+
+go build -o empty-file$GOEXE main.go
+
+-- main.go --
+package main
+func main() {}
+-- empty-file$GOEXE --