github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/cmd/go/run.go (about) 1 // Copyright 2011 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 package main 6 7 import ( 8 "fmt" 9 "os" 10 "os/exec" 11 "runtime" 12 "strings" 13 ) 14 15 var execCmd []string // -exec flag, for run and test 16 17 func findExecCmd() []string { 18 if execCmd != nil { 19 return execCmd 20 } 21 execCmd = []string{} // avoid work the second time 22 if goos == runtime.GOOS && goarch == runtime.GOARCH { 23 return execCmd 24 } 25 path, err := exec.LookPath(fmt.Sprintf("go_%s_%s_exec", goos, goarch)) 26 if err == nil { 27 execCmd = []string{path} 28 } 29 return execCmd 30 } 31 32 var cmdRun = &Command{ 33 UsageLine: "run [build flags] [-exec xprog] gofiles... [arguments...]", 34 Short: "compile and run Go program", 35 Long: ` 36 Run compiles and runs the main package comprising the named Go source files. 37 A Go source file is defined to be a file ending in a literal ".go" suffix. 38 39 By default, 'go run' runs the compiled binary directly: 'a.out arguments...'. 40 If the -exec flag is given, 'go run' invokes the binary using xprog: 'xprog a.out arguments...'. 41 If the -exec flag is not given, GOOS or GOARCH is different from the system 42 default, and a program named go_$GOOS_$GOARCH_exec can be found 43 on the current search path, 'go run' invokes the binary using that program, 44 for example 'go_nacl_386_exec a.out arguments...'. This allows execution of 45 cross-compiled programs when a simulator or other execution method is 46 available. 47 48 For more about build flags, see 'go help build'. 49 50 See also: go build. 51 `, 52 } 53 54 func init() { 55 cmdRun.Run = runRun // break init loop 56 57 addBuildFlags(cmdRun) 58 cmdRun.Flag.Var((*stringsFlag)(&execCmd), "exec", "") 59 } 60 61 func printStderr(args ...interface{}) (int, error) { 62 return fmt.Fprint(os.Stderr, args...) 63 } 64 65 func runRun(cmd *Command, args []string) { 66 raceInit() 67 var b builder 68 b.init() 69 b.print = printStderr 70 i := 0 71 for i < len(args) && strings.HasSuffix(args[i], ".go") { 72 i++ 73 } 74 files, cmdArgs := args[:i], args[i:] 75 if len(files) == 0 { 76 fatalf("go run: no go files listed") 77 } 78 for _, file := range files { 79 if strings.HasSuffix(file, "_test.go") { 80 // goFilesPackage is going to assign this to TestGoFiles. 81 // Reject since it won't be part of the build. 82 fatalf("go run: cannot run *_test.go files (%s)", file) 83 } 84 } 85 p := goFilesPackage(files) 86 if p.Error != nil { 87 fatalf("%s", p.Error) 88 } 89 p.omitDWARF = true 90 for _, err := range p.DepsErrors { 91 errorf("%s", err) 92 } 93 exitIfErrors() 94 if p.Name != "main" { 95 fatalf("go run: cannot run non-main package") 96 } 97 p.target = "" // must build - not up to date 98 var src string 99 if len(p.GoFiles) > 0 { 100 src = p.GoFiles[0] 101 } else if len(p.CgoFiles) > 0 { 102 src = p.CgoFiles[0] 103 } else { 104 // this case could only happen if the provided source uses cgo 105 // while cgo is disabled. 106 hint := "" 107 if !buildContext.CgoEnabled { 108 hint = " (cgo is disabled)" 109 } 110 fatalf("go run: no suitable source files%s", hint) 111 } 112 p.exeName = src[:len(src)-len(".go")] // name temporary executable for first go file 113 a1 := b.action(modeBuild, modeBuild, p) 114 a := &action{f: (*builder).runProgram, args: cmdArgs, deps: []*action{a1}} 115 b.do(a) 116 } 117 118 // runProgram is the action for running a binary that has already 119 // been compiled. We ignore exit status. 120 func (b *builder) runProgram(a *action) error { 121 cmdline := stringList(findExecCmd(), a.deps[0].target, a.args) 122 if buildN || buildX { 123 b.showcmd("", "%s", strings.Join(cmdline, " ")) 124 if buildN { 125 return nil 126 } 127 } 128 129 runStdin(cmdline) 130 return nil 131 } 132 133 // runStdin is like run, but connects Stdin. 134 func runStdin(cmdline []string) { 135 cmd := exec.Command(cmdline[0], cmdline[1:]...) 136 cmd.Stdin = os.Stdin 137 cmd.Stdout = os.Stdout 138 cmd.Stderr = os.Stderr 139 startSigHandlers() 140 if err := cmd.Run(); err != nil { 141 errorf("%v", err) 142 } 143 }