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
)
21 ep
, err
:= os
.Executable()
23 t
.Fatalf("Executable failed: %v", err
)
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
)
29 t
.Fatalf("filepath.Rel: %v", err
)
33 // make child start with a relative program path
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" || runtime
.GOOS
== "aix" {
40 // OpenBSD and AIX rely on argv[0]
43 cmd
.Env
= append(os
.Environ(), fmt
.Sprintf("%s=1", executable_EnvVar
))
44 out
, err
:= cmd
.CombinedOutput()
46 t
.Fatalf("exec(self) failed: %v", err
)
49 if !filepath
.IsAbs(outs
) {
50 t
.Fatalf("Child returned %q, want an absolute path", out
)
52 if !sameFile(outs
, ep
) {
53 t
.Fatalf("Child returned %q, not the same file as %q", out
, ep
)
57 func sameFile(fn1
, fn2
string) bool {
58 fi1
, err
:= os
.Stat(fn1
)
62 fi2
, err
:= os
.Stat(fn2
)
66 return os
.SameFile(fi1
, fi2
)
70 if e
:= os
.Getenv(executable_EnvVar
); e
!= "" {
71 // first chdir to another path
73 if runtime
.GOOS
== "windows" {
74 cwd
, err
:= os
.Getwd()
78 dir
= filepath
.VolumeName(cwd
)
81 if ep
, err
:= os
.Executable(); err
!= nil {
82 fmt
.Fprint(os
.Stderr
, "ERROR: ", err
)
84 fmt
.Fprint(os
.Stderr
, ep
)