github.com/bir3/gocompiler@v0.9.2202/src/cmd/gocmd/internal/toolchain/exec.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build !js && !wasip1 6 7 package toolchain 8 9 import ( 10 "github.com/bir3/gocompiler/src/cmd/gocmd/internal/base" 11 "github.com/bir3/gocompiler/src/internal/godebug" 12 "os" 13 "github.com/bir3/gocompiler/exec" 14 "runtime" 15 "syscall" 16 ) 17 18 // execGoToolchain execs the Go toolchain with the given name (gotoolchain), 19 // GOROOT directory, and go command executable. 20 // The GOROOT directory is empty if we are invoking a command named 21 // gotoolchain found in $PATH. 22 func execGoToolchain(gotoolchain, dir, exe string) { 23 os.Setenv(targetEnv, gotoolchain) 24 if dir == "" { 25 os.Unsetenv("GOROOT") 26 } else { 27 os.Setenv("GOROOT", dir) 28 } 29 30 // On Windows, there is no syscall.Exec, so the best we can do 31 // is run a subprocess and exit with the same status. 32 // Doing the same on Unix would be a problem because it wouldn't 33 // propagate signals and such, but there are no signals on Windows. 34 // We also use the exec case when GODEBUG=gotoolchainexec=0, 35 // to allow testing this code even when not on Windows. 36 if godebug.New("#gotoolchainexec").Value() == "0" || runtime.GOOS == "windows" { 37 cmd := exec.Command(exe, os.Args[1:]...) 38 cmd.Stdin = os.Stdin 39 cmd.Stdout = os.Stdout 40 cmd.Stderr = os.Stderr 41 err := cmd.Run() 42 if err != nil { 43 if e, ok := err.(*exec.ExitError); ok && e.ProcessState != nil { 44 if e.ProcessState.Exited() { 45 os.Exit(e.ProcessState.ExitCode()) 46 } 47 base.Fatalf("exec %s: %s", gotoolchain, e.ProcessState) 48 } 49 base.Fatalf("exec %s: %s", exe, err) 50 } 51 os.Exit(0) 52 } 53 err := syscall.Exec(exe, os.Args, os.Environ()) 54 base.Fatalf("exec %s: %v", gotoolchain, err) 55 }