golang.org/toolchain@v0.0.1-go1.9rc2.windows-amd64/src/os/executable_test.go (about) 1 // Copyright 2016 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 os_test 6 7 import ( 8 "fmt" 9 "internal/testenv" 10 "os" 11 osexec "os/exec" 12 "path/filepath" 13 "runtime" 14 "testing" 15 ) 16 17 const executable_EnvVar = "OSTEST_OUTPUT_EXECPATH" 18 19 func TestExecutable(t *testing.T) { 20 testenv.MustHaveExec(t) // will also execlude nacl, which doesn't support Executable anyway 21 ep, err := os.Executable() 22 if err != nil { 23 t.Fatalf("Executable failed: %v", err) 24 } 25 // we want fn to be of the form "dir/prog" 26 dir := filepath.Dir(filepath.Dir(ep)) 27 fn, err := filepath.Rel(dir, ep) 28 if err != nil { 29 t.Fatalf("filepath.Rel: %v", err) 30 } 31 32 cmd := &osexec.Cmd{} 33 // make child start with a relative program path 34 cmd.Dir = dir 35 cmd.Path = fn 36 // forge argv[0] for child, so that we can verify we could correctly 37 // get real path of the executable without influenced by argv[0]. 38 cmd.Args = []string{"-", "-test.run=XXXX"} 39 if runtime.GOOS == "openbsd" { 40 // OpenBSD relies on argv[0] 41 cmd.Args[0] = fn 42 } 43 cmd.Env = append(os.Environ(), fmt.Sprintf("%s=1", executable_EnvVar)) 44 out, err := cmd.CombinedOutput() 45 if err != nil { 46 t.Fatalf("exec(self) failed: %v", err) 47 } 48 outs := string(out) 49 if !filepath.IsAbs(outs) { 50 t.Fatalf("Child returned %q, want an absolute path", out) 51 } 52 if !sameFile(outs, ep) { 53 t.Fatalf("Child returned %q, not the same file as %q", out, ep) 54 } 55 } 56 57 func sameFile(fn1, fn2 string) bool { 58 fi1, err := os.Stat(fn1) 59 if err != nil { 60 return false 61 } 62 fi2, err := os.Stat(fn2) 63 if err != nil { 64 return false 65 } 66 return os.SameFile(fi1, fi2) 67 } 68 69 func init() { 70 if e := os.Getenv(executable_EnvVar); e != "" { 71 // first chdir to another path 72 dir := "/" 73 if runtime.GOOS == "windows" { 74 cwd, err := os.Getwd() 75 if err != nil { 76 panic(err) 77 } 78 dir = filepath.VolumeName(cwd) 79 } 80 os.Chdir(dir) 81 if ep, err := os.Executable(); err != nil { 82 fmt.Fprint(os.Stderr, "ERROR: ", err) 83 } else { 84 fmt.Fprint(os.Stderr, ep) 85 } 86 os.Exit(0) 87 } 88 }