Skip to content

Commit 3614793

Browse files
committed
feat: add WASI sock_accept support
1 parent 1dcdd5f commit 3614793

File tree

6 files changed

+176
-19
lines changed

6 files changed

+176
-19
lines changed

src/net/error_posix.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// The following is copied and adapted from Go 1.17 official implementation.
2+
3+
// Copyright 2017 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows || wasi
8+
// +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows wasi
9+
10+
package net
11+
12+
import (
13+
"os"
14+
"syscall"
15+
)
16+
17+
// wrapSyscallError takes an error and a syscall name. If the error is
18+
// a syscall.Errno, it wraps it in a os.SyscallError using the syscall name.
19+
func wrapSyscallError(name string, err error) error {
20+
if _, ok := err.(syscall.Errno); ok {
21+
err = os.NewSyscallError(name, err)
22+
}
23+
return err
24+
}

src/net/file.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//go:build wasi
2+
// +build wasi
3+
4+
// The following is copied from Go 1.17 official implementation.
5+
6+
// Copyright 2015 The Go Authors. All rights reserved.
7+
// Use of this source code is governed by a BSD-style
8+
// license that can be found in the LICENSE file.
9+
10+
package net
11+
12+
import (
13+
"os"
14+
)
15+
16+
type fileAddr string
17+
18+
func (fileAddr) Network() string { return "file+net" }
19+
func (f fileAddr) String() string { return string(f) }
20+
21+
// FileListener returns a copy of the network listener corresponding
22+
// to the open file f.
23+
// It is the caller's responsibility to close ln when finished.
24+
// Closing ln does not affect f, and closing f does not affect ln.
25+
func FileListener(f *os.File) (ln Listener, err error) {
26+
ln, err = fileListener(f)
27+
if err != nil {
28+
err = &OpError{Op: "file", Net: "file+net", Source: nil, Addr: fileAddr(f.Name()), Err: err}
29+
}
30+
return
31+
}

src/net/file_wasi.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//go:build wasi
2+
// +build wasi
3+
4+
package net
5+
6+
import (
7+
"io"
8+
"os"
9+
"syscall"
10+
"time"
11+
)
12+
13+
type conn struct {
14+
*os.File
15+
}
16+
17+
// Read implements the Conn Read method.
18+
func (c *conn) Read(b []byte) (int, error) {
19+
n, err := c.File.Read(b)
20+
if err != nil && err != io.EOF {
21+
return 0, &OpError{Op: "read", Net: "file+net", Source: nil, Addr: nil, Err: err}
22+
}
23+
return n, err
24+
}
25+
26+
// Write implements the Conn Write method.
27+
func (c *conn) Write(b []byte) (int, error) {
28+
n, err := c.File.Write(b)
29+
if err != nil {
30+
return 0, &OpError{Op: "write", Net: "file+net", Source: nil, Addr: nil, Err: err}
31+
}
32+
return n, err
33+
}
34+
35+
// LocalAddr implements the Conn LocalAddr method.
36+
func (*conn) LocalAddr() Addr {
37+
return nil
38+
}
39+
40+
// RemoteAddr implements the Conn RemoteAddr method.
41+
func (*conn) RemoteAddr() Addr {
42+
return nil
43+
}
44+
45+
// SetDeadline implements the Conn SetDeadline method.
46+
func (*conn) SetDeadline(t time.Time) error {
47+
return ErrNotImplemented
48+
}
49+
50+
// SetReadDeadline implements the Conn SetReadDeadline method.
51+
func (*conn) SetReadDeadline(t time.Time) error {
52+
return ErrNotImplemented
53+
}
54+
55+
// SetWriteDeadline implements the Conn SetWriteDeadline method.
56+
func (*conn) SetWriteDeadline(t time.Time) error {
57+
return ErrNotImplemented
58+
}
59+
60+
type listener struct {
61+
*os.File
62+
}
63+
64+
// Accept implements the Listener Accept method.
65+
func (l *listener) Accept() (Conn, error) {
66+
fd, err := syscall.SockAccept(int(l.File.Fd()), 0)
67+
if err != nil {
68+
return nil, wrapSyscallError("sock_accept", err)
69+
}
70+
return &conn{File: os.NewFile(uintptr(fd), "conn")}, nil
71+
}
72+
73+
// Addr implements the Listener Addr method.
74+
func (*listener) Addr() Addr {
75+
return nil
76+
}
77+
78+
func fileListener(f *os.File) (Listener, error) {
79+
return &listener{File: f}, nil
80+
}

