rawconn.mx raw

   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  package net
   6  
   7  import (
   8  	"internal/poll"
   9  	"runtime"
  10  	"syscall"
  11  )
  12  
  13  // BUG(tmm1): On Windows, the Write method of syscall.RawConn
  14  // does not integrate with the runtime's network poller. It cannot
  15  // wait for the connection to become writeable, and does not respect
  16  // deadlines. If the user-provided callback returns false, the Write
  17  // method will fail immediately.
  18  
  19  // BUG(mikio): On JS and Plan 9, the Control, Read and Write
  20  // methods of syscall.RawConn are not implemented.
  21  
  22  type rawConn struct {
  23  	fd *netFD
  24  }
  25  
  26  func (c *rawConn) ok() bool { return c != nil && c.fd != nil }
  27  
  28  func (c *rawConn) Control(f func(uintptr)) error {
  29  	if !c.ok() {
  30  		return syscall.EINVAL
  31  	}
  32  	err := c.fd.pfd.RawControl(f)
  33  	runtime.KeepAlive(c.fd)
  34  	if err != nil {
  35  		err = &OpError{Op: "raw-control", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
  36  	}
  37  	return err
  38  }
  39  
  40  func (c *rawConn) Read(f func(uintptr) bool) error {
  41  	if !c.ok() {
  42  		return syscall.EINVAL
  43  	}
  44  	err := c.fd.pfd.RawRead(f)
  45  	runtime.KeepAlive(c.fd)
  46  	if err != nil {
  47  		err = &OpError{Op: "raw-read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
  48  	}
  49  	return err
  50  }
  51  
  52  func (c *rawConn) Write(f func(uintptr) bool) error {
  53  	if !c.ok() {
  54  		return syscall.EINVAL
  55  	}
  56  	err := c.fd.pfd.RawWrite(f)
  57  	runtime.KeepAlive(c.fd)
  58  	if err != nil {
  59  		err = &OpError{Op: "raw-write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
  60  	}
  61  	return err
  62  }
  63  
  64  // PollFD returns the poll.FD of the underlying connection.
  65  //
  66  // Other packages in std that also import [internal/poll] (such as os)
  67  // can use a type assertion to access this extension method so that
  68  // they can pass the *poll.FD to functions like poll.Splice.
  69  //
  70  // PollFD is not intended for use outside the standard library.
  71  func (c *rawConn) PollFD() *poll.FD {
  72  	if !c.ok() {
  73  		return nil
  74  	}
  75  	return &c.fd.pfd
  76  }
  77  
  78  func newRawConn(fd *netFD) *rawConn {
  79  	return &rawConn{fd: fd}
  80  }
  81  
  82  // Network returns the network type of the underlying connection.
  83  //
  84  // Other packages in std that import internal/poll and are unable to
  85  // import net (such as os) can use a type assertion to access this
  86  // extension method so that they can distinguish different socket types.
  87  //
  88  // Network is not intended for use outside the standard library.
  89  func (c *rawConn) Network() poll.String {
  90  	return poll.String(c.fd.net)
  91  }
  92  
  93  type rawListener struct {
  94  	rawConn
  95  }
  96  
  97  func (l *rawListener) Read(func(uintptr) bool) error {
  98  	return syscall.EINVAL
  99  }
 100  
 101  func (l *rawListener) Write(func(uintptr) bool) error {
 102  	return syscall.EINVAL
 103  }
 104  
 105  func newRawListener(fd *netFD) *rawListener {
 106  	return &rawListener{rawConn{fd: fd}}
 107  }
 108