adds experimental sys.Errno to begin decoupling from the syscall package (#1582)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
@@ -2,9 +2,8 @@ package gojs
|
||||
|
||||
import (
|
||||
"io"
|
||||
"syscall"
|
||||
|
||||
"github.com/tetratelabs/wazero/internal/platform"
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
)
|
||||
|
||||
// Errno is a (GOARCH=wasm) error, which must match a key in mapJSError.
|
||||
@@ -62,50 +61,50 @@ var (
|
||||
|
||||
// ToErrno maps I/O errors as the message must be the code, ex. "EINVAL", not
|
||||
// the message, e.g. "invalid argument".
|
||||
//
|
||||
// This should match wasi_snapshot_preview1.ToErrno for maintenance ease.
|
||||
func ToErrno(err error) *Errno {
|
||||
if err == nil || err == io.EOF {
|
||||
return nil // io.EOF has no value in GOOS=js, and isn't an error.
|
||||
}
|
||||
errno := platform.UnwrapOSError(err)
|
||||
|
||||
switch errno {
|
||||
case syscall.EACCES:
|
||||
return ErrnoAcces
|
||||
case syscall.EAGAIN:
|
||||
return ErrnoAgain
|
||||
case syscall.EBADF:
|
||||
return ErrnoBadf
|
||||
case syscall.EEXIST:
|
||||
return ErrnoExist
|
||||
case syscall.EFAULT:
|
||||
return ErrnoFault
|
||||
case syscall.EINTR:
|
||||
return ErrnoIntr
|
||||
case syscall.EINVAL:
|
||||
return ErrnoInval
|
||||
case syscall.EIO:
|
||||
errno, ok := err.(sys.Errno)
|
||||
if !ok {
|
||||
return ErrnoIo
|
||||
case syscall.EISDIR:
|
||||
}
|
||||
switch errno {
|
||||
case sys.EACCES:
|
||||
return ErrnoAcces
|
||||
case sys.EAGAIN:
|
||||
return ErrnoAgain
|
||||
case sys.EBADF:
|
||||
return ErrnoBadf
|
||||
case sys.EEXIST:
|
||||
return ErrnoExist
|
||||
case sys.EFAULT:
|
||||
return ErrnoFault
|
||||
case sys.EINTR:
|
||||
return ErrnoIntr
|
||||
case sys.EINVAL:
|
||||
return ErrnoInval
|
||||
case sys.EIO:
|
||||
return ErrnoIo
|
||||
case sys.EISDIR:
|
||||
return ErrnoIsdir
|
||||
case syscall.ELOOP:
|
||||
case sys.ELOOP:
|
||||
return ErrnoLoop
|
||||
case syscall.ENAMETOOLONG:
|
||||
case sys.ENAMETOOLONG:
|
||||
return ErrnoNametoolong
|
||||
case syscall.ENOENT:
|
||||
case sys.ENOENT:
|
||||
return ErrnoNoent
|
||||
case syscall.ENOSYS:
|
||||
case sys.ENOSYS:
|
||||
return ErrnoNosys
|
||||
case syscall.ENOTDIR:
|
||||
case sys.ENOTDIR:
|
||||
return ErrnoNotdir
|
||||
case syscall.ENOTEMPTY:
|
||||
case sys.ENOTEMPTY:
|
||||
return ErrnoNotempty
|
||||
case syscall.ENOTSUP:
|
||||
case sys.ENOTSUP:
|
||||
return ErrnoNotsup
|
||||
case syscall.EPERM:
|
||||
case sys.EPERM:
|
||||
return ErrnoPerm
|
||||
case syscall.EROFS:
|
||||
case sys.EROFS:
|
||||
return ErrnoRofs
|
||||
default:
|
||||
return ErrnoIo
|
||||
|
||||
@@ -2,8 +2,9 @@ package gojs
|
||||
|
||||
import (
|
||||
"io"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
)
|
||||
|
||||
func TestToErrno(t *testing.T) {
|
||||
@@ -20,98 +21,98 @@ func TestToErrno(t *testing.T) {
|
||||
input: io.EOF,
|
||||
},
|
||||
{
|
||||
name: "syscall.EACCES",
|
||||
input: syscall.EACCES,
|
||||
name: "sys.EACCES",
|
||||
input: sys.EACCES,
|
||||
expected: ErrnoAcces,
|
||||
},
|
||||
{
|
||||
name: "syscall.EAGAIN",
|
||||
input: syscall.EAGAIN,
|
||||
name: "sys.EAGAIN",
|
||||
input: sys.EAGAIN,
|
||||
expected: ErrnoAgain,
|
||||
},
|
||||
{
|
||||
name: "syscall.EBADF",
|
||||
input: syscall.EBADF,
|
||||
name: "sys.EBADF",
|
||||
input: sys.EBADF,
|
||||
expected: ErrnoBadf,
|
||||
},
|
||||
{
|
||||
name: "syscall.EEXIST",
|
||||
input: syscall.EEXIST,
|
||||
name: "sys.EEXIST",
|
||||
input: sys.EEXIST,
|
||||
expected: ErrnoExist,
|
||||
},
|
||||
{
|
||||
name: "syscall.EFAULT",
|
||||
input: syscall.EFAULT,
|
||||
name: "sys.EFAULT",
|
||||
input: sys.EFAULT,
|
||||
expected: ErrnoFault,
|
||||
},
|
||||
{
|
||||
name: "syscall.EINTR",
|
||||
input: syscall.EINTR,
|
||||
name: "sys.EINTR",
|
||||
input: sys.EINTR,
|
||||
expected: ErrnoIntr,
|
||||
},
|
||||
{
|
||||
name: "syscall.EINVAL",
|
||||
input: syscall.EINVAL,
|
||||
name: "sys.EINVAL",
|
||||
input: sys.EINVAL,
|
||||
expected: ErrnoInval,
|
||||
},
|
||||
{
|
||||
name: "syscall.EIO",
|
||||
input: syscall.EIO,
|
||||
name: "sys.EIO",
|
||||
input: sys.EIO,
|
||||
expected: ErrnoIo,
|
||||
},
|
||||
{
|
||||
name: "syscall.EISDIR",
|
||||
input: syscall.EISDIR,
|
||||
name: "sys.EISDIR",
|
||||
input: sys.EISDIR,
|
||||
expected: ErrnoIsdir,
|
||||
},
|
||||
{
|
||||
name: "syscall.ELOOP",
|
||||
input: syscall.ELOOP,
|
||||
name: "sys.ELOOP",
|
||||
input: sys.ELOOP,
|
||||
expected: ErrnoLoop,
|
||||
},
|
||||
{
|
||||
name: "syscall.ENAMETOOLONG",
|
||||
input: syscall.ENAMETOOLONG,
|
||||
name: "sys.ENAMETOOLONG",
|
||||
input: sys.ENAMETOOLONG,
|
||||
expected: ErrnoNametoolong,
|
||||
},
|
||||
{
|
||||
name: "syscall.ENOENT",
|
||||
input: syscall.ENOENT,
|
||||
name: "sys.ENOENT",
|
||||
input: sys.ENOENT,
|
||||
expected: ErrnoNoent,
|
||||
},
|
||||
{
|
||||
name: "syscall.ENOSYS",
|
||||
input: syscall.ENOSYS,
|
||||
name: "sys.ENOSYS",
|
||||
input: sys.ENOSYS,
|
||||
expected: ErrnoNosys,
|
||||
},
|
||||
{
|
||||
name: "syscall.ENOTDIR",
|
||||
input: syscall.ENOTDIR,
|
||||
name: "sys.ENOTDIR",
|
||||
input: sys.ENOTDIR,
|
||||
expected: ErrnoNotdir,
|
||||
},
|
||||
{
|
||||
name: "syscall.ENOTEMPTY",
|
||||
input: syscall.ENOTEMPTY,
|
||||
name: "sys.ENOTEMPTY",
|
||||
input: sys.ENOTEMPTY,
|
||||
expected: ErrnoNotempty,
|
||||
},
|
||||
{
|
||||
name: "syscall.ENOTSUP",
|
||||
input: syscall.ENOTSUP,
|
||||
name: "sys.ENOTSUP",
|
||||
input: sys.ENOTSUP,
|
||||
expected: ErrnoNotsup,
|
||||
},
|
||||
{
|
||||
name: "syscall.EPERM",
|
||||
input: syscall.EPERM,
|
||||
name: "sys.EPERM",
|
||||
input: sys.EPERM,
|
||||
expected: ErrnoPerm,
|
||||
},
|
||||
{
|
||||
name: "syscall.EROFS",
|
||||
input: syscall.EROFS,
|
||||
name: "sys.EROFS",
|
||||
input: sys.EROFS,
|
||||
expected: ErrnoRofs,
|
||||
},
|
||||
{
|
||||
name: "syscall.Errno unexpected == ErrnoIo",
|
||||
input: syscall.Errno(0xfe),
|
||||
name: "sys.Errno unexpected == ErrnoIo",
|
||||
input: sys.Errno(0xfe),
|
||||
expected: ErrnoIo,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
|
||||
"github.com/tetratelabs/wazero/internal/gojs/custom"
|
||||
"github.com/tetratelabs/wazero/internal/gojs/goos"
|
||||
"github.com/tetratelabs/wazero/internal/gojs/util"
|
||||
@@ -174,7 +175,7 @@ func (jsfsFstat) invoke(ctx context.Context, mod api.Module, args ...interface{}
|
||||
func syscallFstat(fsc *internalsys.FSContext, fd int32) (*jsSt, error) {
|
||||
f, ok := fsc.LookupFile(fd)
|
||||
if !ok {
|
||||
return nil, syscall.EBADF
|
||||
return nil, experimentalsys.EBADF
|
||||
}
|
||||
|
||||
if st, errno := f.File.Stat(); errno != 0 {
|
||||
@@ -239,11 +240,11 @@ func (jsfsRead) invoke(ctx context.Context, mod api.Module, args ...interface{})
|
||||
}
|
||||
|
||||
// syscallRead is like syscall.Read
|
||||
func syscallRead(mod api.Module, fd int32, offset interface{}, buf []byte) (n int, errno syscall.Errno) {
|
||||
func syscallRead(mod api.Module, fd int32, offset interface{}, buf []byte) (n int, errno experimentalsys.Errno) {
|
||||
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
|
||||
|
||||
if f, ok := fsc.LookupFile(fd); !ok {
|
||||
return 0, syscall.EBADF
|
||||
return 0, experimentalsys.EBADF
|
||||
} else if offset != nil {
|
||||
return f.File.Pread(buf, toInt64(offset))
|
||||
} else {
|
||||
@@ -282,17 +283,17 @@ func (jsfsWrite) invoke(ctx context.Context, mod api.Module, args ...interface{}
|
||||
}
|
||||
|
||||
// syscallWrite is like syscall.Write
|
||||
func syscallWrite(mod api.Module, fd int32, offset interface{}, buf []byte) (n int, errno syscall.Errno) {
|
||||
func syscallWrite(mod api.Module, fd int32, offset interface{}, buf []byte) (n int, errno experimentalsys.Errno) {
|
||||
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
|
||||
if f, ok := fsc.LookupFile(fd); !ok {
|
||||
errno = syscall.EBADF
|
||||
errno = experimentalsys.EBADF
|
||||
} else if offset != nil {
|
||||
n, errno = f.File.Pwrite(buf, toInt64(offset))
|
||||
} else {
|
||||
n, errno = f.File.Write(buf)
|
||||
}
|
||||
if errno == syscall.ENOSYS {
|
||||
errno = syscall.EBADF // e.g. unimplemented for write
|
||||
if errno == experimentalsys.ENOSYS {
|
||||
errno = experimentalsys.EBADF // e.g. unimplemented for write
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -350,7 +351,7 @@ func (m *jsfsMkdir) invoke(ctx context.Context, mod api.Module, args ...interfac
|
||||
root := fsc.RootFS()
|
||||
|
||||
var fd int32
|
||||
var errno syscall.Errno
|
||||
var errno experimentalsys.Errno
|
||||
// We need at least read access to open the file descriptor
|
||||
if perm == 0 {
|
||||
perm = 0o0500
|
||||
@@ -467,11 +468,11 @@ func (jsfsFchmod) invoke(ctx context.Context, mod api.Module, args ...interface{
|
||||
|
||||
// Check to see if the file descriptor is available
|
||||
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
|
||||
var errno syscall.Errno
|
||||
var errno experimentalsys.Errno
|
||||
if _, ok := fsc.LookupFile(fd); !ok {
|
||||
errno = syscall.EBADF
|
||||
errno = experimentalsys.EBADF
|
||||
} else {
|
||||
errno = syscall.ENOSYS // We only support functions used in wasip1
|
||||
errno = experimentalsys.ENOSYS // We only support functions used in wasip1
|
||||
}
|
||||
|
||||
return jsfsInvoke(ctx, mod, callback, errno)
|
||||
@@ -490,7 +491,7 @@ func (c *jsfsChown) invoke(ctx context.Context, mod api.Module, args ...interfac
|
||||
_ = args[2] // gid
|
||||
callback := args[3].(funcWrapper)
|
||||
|
||||
errno := syscall.ENOSYS // We only support functions used in wasip1
|
||||
errno := experimentalsys.ENOSYS // We only support functions used in wasip1
|
||||
|
||||
return jsfsInvoke(ctx, mod, callback, errno)
|
||||
}
|
||||
@@ -508,11 +509,11 @@ func (jsfsFchown) invoke(ctx context.Context, mod api.Module, args ...interface{
|
||||
|
||||
// Check to see if the file descriptor is available
|
||||
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
|
||||
var errno syscall.Errno
|
||||
var errno experimentalsys.Errno
|
||||
if _, ok := fsc.LookupFile(fd); !ok {
|
||||
errno = syscall.EBADF
|
||||
errno = experimentalsys.EBADF
|
||||
} else {
|
||||
errno = syscall.ENOSYS // We only support functions used in wasip1
|
||||
errno = experimentalsys.ENOSYS // We only support functions used in wasip1
|
||||
}
|
||||
|
||||
return jsfsInvoke(ctx, mod, callback, errno)
|
||||
@@ -531,7 +532,7 @@ func (l *jsfsLchown) invoke(ctx context.Context, mod api.Module, args ...interfa
|
||||
_ = args[2] // gid
|
||||
callback := args[3].(funcWrapper)
|
||||
|
||||
errno := syscall.ENOSYS // We only support functions used in wasip1
|
||||
errno := experimentalsys.ENOSYS // We only support functions used in wasip1
|
||||
|
||||
return jsfsInvoke(ctx, mod, callback, errno)
|
||||
}
|
||||
@@ -548,7 +549,7 @@ func (t *jsfsTruncate) invoke(ctx context.Context, mod api.Module, args ...inter
|
||||
_ = args[1] // length
|
||||
callback := args[2].(funcWrapper)
|
||||
|
||||
errno := syscall.ENOSYS // We only support functions used in wasip1
|
||||
errno := experimentalsys.ENOSYS // We only support functions used in wasip1
|
||||
|
||||
return jsfsInvoke(ctx, mod, callback, errno)
|
||||
}
|
||||
@@ -565,9 +566,9 @@ func (jsfsFtruncate) invoke(ctx context.Context, mod api.Module, args ...interfa
|
||||
|
||||
// Check to see if the file descriptor is available
|
||||
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
|
||||
var errno syscall.Errno
|
||||
var errno experimentalsys.Errno
|
||||
if f, ok := fsc.LookupFile(fd); !ok {
|
||||
errno = syscall.EBADF
|
||||
errno = experimentalsys.EBADF
|
||||
} else {
|
||||
errno = f.File.Truncate(length)
|
||||
}
|
||||
@@ -640,9 +641,9 @@ func (jsfsFsync) invoke(ctx context.Context, mod api.Module, args ...interface{}
|
||||
|
||||
// Check to see if the file descriptor is available
|
||||
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
|
||||
var errno syscall.Errno
|
||||
var errno experimentalsys.Errno
|
||||
if f, ok := fsc.LookupFile(fd); !ok {
|
||||
errno = syscall.EBADF
|
||||
errno = experimentalsys.EBADF
|
||||
} else {
|
||||
errno = f.File.Sync()
|
||||
}
|
||||
@@ -714,11 +715,11 @@ func (s *jsSt) call(_ context.Context, _ api.Module, _ goos.Ref, method string,
|
||||
panic(fmt.Sprintf("TODO: stat.%s", method))
|
||||
}
|
||||
|
||||
func jsfsInvoke(ctx context.Context, mod api.Module, callback funcWrapper, err syscall.Errno) (interface{}, error) {
|
||||
func jsfsInvoke(ctx context.Context, mod api.Module, callback funcWrapper, err experimentalsys.Errno) (interface{}, error) {
|
||||
return callback.invoke(ctx, mod, goos.RefJsfs, maybeError(err), err == 0) // note: error first
|
||||
}
|
||||
|
||||
func maybeError(errno syscall.Errno) error {
|
||||
func maybeError(errno experimentalsys.Errno) error {
|
||||
if errno != 0 {
|
||||
return errno
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package gojs
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"syscall"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
"github.com/tetratelabs/wazero/internal/gojs/custom"
|
||||
"github.com/tetratelabs/wazero/internal/gojs/goos"
|
||||
"github.com/tetratelabs/wazero/internal/gojs/util"
|
||||
@@ -65,7 +65,7 @@ func (p *processChdir) invoke(_ context.Context, mod api.Module, args ...interfa
|
||||
if s, err := syscallStat(mod, newWd); err != nil {
|
||||
return nil, err
|
||||
} else if !s.isDir {
|
||||
return nil, syscall.ENOTDIR
|
||||
return nil, sys.ENOTDIR
|
||||
} else {
|
||||
p.proc.cwd = newWd
|
||||
return nil, nil
|
||||
|
||||
@@ -3,10 +3,10 @@ package gojs
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
"github.com/tetratelabs/wazero/internal/gojs/custom"
|
||||
"github.com/tetratelabs/wazero/internal/gojs/goarch"
|
||||
"github.com/tetratelabs/wazero/internal/wasm"
|
||||
@@ -47,9 +47,9 @@ func wasmWrite(_ context.Context, mod api.Module, stack goarch.Stack) {
|
||||
switch errno {
|
||||
case 0:
|
||||
return // success
|
||||
case syscall.ENOSYS:
|
||||
case sys.ENOSYS:
|
||||
return // e.g. unimplemented for write
|
||||
case syscall.EBADF:
|
||||
case sys.EBADF:
|
||||
return // e.g. not opened for write
|
||||
default:
|
||||
panic(fmt.Errorf("error writing p: %w", errno))
|
||||
|
||||
4
internal/gojs/testdata/writefs/stat.go
vendored
4
internal/gojs/testdata/writefs/stat.go
vendored
@@ -3,10 +3,10 @@
|
||||
package writefs
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
)
|
||||
|
||||
// statFields isn't used outside JS, it is only for compilation
|
||||
func statFields(string) (atimeNsec, mtimeNsec int64, dev, inode uint64) {
|
||||
panic(syscall.ENOSYS)
|
||||
panic(sys.ENOSYS)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user