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.
17 const executable_EnvVar
= "OSTEST_OUTPUT_EXECPATH"
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()
23 switch goos
:= runtime
.GOOS
; goos
{
24 case "openbsd": // procfs is not mounted by default
25 t
.Skipf("Executable failed on %s: %v, expected", goos
, err
)
27 t
.Fatalf("Executable failed: %v", err
)
29 // we want fn to be of the form "dir/prog"
30 dir
:= filepath
.Dir(filepath
.Dir(ep
))
31 fn
, err
:= filepath
.Rel(dir
, ep
)
33 t
.Fatalf("filepath.Rel: %v", err
)
36 // make child start with a relative program path
39 // forge argv[0] for child, so that we can verify we could correctly
40 // get real path of the executable without influenced by argv[0].
41 cmd
.Args
= []string{"-", "-test.run=XXXX"}
42 cmd
.Env
= append(os
.Environ(), fmt
.Sprintf("%s=1", executable_EnvVar
))
43 out
, err
:= cmd
.CombinedOutput()
45 t
.Fatalf("exec(self) failed: %v", err
)
48 if !filepath
.IsAbs(outs
) {
49 t
.Fatalf("Child returned %q, want an absolute path", out
)
51 if !sameFile(outs
, ep
) {
52 t
.Fatalf("Child returned %q, not the same file as %q", out
, ep
)
56 func sameFile(fn1
, fn2
string) bool {
57 fi1
, err
:= os
.Stat(fn1
)
61 fi2
, err
:= os
.Stat(fn2
)
65 return os
.SameFile(fi1
, fi2
)
69 if e
:= os
.Getenv(executable_EnvVar
); e
!= "" {
70 // first chdir to another path
72 if runtime
.GOOS
== "windows" {
73 cwd
, err
:= os
.Getwd()
77 dir
= filepath
.VolumeName(cwd
)
80 if ep
, err
:= os
.Executable(); err
!= nil {
81 fmt
.Fprint(os
.Stderr
, "ERROR: ", err
)
83 fmt
.Fprint(os
.Stderr
, ep
)