Skip to content

Commit 5a10d8a

Browse files
Bryan C. Millsgopherbot
Bryan C. Mills
authored andcommitted
internal/testenv: in HasExec, try to actually exec on ios and wasm platforms
Some iOS environments may support exec. wasip1 and js do not, but trying to exec on those platforms is inexpensive anyway and gives better test coverage for the ios path. Change-Id: I4baffb2ef5dc7d81e6a260f69033bfb229f13d92 Reviewed-on: https://go-review.googlesource.com/c/go/+/486275 TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Bryan Mills <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Auto-Submit: Bryan Mills <[email protected]>
1 parent d5fea50 commit 5a10d8a

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

src/internal/testenv/exec.go

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,65 @@ import (
1919
// HasExec reports whether the current system can start new processes
2020
// using os.StartProcess or (more commonly) exec.Command.
2121
func HasExec() bool {
22+
tryExecOnce.Do(func() {
23+
tryExecOk = tryExec()
24+
})
25+
return tryExecOk
26+
}
27+
28+
var (
29+
tryExec = func() bool { return true }
30+
tryExecOnce sync.Once
31+
tryExecOk bool
32+
)
33+
34+
func init() {
2235
switch runtime.GOOS {
2336
case "wasip1", "js", "ios":
37+
default:
38+
// Assume that exec always works on non-mobile platforms and Android.
39+
return
40+
}
41+
42+
// ios has an exec syscall but on real iOS devices it might return a
43+
// permission error. In an emulated environment (such as a Corellium host)
44+
// it might succeed, so if we need to exec we'll just have to try it and
45+
// find out.
46+
//
47+
// As of 2023-04-19 wasip1 and js don't have exec syscalls at all, but we
48+
// may as well use the same path so that this branch can be tested without
49+
// an ios environment.
50+
51+
if !testing.Testing() {
52+
// This isn't a standard 'go test' binary, so we don't know how to
53+
// self-exec in a way that should succeed without side effects.
54+
// Just forget it.
55+
tryExec = func() bool { return false }
56+
return
57+
}
58+
59+
// We know that this is a test executable.
60+
// We should be able to run it with a no-op flag and the original test
61+
// execution environment to check for overall exec support.
62+
63+
// Save the original environment during init for use in the check. A test
64+
// binary may modify its environment before calling HasExec to change its
65+
// behavior// (such as mimicking a command-line tool), and that modified
66+
// environment might cause our self-test to behave unpredictably.
67+
origEnv := os.Environ()
68+
69+
tryExec = func() bool {
70+
exe, err := os.Executable()
71+
if err != nil {
72+
return false
73+
}
74+
cmd := exec.Command(exe, "-test.list=^$")
75+
cmd.Env = origEnv
76+
if err := cmd.Run(); err == nil {
77+
tryExecOk = true
78+
}
2479
return false
2580
}
26-
return true
2781
}
2882

2983
// MustHaveExec checks that the current system can start new processes

0 commit comments

Comments
 (0)