blob: 385bd0f7ccd9fc103254cb8a507e5d778e023052 [file] [log] [blame]
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// TODO: move to using fd_unix for fuchsia?
package net
import (
"errors"
"internal/poll"
"os"
"runtime"
"syscall"
"syscall/zx/mxnet"
"syscall/zx/zxsocket"
"time"
)
// Network file descriptor.
type netFD struct {
pfd poll.FD
// immutable until Close
net string
family int
sotype int
isStream bool
isConnected bool
laddr Addr
raddr Addr
}
func newFD(handle *zxsocket.Socket, family, sotype int, net string) *netFD {
netfd := &netFD{
pfd: poll.FD{
Sysfd: syscall.OpenFDIO(handle),
Handle: handle,
},
family: family,
sotype: sotype,
net: net,
}
return netfd
}
func (fd *netFD) destroy() {
panic("TODO")
}
func sysInit() {
}
func (fd *netFD) isTCP() bool {
return len(fd.net) >= 3 && fd.net[:3] == "tcp"
}
func (fd *netFD) Read(b []byte) (n int, err error) {
n, err = fd.pfd.Read(b)
runtime.KeepAlive(fd)
return n, err
}
func (fd *netFD) Write(b []byte) (n int, err error) {
n, err = fd.pfd.Write(b)
runtime.KeepAlive(fd)
return n, err
}
func (fd *netFD) readMsg(b []byte) (n, flags int, addr string, port uint16, err error) {
// TODO: move call to pfd
data, flags, addr, port, err := fd.pfd.Handle.(*zxsocket.Socket).RecvMsg(len(b))
runtime.KeepAlive(fd)
n = copy(b, data)
return n, flags, addr, port, err
}
func (fd *netFD) sendMsg(b []byte, addr string, port uint16) (n int, err error) {
// TODO: move call to pfd
n, err = fd.pfd.Handle.(*zxsocket.Socket).SendMsg(b, addr, port)
runtime.KeepAlive(fd)
return n, err
}
func (fd *netFD) closeRead() error {
return errors.New("net: closeRead not implemented on fuchsia")
}
func (fd *netFD) closeWrite() error {
return errors.New("net: closeWrite not implemented on fuchsia")
}
func (fd *netFD) Close() error {
return fd.pfd.Close()
}
func (fd *netFD) dup() (*os.File, error) {
// TODO(mknyszek): fd.sock is an FDIO so one can make an FD from it to
// implement this.
return nil, errors.New("net: dup not implemented on fuchsia")
}
func (fd *netFD) accept() (netfd *netFD, err error) {
newm, err := fd.pfd.Accept()
if err != nil {
return nil, err
}
netfd = newFD(newm, fd.family, fd.sotype, fd.net)
netfd.setAddr()
return netfd, nil
}
func (fd *netFD) asAddr(ipAddr mxnet.Addr, port uint16, err error) sockaddr {
if err != nil {
return nil
}
ip := IP(ipAddr)
if isZeros(ip) && port == 0 {
return nil
}
switch fd.sotype {
case syscall.SOCK_STREAM:
return &TCPAddr{IP: ip, Port: int(port)}
case syscall.SOCK_DGRAM:
return &UDPAddr{IP: ip, Port: int(port)}
}
return nil
}
func (fd *netFD) setAddr() {
fd.laddr = fd.asAddr(fd.pfd.Handle.(*zxsocket.Socket).SockName())
fd.raddr = fd.asAddr(fd.pfd.Handle.(*zxsocket.Socket).PeerName())
runtime.SetFinalizer(fd, (*netFD).Close)
}
func (fd *netFD) SetDeadline(t time.Time) error {
return fd.pfd.SetDeadline(t)
}
func (fd *netFD) SetReadDeadline(t time.Time) error {
return fd.pfd.SetReadDeadline(t)
}
func (fd *netFD) SetWriteDeadline(t time.Time) error {
return fd.pfd.SetWriteDeadline(t)
}