import (
        "internal/testenv"
-       "math"
        "os"
        "os/signal"
        "runtime"
                t.Fatalf("second Release: got err %v, want %v", err, want)
        }
 }
-
-// Lookup of a process that does not exist at time of lookup.
-func TestProcessAlreadyDone(t *testing.T) {
-       if runtime.GOOS == "windows" {
-               t.Skip("Windows does not support lookup of non-existant process")
-       }
-       if runtime.GOARCH == "wasm" {
-               t.Skip("Wait not supported om wasm port")
-       }
-
-       // Theoretically MaxInt32 is a valid PID, but the chance of it actually
-       // being used is extremely unlikely.
-       p, err := os.FindProcess(math.MaxInt32)
-       if err != nil {
-               t.Fatalf("FindProcess(math.MaxInt32) got err %v, want nil", err)
-       }
-
-       if ps, err := p.Wait(); err != os.ErrProcessDone {
-               t.Errorf("Wait() got err %v (ps %+v), want ErrProcessDone", err, ps)
-       }
-
-       if err := p.Release(); err != nil {
-               t.Errorf("Release() got err %v, want nil", err)
-       }
-}
 
 package os_test
 
 import (
+       "errors"
        "internal/testenv"
+       "math"
        . "os"
+       "runtime"
        "syscall"
        "testing"
 )
        }
 }
 
+// Lookup of a process that does not exist at time of lookup.
+func TestProcessAlreadyDone(t *testing.T) {
+       // Theoretically MaxInt32 is a valid PID, but the chance of it actually
+       // being used is extremely unlikely.
+       pid := math.MaxInt32
+       if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" {
+               // Solaris/Illumos have a lower limit, above which wait returns
+               // EINVAL (see waitid in usr/src/uts/common/os/exit.c in
+               // illumos). This is configurable via sysconf(_SC_MAXPID), but
+               // we'll just take the default.
+               pid = 30000-1
+       }
+
+       p, err := FindProcess(pid)
+       if err != nil {
+               t.Fatalf("FindProcess(math.MaxInt32) got err %v, want nil", err)
+       }
+
+       if ps, err := p.Wait(); !errors.Is(err, syscall.ECHILD) {
+               t.Errorf("Wait() got err %v (ps %+v), want %v", err, ps, syscall.ECHILD)
+       }
+
+       if err := p.Release(); err != nil {
+               t.Errorf("Release() got err %v, want nil", err)
+       }
+}
+
 func TestUNIXProcessAlive(t *testing.T) {
        testenv.MustHaveGoBuild(t)
        t.Parallel()
 
        handle, status := p.handleTransientAcquire()
        switch status {
        case statusDone:
-               return nil, ErrProcessDone
+               // Process already completed Wait, or was not found by
+               // pidfdFind. Return ECHILD for consistency with what the wait
+               // syscall would return.
+               return nil, NewSyscallError("wait", syscall.ECHILD)
        case statusReleased:
                return nil, syscall.EINVAL
        }
 
 package os_test
 
 import (
+       "errors"
        "internal/testenv"
        "os"
+       "syscall"
        "testing"
 )
 
        if err := proc.Signal(os.Kill); err != os.ErrProcessDone {
                t.Errorf("Signal: got %v, want %v", err, os.ErrProcessDone)
        }
-       if _, err := proc.Wait(); err != os.ErrProcessDone {
+       if _, err := proc.Wait(); !errors.Is(err, syscall.ECHILD) {
                t.Errorf("Wait: got %v, want %v", err, os.ErrProcessDone)
        }
        // Release never returns errors on Unix.