Skip to content

Commit

Permalink
wasi: support conversion of wasi.Errno values to syscall.Errno (#71)
Browse files Browse the repository at this point in the history
This PR adds the `wasi.Errno.Syscall` method to convert errno values to
error codes of the host platform.

Signed-off-by: Achille Roussel <[email protected]>
  • Loading branch information
achille-roussel committed Jun 25, 2023
1 parent d1f5b98 commit 886c29d
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 4 deletions.
10 changes: 10 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package wasi

import (
"fmt"
"syscall"
)

// Errno are the error codes returned by functions.
Expand Down Expand Up @@ -263,6 +264,15 @@ func (e Errno) Name() string {
return fmt.Sprintf("errno(%d)", int(e))
}

// Syscall convers the error to a native error number of the host platform.
//
// The method does the inverse of passing the syscall.Errno value to
// wasi.MakeErrno tho some error numbers may differ on the host platform,
// therefore there is no guarantee that the wasi.Errno value obtained by a
// call to wasi.MakeErrno will yield the same syscall.Errno returned by this
// method.
func (e Errno) Syscall() syscall.Errno { return errnoToSyscall(e) }

var errorStrings = [...]string{
ESUCCESS: "OK",
E2BIG: "Argument list too long",
Expand Down
3 changes: 1 addition & 2 deletions error_darwin.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package wasi

import (
"fmt"
"syscall"
)

Expand Down Expand Up @@ -198,6 +197,6 @@ func syscallErrnoToWASI(err syscall.Errno) Errno {
// case syscall.ETOOMANYREFS:

default:
panic(fmt.Errorf("unexpected syscall.Errno(%d): %v", int(err), err))
panic("unsupported syscall errno: " + err.Error())
}
}
3 changes: 1 addition & 2 deletions error_linux.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package wasi

import (
"fmt"
"syscall"
)

Expand Down Expand Up @@ -222,6 +221,6 @@ func syscallErrnoToWASI(err syscall.Errno) Errno {
// case syscall.EXFULL:

default:
panic(fmt.Errorf("unexpected syscall.Errno(%d): %v", int(err), err))
panic("unsupported syscall errno: " + err.Error())
}
}
19 changes: 19 additions & 0 deletions error_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package wasi_test

import (
"testing"

"github.com/stealthrocket/wasi-go"
)

func TestErrno(t *testing.T) {
for errno := wasi.Errno(0); errno < wasi.ENOTCAPABLE; errno++ {
t.Run(errno.Name(), func(t *testing.T) {
e1 := errno.Syscall()
e2 := wasi.MakeErrno(e1)
if e2 != errno {
t.Errorf("conversion to syscall.Errno did not yield the same error code: want=%d got=%d", errno, e2)
}
})
}
}
161 changes: 161 additions & 0 deletions error_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,164 @@ func makeErrnoSlow(err error) Errno {
}
panic(fmt.Errorf("unexpected error: %v", err))
}

func errnoToSyscall(errno Errno) syscall.Errno {
switch errno {
case ESUCCESS:
return 0
case E2BIG:
return syscall.E2BIG
case EACCES:
return syscall.EACCES
case EADDRINUSE:
return syscall.EADDRINUSE
case EADDRNOTAVAIL:
return syscall.EADDRNOTAVAIL
case EAFNOSUPPORT:
return syscall.EAFNOSUPPORT
case EAGAIN:
return syscall.EAGAIN
case EALREADY:
return syscall.EALREADY
case EBADF:
return syscall.EBADF
case EBADMSG:
return syscall.EBADMSG
case EBUSY:
return syscall.EBUSY
case ECANCELED:
return syscall.ECANCELED
case ECHILD:
return syscall.ECHILD
case ECONNABORTED:
return syscall.ECONNABORTED
case ECONNREFUSED:
return syscall.ECONNREFUSED
case ECONNRESET:
return syscall.ECONNRESET
case EDEADLK:
return syscall.EDEADLK
case EDESTADDRREQ:
return syscall.EDESTADDRREQ
case EDOM:
return syscall.EDOM
case EDQUOT:
return syscall.EDQUOT
case EEXIST:
return syscall.EEXIST
case EFAULT:
return syscall.EFAULT
case EFBIG:
return syscall.EFBIG
case EHOSTUNREACH:
return syscall.EHOSTUNREACH
case EIDRM:
return syscall.EIDRM
case EILSEQ:
return syscall.EILSEQ
case EINPROGRESS:
return syscall.EINPROGRESS
case EINTR:
return syscall.EINTR
case EINVAL:
return syscall.EINVAL
case EIO:
return syscall.EIO
case EISCONN:
return syscall.EISCONN
case EISDIR:
return syscall.EISDIR
case ELOOP:
return syscall.ELOOP
case EMFILE:
return syscall.EMFILE
case EMLINK:
return syscall.EMLINK
case EMSGSIZE:
return syscall.EMSGSIZE
case EMULTIHOP:
return syscall.EMULTIHOP
case ENAMETOOLONG:
return syscall.ENAMETOOLONG
case ENETDOWN:
return syscall.ENETDOWN
case ENETRESET:
return syscall.ENETRESET
case ENETUNREACH:
return syscall.ENETUNREACH
case ENFILE:
return syscall.ENFILE
case ENOBUFS:
return syscall.ENOBUFS
case ENODEV:
return syscall.ENODEV
case ENOENT:
return syscall.ENOENT
case ENOEXEC:
return syscall.ENOEXEC
case ENOLCK:
return syscall.ENOLCK
case ENOLINK:
return syscall.ENOLINK
case ENOMEM:
return syscall.ENOMEM
case ENOMSG:
return syscall.ENOMSG
case ENOPROTOOPT:
return syscall.ENOPROTOOPT
case ENOSPC:
return syscall.ENOSPC
case ENOSYS:
return syscall.ENOSYS
case ENOTCONN:
return syscall.ENOTCONN
case ENOTDIR:
return syscall.ENOTDIR
case ENOTEMPTY:
return syscall.ENOTEMPTY
case ENOTRECOVERABLE:
return syscall.ENOTRECOVERABLE
case ENOTSOCK:
return syscall.ENOTSOCK
case ENOTSUP:
return syscall.ENOTSUP
case ENOTTY:
return syscall.ENOTTY
case ENXIO:
return syscall.ENXIO
case EOVERFLOW:
return syscall.EOVERFLOW
case EOWNERDEAD:
return syscall.EOWNERDEAD
case EPERM:
return syscall.EPERM
case EPIPE:
return syscall.EPIPE
case EPROTO:
return syscall.EPROTO
case EPROTONOSUPPORT:
return syscall.EPROTONOSUPPORT
case EPROTOTYPE:
return syscall.EPROTOTYPE
case ERANGE:
return syscall.ERANGE
case EROFS:
return syscall.EROFS
case ESPIPE:
return syscall.ESPIPE
case ESRCH:
return syscall.ESRCH
case ESTALE:
return syscall.ESTALE
case ETIMEDOUT:
return syscall.ETIMEDOUT
case ETXTBSY:
return syscall.ETXTBSY
case EXDEV:
return syscall.EXDEV
case ENOTCAPABLE:
return syscall.EPERM
default:
panic("unsupport wasi errno: " + errno.Error())
}
}

0 comments on commit 886c29d

Please sign in to comment.