1// Copyright 2023 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build wasip1
6
7package net
8
9import (
10	"os"
11	"syscall"
12	_ "unsafe" // for go:linkname
13)
14
15func fileListener(f *os.File) (Listener, error) {
16	filetype, err := fd_fdstat_get_type(f.PollFD().Sysfd)
17	if err != nil {
18		return nil, err
19	}
20	net, err := fileListenNet(filetype)
21	if err != nil {
22		return nil, err
23	}
24	pfd := f.PollFD().Copy()
25	fd := newPollFD(net, pfd)
26	if err := fd.init(); err != nil {
27		pfd.Close()
28		return nil, err
29	}
30	return newFileListener(fd), nil
31}
32
33func fileConn(f *os.File) (Conn, error) {
34	filetype, err := fd_fdstat_get_type(f.PollFD().Sysfd)
35	if err != nil {
36		return nil, err
37	}
38	net, err := fileConnNet(filetype)
39	if err != nil {
40		return nil, err
41	}
42	pfd := f.PollFD().Copy()
43	fd := newPollFD(net, pfd)
44	if err := fd.init(); err != nil {
45		pfd.Close()
46		return nil, err
47	}
48	return newFileConn(fd), nil
49}
50
51func filePacketConn(f *os.File) (PacketConn, error) {
52	return nil, syscall.ENOPROTOOPT
53}
54
55func fileListenNet(filetype syscall.Filetype) (string, error) {
56	switch filetype {
57	case syscall.FILETYPE_SOCKET_STREAM:
58		return "tcp", nil
59	case syscall.FILETYPE_SOCKET_DGRAM:
60		return "", syscall.EOPNOTSUPP
61	default:
62		return "", syscall.ENOTSOCK
63	}
64}
65
66func fileConnNet(filetype syscall.Filetype) (string, error) {
67	switch filetype {
68	case syscall.FILETYPE_SOCKET_STREAM:
69		return "tcp", nil
70	case syscall.FILETYPE_SOCKET_DGRAM:
71		return "udp", nil
72	default:
73		return "", syscall.ENOTSOCK
74	}
75}
76
77func newFileListener(fd *netFD) Listener {
78	switch fd.net {
79	case "tcp":
80		return &TCPListener{fd: fd}
81	default:
82		panic("unsupported network for file listener: " + fd.net)
83	}
84}
85
86func newFileConn(fd *netFD) Conn {
87	switch fd.net {
88	case "tcp":
89		return &TCPConn{conn{fd: fd}}
90	case "udp":
91		return &UDPConn{conn{fd: fd}}
92	default:
93		panic("unsupported network for file connection: " + fd.net)
94	}
95}
96
97// This helper is implemented in the syscall package. It means we don't have
98// to redefine the fd_fdstat_get host import or the fdstat struct it
99// populates.
100//
101//go:linkname fd_fdstat_get_type syscall.fd_fdstat_get_type
102func fd_fdstat_get_type(fd int) (uint8, error)
103