wasi: support building internal/sysfs with TinyGo (#2160)
Signed-off-by: gram <git@orsinium.dev> Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com> Co-authored-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
This commit is contained in:
@@ -86,12 +86,6 @@ func (d *dirFS) Readlink(path string) (string, experimentalsys.Errno) {
|
|||||||
return platform.ToPosixPath(dst), 0
|
return platform.ToPosixPath(dst), 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link implements the same method as documented on sys.FS
|
|
||||||
func (d *dirFS) Link(oldName, newName string) experimentalsys.Errno {
|
|
||||||
err := os.Link(d.join(oldName), d.join(newName))
|
|
||||||
return experimentalsys.UnwrapOSError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rmdir implements the same method as documented on sys.FS
|
// Rmdir implements the same method as documented on sys.FS
|
||||||
func (d *dirFS) Rmdir(path string) experimentalsys.Errno {
|
func (d *dirFS) Rmdir(path string) experimentalsys.Errno {
|
||||||
return rmdir(d.join(path))
|
return rmdir(d.join(path))
|
||||||
|
|||||||
15
internal/sysfs/dirfs_link_supported.go
Normal file
15
internal/sysfs/dirfs_link_supported.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//go:build !tinygo
|
||||||
|
|
||||||
|
package sysfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Link implements the same method as documented on sys.FS
|
||||||
|
func (d *dirFS) Link(oldName, newName string) experimentalsys.Errno {
|
||||||
|
err := os.Link(d.join(oldName), d.join(newName))
|
||||||
|
return experimentalsys.UnwrapOSError(err)
|
||||||
|
}
|
||||||
12
internal/sysfs/dirfs_link_unsupported.go
Normal file
12
internal/sysfs/dirfs_link_unsupported.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
//go:build tinygo
|
||||||
|
|
||||||
|
package sysfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Link implements the same method as documented on sys.FS
|
||||||
|
func (d *dirFS) Link(oldName, newName string) experimentalsys.Errno {
|
||||||
|
return experimentalsys.ENOSYS
|
||||||
|
}
|
||||||
@@ -58,25 +58,6 @@ func newDefaultTCPListenerFile(tl *net.TCPListener) socketapi.TCPSock {
|
|||||||
return &tcpListenerFile{tl: tl}
|
return &tcpListenerFile{tl: tl}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accept implements the same method as documented on socketapi.TCPSock
|
|
||||||
func (f *tcpListenerFile) Accept() (socketapi.TCPConn, experimentalsys.Errno) {
|
|
||||||
// Ensure we have an incoming connection, otherwise return immediately.
|
|
||||||
if f.nonblock {
|
|
||||||
if ready, errno := _pollSock(f.tl, fsapi.POLLIN, 0); !ready || errno != 0 {
|
|
||||||
return nil, experimentalsys.EAGAIN
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accept normally blocks goroutines, but we
|
|
||||||
// made sure that we have an incoming connection,
|
|
||||||
// so we should be safe.
|
|
||||||
if conn, err := f.tl.Accept(); err != nil {
|
|
||||||
return nil, experimentalsys.UnwrapOSError(err)
|
|
||||||
} else {
|
|
||||||
return newTcpConn(conn.(*net.TCPConn)), 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close implements the same method as documented on experimentalsys.File
|
// Close implements the same method as documented on experimentalsys.File
|
||||||
func (f *tcpListenerFile) Close() experimentalsys.Errno {
|
func (f *tcpListenerFile) Close() experimentalsys.Errno {
|
||||||
if !f.closed {
|
if !f.closed {
|
||||||
@@ -90,15 +71,6 @@ func (f *tcpListenerFile) Addr() *net.TCPAddr {
|
|||||||
return f.tl.Addr().(*net.TCPAddr)
|
return f.tl.Addr().(*net.TCPAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetNonblock implements the same method as documented on fsapi.File
|
|
||||||
func (f *tcpListenerFile) SetNonblock(enabled bool) (errno experimentalsys.Errno) {
|
|
||||||
f.nonblock = enabled
|
|
||||||
_, errno = syscallConnControl(f.tl, func(fd uintptr) (int, experimentalsys.Errno) {
|
|
||||||
return 0, setNonblockSocket(fd, enabled)
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNonblock implements the same method as documented on fsapi.File
|
// IsNonblock implements the same method as documented on fsapi.File
|
||||||
func (f *tcpListenerFile) IsNonblock() bool {
|
func (f *tcpListenerFile) IsNonblock() bool {
|
||||||
return f.nonblock
|
return f.nonblock
|
||||||
@@ -182,23 +154,6 @@ func (f *tcpConnFile) Recvfrom(p []byte, flags int) (n int, errno experimentalsy
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown implements the same method as documented on experimentalsys.Conn
|
|
||||||
func (f *tcpConnFile) Shutdown(how int) experimentalsys.Errno {
|
|
||||||
// FIXME: can userland shutdown listeners?
|
|
||||||
var err error
|
|
||||||
switch how {
|
|
||||||
case socketapi.SHUT_RD:
|
|
||||||
err = f.tc.CloseRead()
|
|
||||||
case socketapi.SHUT_WR:
|
|
||||||
err = f.tc.CloseWrite()
|
|
||||||
case socketapi.SHUT_RDWR:
|
|
||||||
return f.close()
|
|
||||||
default:
|
|
||||||
return experimentalsys.EINVAL
|
|
||||||
}
|
|
||||||
return experimentalsys.UnwrapOSError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close implements the same method as documented on experimentalsys.File
|
// Close implements the same method as documented on experimentalsys.File
|
||||||
func (f *tcpConnFile) Close() experimentalsys.Errno {
|
func (f *tcpConnFile) Close() experimentalsys.Errno {
|
||||||
return f.close()
|
return f.close()
|
||||||
|
|||||||
@@ -1,13 +1,61 @@
|
|||||||
//go:build linux || darwin || windows
|
//go:build (linux || darwin || windows) && !tinygo
|
||||||
|
|
||||||
package sysfs
|
package sysfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
|
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
|
||||||
|
"github.com/tetratelabs/wazero/internal/fsapi"
|
||||||
|
socketapi "github.com/tetratelabs/wazero/internal/sock"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Accept implements the same method as documented on socketapi.TCPSock
|
||||||
|
func (f *tcpListenerFile) Accept() (socketapi.TCPConn, experimentalsys.Errno) {
|
||||||
|
// Ensure we have an incoming connection, otherwise return immediately.
|
||||||
|
if f.nonblock {
|
||||||
|
if ready, errno := _pollSock(f.tl, fsapi.POLLIN, 0); !ready || errno != 0 {
|
||||||
|
return nil, experimentalsys.EAGAIN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept normally blocks goroutines, but we
|
||||||
|
// made sure that we have an incoming connection,
|
||||||
|
// so we should be safe.
|
||||||
|
if conn, err := f.tl.Accept(); err != nil {
|
||||||
|
return nil, experimentalsys.UnwrapOSError(err)
|
||||||
|
} else {
|
||||||
|
return newTcpConn(conn.(*net.TCPConn)), 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNonblock implements the same method as documented on fsapi.File
|
||||||
|
func (f *tcpListenerFile) SetNonblock(enabled bool) (errno experimentalsys.Errno) {
|
||||||
|
f.nonblock = enabled
|
||||||
|
_, errno = syscallConnControl(f.tl, func(fd uintptr) (int, experimentalsys.Errno) {
|
||||||
|
return 0, setNonblockSocket(fd, enabled)
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shutdown implements the same method as documented on experimentalsys.Conn
|
||||||
|
func (f *tcpConnFile) Shutdown(how int) experimentalsys.Errno {
|
||||||
|
// FIXME: can userland shutdown listeners?
|
||||||
|
var err error
|
||||||
|
switch how {
|
||||||
|
case socketapi.SHUT_RD:
|
||||||
|
err = f.tc.CloseRead()
|
||||||
|
case socketapi.SHUT_WR:
|
||||||
|
err = f.tc.CloseWrite()
|
||||||
|
case socketapi.SHUT_RDWR:
|
||||||
|
return f.close()
|
||||||
|
default:
|
||||||
|
return experimentalsys.EINVAL
|
||||||
|
}
|
||||||
|
return experimentalsys.UnwrapOSError(err)
|
||||||
|
}
|
||||||
|
|
||||||
// syscallConnControl extracts a syscall.RawConn from the given syscall.Conn and applies
|
// syscallConnControl extracts a syscall.RawConn from the given syscall.Conn and applies
|
||||||
// the given fn to a file descriptor, returning an integer or a nonzero syscall.Errno on failure.
|
// the given fn to a file descriptor, returning an integer or a nonzero syscall.Errno on failure.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//go:build linux || darwin
|
//go:build (linux || darwin) && !tinygo
|
||||||
|
|
||||||
package sysfs
|
package sysfs
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//go:build !linux && !darwin && !windows
|
//go:build (!linux && !darwin && !windows) || tinygo
|
||||||
|
|
||||||
package sysfs
|
package sysfs
|
||||||
|
|
||||||
@@ -57,3 +57,25 @@ func recvfrom(fd uintptr, buf []byte, flags int32) (n int, errno sys.Errno) {
|
|||||||
func syscallConnControl(conn syscall.Conn, fn func(fd uintptr) (int, experimentalsys.Errno)) (n int, errno sys.Errno) {
|
func syscallConnControl(conn syscall.Conn, fn func(fd uintptr) (int, experimentalsys.Errno)) (n int, errno sys.Errno) {
|
||||||
return -1, sys.ENOTSUP
|
return -1, sys.ENOTSUP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Accept implements the same method as documented on socketapi.TCPSock
|
||||||
|
func (f *tcpListenerFile) Accept() (socketapi.TCPConn, experimentalsys.Errno) {
|
||||||
|
return nil, experimentalsys.ENOSYS
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shutdown implements the same method as documented on experimentalsys.Conn
|
||||||
|
func (f *tcpConnFile) Shutdown(how int) experimentalsys.Errno {
|
||||||
|
// FIXME: can userland shutdown listeners?
|
||||||
|
var err error
|
||||||
|
switch how {
|
||||||
|
case socketapi.SHUT_RD:
|
||||||
|
err = f.tc.Close()
|
||||||
|
case socketapi.SHUT_WR:
|
||||||
|
err = f.tc.Close()
|
||||||
|
case socketapi.SHUT_RDWR:
|
||||||
|
return f.close()
|
||||||
|
default:
|
||||||
|
return experimentalsys.EINVAL
|
||||||
|
}
|
||||||
|
return experimentalsys.UnwrapOSError(err)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user