singleflight: make the check for exec support in TestPanicDoChan platform-agnostic

The new wasip1 GOOS does not support exec, but some ios environments
(like Corellium) might. Update the test to exec itself with -test.list
as a control case.

For golang/go#58141.

Change-Id: Id69950fc394910620f6c73cb437ca75c09ad8c29
Reviewed-on: https://go-review.googlesource.com/c/sync/+/485980
Run-TryBot: Bryan Mills <bcmills@google.com>
Commit-Queue: Bryan Mills <bcmills@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/singleflight/singleflight_test.go b/singleflight/singleflight_test.go
index 3e51203..4a4e0b8 100644
--- a/singleflight/singleflight_test.go
+++ b/singleflight/singleflight_test.go
@@ -223,11 +223,24 @@
 	}
 }
 
-func TestPanicDoChan(t *testing.T) {
-	if runtime.GOOS == "js" {
-		t.Skipf("js does not support exec")
+func executable(t testing.TB) string {
+	exe, err := os.Executable()
+	if err != nil {
+		t.Skipf("skipping: test executable not found")
 	}
 
+	// Control case: check whether exec.Command works at all.
+	// (For example, it might fail with a permission error on iOS.)
+	cmd := exec.Command(exe, "-test.list=^$")
+	cmd.Env = []string{}
+	if err := cmd.Run(); err != nil {
+		t.Skipf("skipping: exec appears not to work on %s: %v", runtime.GOOS, err)
+	}
+
+	return exe
+}
+
+func TestPanicDoChan(t *testing.T) {
 	if os.Getenv("TEST_PANIC_DOCHAN") != "" {
 		defer func() {
 			recover()
@@ -243,7 +256,7 @@
 
 	t.Parallel()
 
-	cmd := exec.Command(os.Args[0], "-test.run="+t.Name(), "-test.v")
+	cmd := exec.Command(executable(t), "-test.run="+t.Name(), "-test.v")
 	cmd.Env = append(os.Environ(), "TEST_PANIC_DOCHAN=1")
 	out := new(bytes.Buffer)
 	cmd.Stdout = out
@@ -266,10 +279,6 @@
 }
 
 func TestPanicDoSharedByDoChan(t *testing.T) {
-	if runtime.GOOS == "js" {
-		t.Skipf("js does not support exec")
-	}
-
 	if os.Getenv("TEST_PANIC_DOCHAN") != "" {
 		blocked := make(chan struct{})
 		unblock := make(chan struct{})
@@ -297,7 +306,7 @@
 
 	t.Parallel()
 
-	cmd := exec.Command(os.Args[0], "-test.run="+t.Name(), "-test.v")
+	cmd := exec.Command(executable(t), "-test.run="+t.Name(), "-test.v")
 	cmd.Env = append(os.Environ(), "TEST_PANIC_DOCHAN=1")
 	out := new(bytes.Buffer)
 	cmd.Stdout = out