Source file src/net/rawconn.go

     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  

View as plain text