src/net/net.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,6 @@ type Conn interface {
8181
SetWriteDeadline(t time.Time) error
8282
}
8383

84-
type conn struct {
85-
//
86-
}
87-
8884
// A Listener is a generic network listener for stream-oriented protocols.
8985
//
9086
// Multiple goroutines may invoke methods on a Listener simultaneously.

src/net/tcpsock.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ package net
22

33
// TCPConn is an implementation of the Conn interface for TCP network
44
// connections.
5-
type TCPConn struct {
6-
conn
7-
}
5+
type TCPConn struct{}
86

97
func (c *TCPConn) CloseWrite() error {
108
return &OpError{"close", "", nil, nil, ErrNotImplemented}

src/syscall/syscall_libc_wasi.go

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
package syscall
55

66
import (
7-
"internal/itoa"
87
"unsafe"
8+
9+
"internal/itoa"
910
)
1011

1112
// https://github.com/WebAssembly/wasi-libc/blob/main/expected/wasm32-wasi/predefined-macros.txt
@@ -50,21 +51,29 @@ const (
5051
)
5152

5253
const (
53-
__WASI_OFLAGS_CREAT = 1
54-
__WASI_FDFLAGS_APPEND = 1
55-
__WASI_OFLAGS_EXCL = 4
56-
__WASI_OFLAGS_TRUNC = 8
57-
__WASI_FDFLAGS_SYNC = 16
54+
__WASI_OFLAGS_CREAT = 1
55+
__WASI_OFLAGS_EXCL = 4
56+
__WASI_OFLAGS_TRUNC = 8
57+
58+
__WASI_FDFLAGS_APPEND = 1
59+
__WASI_FDFLAGS_DSYNC = 2
60+
__WASI_FDFLAGS_NONBLOCK = 4
61+
__WASI_FDFLAGS_RSYNC = 8
62+
__WASI_FDFLAGS_SYNC = 16
5863

5964
O_RDONLY = 0x04000000
6065
O_WRONLY = 0x10000000
6166
O_RDWR = O_RDONLY | O_WRONLY
6267

63-
O_CREAT = __WASI_OFLAGS_CREAT << 12
64-
O_TRUNC = __WASI_OFLAGS_TRUNC << 12
65-
O_APPEND = __WASI_FDFLAGS_APPEND
66-
O_EXCL = __WASI_OFLAGS_EXCL << 12
67-
O_SYNC = __WASI_FDFLAGS_SYNC
68+
O_CREAT = __WASI_OFLAGS_CREAT << 12
69+
O_TRUNC = __WASI_OFLAGS_TRUNC << 12
70+
O_EXCL = __WASI_OFLAGS_EXCL << 12
71+
72+
O_APPEND = __WASI_FDFLAGS_APPEND
73+
O_DSYNC = __WASI_FDFLAGS_DSYNC
74+
O_NONBLOCK = __WASI_FDFLAGS_NONBLOCK
75+
O_RSYNC = __WASI_FDFLAGS_RSYNC
76+
O_SYNC = __WASI_FDFLAGS_SYNC
6877

6978
O_CLOEXEC = 0
7079

@@ -292,14 +301,33 @@ func Lstat(path string, p *Stat_t) (err error) {
292301
return
293302
}
294303

304+
func SockAccept(fd int, flags int) (nfd int, err error) {
305+
var retptr0 __wasi_fd_t
306+
if n := sock_accept(__wasi_fd_t(fd), __wasi_fdflags_t(flags), &retptr0); n < 0 {
307+
return -1, Errno(n)
308+
}
309+
return int(retptr0), nil
310+
}
311+
295312
// int stat(const char *path, struct stat * buf);
296313
//export stat
297314
func libc_stat(pathname *byte, ptr unsafe.Pointer) int32
298315

299-
// int fstat(fd int, struct stat * buf);
316+
// int fstat(int fd, struct stat * buf);
300317
//export fstat
301318
func libc_fstat(fd int32, ptr unsafe.Pointer) int32
302319

303320
// int lstat(const char *path, struct stat * buf);
304321
//export lstat
305322
func libc_lstat(pathname *byte, ptr unsafe.Pointer) int32
323+
324+
type (
325+
__wasi_errno_t = uint16
326+
327+
__wasi_fd_t = int32
328+
__wasi_fdflags_t = uint16
329+
)
330+
331+
//go:wasm-module wasi_snapshot_preview1
332+
//export sock_accept
333+
func sock_accept(fd __wasi_fd_t, flags __wasi_fdflags_t, retptr0 *__wasi_fd_t) __wasi_errno_t

0 commit comments

Comments
 (0)