]> Cypherpunks repositories - gostls13.git/commitdiff
internal/testenv: probe for symlink on wasip1
authorJohan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Fri, 28 Apr 2023 04:39:57 +0000 (21:39 -0700)
committerJohan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Tue, 2 May 2023 05:22:00 +0000 (05:22 +0000)
Certain WASI runtimes do not support generic symlinks, and
instead return permission errors when they are attempted.
Perform a runtime probe of symlink support in hasSymlink
on wasip1 to determine whether the runtime supports
generic symlinks.

Also perform the same probe on android.

For #59583

Change-Id: Iae5b704e670650d38ee350a5a98f99dcce8b5b28
Reviewed-on: https://go-review.googlesource.com/c/go/+/490115
Auto-Submit: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Reviewed-by: Achille Roussel <achille.roussel@gmail.com>
TryBot-Bypass: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
src/internal/testenv/testenv.go
src/internal/testenv/testenv_notunix.go
src/internal/testenv/testenv_notwin.go

index aeda1f964f71101d270ad39d1be8e942cbbe6ed4..d03bb0550aa98e10c081ed99f04f77e9cb3df594 100644 (file)
@@ -387,7 +387,7 @@ func HasSymlink() bool {
 func MustHaveSymlink(t testing.TB) {
        ok, reason := hasSymlink()
        if !ok {
-               t.Skipf("skipping test: cannot make symlinks on %s/%s%s", runtime.GOOS, runtime.GOARCH, reason)
+               t.Skipf("skipping test: cannot make symlinks on %s/%s%s", runtime.GOOS, runtime.GOARCH, reason)
        }
 }
 
index 31abe8d0924d74e2e3567450b9a4ed0f9e305953..a7df5f5ddcecea267bccc61cabd74a25a4d80312 100644 (file)
@@ -8,6 +8,7 @@ package testenv
 
 import (
        "errors"
+       "io/fs"
        "os"
 )
 
@@ -16,5 +17,5 @@ import (
 var Sigquit = os.Kill
 
 func syscallIsNotSupported(err error) bool {
-       return errors.Is(err, errors.ErrUnsupported)
+       return errors.Is(err, fs.ErrPermission) || errors.Is(err, errors.ErrUnsupported)
 }
index 81171fd193ffbade5ca560ff9b8015f15a6147f2..30e159a6ecd4a2d2902639e33378f3a603d36352 100644 (file)
@@ -7,13 +7,39 @@
 package testenv
 
 import (
+       "fmt"
+       "os"
+       "path/filepath"
        "runtime"
 )
 
 func hasSymlink() (ok bool, reason string) {
        switch runtime.GOOS {
-       case "android", "plan9":
+       case "plan9":
                return false, ""
+       case "android", "wasip1":
+               // For wasip1, some runtimes forbid absolute symlinks,
+               // or symlinks that escape the current working directory.
+               // Perform a simple test to see whether the runtime
+               // supports symlinks or not. If we get a permission
+               // error, the runtime does not support symlinks.
+               dir, err := os.MkdirTemp("", "")
+               if err != nil {
+                       return false, ""
+               }
+               defer func() {
+                       _ = os.RemoveAll(dir)
+               }()
+               fpath := filepath.Join(dir, "testfile.txt")
+               if err := os.WriteFile(fpath, nil, 0644); err != nil {
+                       return false, ""
+               }
+               if err := os.Symlink(fpath, filepath.Join(dir, "testlink")); err != nil {
+                       if SyscallIsNotSupported(err) {
+                               return false, fmt.Sprintf("symlinks unsupported: %s", err.Error())
+                       }
+                       return false, ""
+               }
        }
 
        return true, ""