github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/internal/socket/rawconn_msg.go (about)

     1  // Copyright 2017 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  // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
     6  
     7  package socket
     8  
     9  import (
    10  	"os"
    11  	"syscall"
    12  )
    13  
    14  func (c *Conn) recvMsg(m *Message, flags int) error {
    15  	var h msghdr
    16  	vs := make([]iovec, len(m.Buffers))
    17  	var sa []byte
    18  	if c.network != "tcp" {
    19  		sa = make([]byte, sizeofSockaddrInet6)
    20  	}
    21  	h.pack(vs, m.Buffers, m.OOB, sa)
    22  	var operr error
    23  	var n int
    24  	fn := func(s uintptr) bool {
    25  		n, operr = recvmsg(s, &h, flags)
    26  		if operr == syscall.EAGAIN {
    27  			return false
    28  		}
    29  		return true
    30  	}
    31  	if err := c.c.Read(fn); err != nil {
    32  		return err
    33  	}
    34  	if operr != nil {
    35  		return os.NewSyscallError("recvmsg", operr)
    36  	}
    37  	if c.network != "tcp" {
    38  		var err error
    39  		m.Addr, err = parseInetAddr(sa[:], c.network)
    40  		if err != nil {
    41  			return err
    42  		}
    43  	}
    44  	m.N = n
    45  	m.NN = h.controllen()
    46  	m.Flags = h.flags()
    47  	return nil
    48  }
    49  
    50  func (c *Conn) sendMsg(m *Message, flags int) error {
    51  	var h msghdr
    52  	vs := make([]iovec, len(m.Buffers))
    53  	var sa []byte
    54  	if m.Addr != nil {
    55  		sa = marshalInetAddr(m.Addr)
    56  	}
    57  	h.pack(vs, m.Buffers, m.OOB, sa)
    58  	var operr error
    59  	var n int
    60  	fn := func(s uintptr) bool {
    61  		n, operr = sendmsg(s, &h, flags)
    62  		if operr == syscall.EAGAIN {
    63  			return false
    64  		}
    65  		return true
    66  	}
    67  	if err := c.c.Write(fn); err != nil {
    68  		return err
    69  	}
    70  	if operr != nil {
    71  		return os.NewSyscallError("sendmsg", operr)
    72  	}
    73  	m.N = n
    74  	m.NN = len(m.OOB)
    75  	return nil
    76  }