tcpsock_plan9.mx raw

   1  // Copyright 2009 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  	"context"
   9  	"io"
  10  	"os"
  11  )
  12  
  13  func (c *TCPConn) readFrom(r io.Reader) (int64, error) {
  14  	return genericReadFrom(c, r)
  15  }
  16  
  17  func (c *TCPConn) writeTo(w io.Writer) (int64, error) {
  18  	return genericWriteTo(c, w)
  19  }
  20  
  21  func (sd *sysDialer) dialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
  22  	if h := sd.testHookDialTCP; h != nil {
  23  		return h(ctx, sd.network, laddr, raddr)
  24  	}
  25  	if h := testHookDialTCP; h != nil {
  26  		return h(ctx, sd.network, laddr, raddr)
  27  	}
  28  	return sd.doDialTCP(ctx, laddr, raddr)
  29  }
  30  
  31  func (sd *sysDialer) doDialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
  32  	switch sd.network {
  33  	case "tcp4":
  34  		// Plan 9 doesn't complain about [::]:0->127.0.0.1, so it's up to us.
  35  		if laddr != nil && len(laddr.IP) != 0 && laddr.IP.To4() == nil {
  36  			return nil, &AddrError{Err: "non-IPv4 local address", Addr: laddr.String()}
  37  		}
  38  	case "tcp", "tcp6":
  39  	default:
  40  		return nil, UnknownNetworkError(sd.network)
  41  	}
  42  	if raddr == nil {
  43  		return nil, errMissingAddress
  44  	}
  45  	fd, err := dialPlan9(ctx, sd.network, laddr, raddr)
  46  	if err != nil {
  47  		return nil, err
  48  	}
  49  	return newTCPConn(fd, sd.Dialer.KeepAlive, sd.Dialer.KeepAliveConfig, testPreHookSetKeepAlive, testHookSetKeepAlive), nil
  50  }
  51  
  52  func (ln *TCPListener) ok() bool { return ln != nil && ln.fd != nil && ln.fd.ctl != nil }
  53  
  54  func (ln *TCPListener) accept() (*TCPConn, error) {
  55  	fd, err := ln.fd.acceptPlan9()
  56  	if err != nil {
  57  		return nil, err
  58  	}
  59  	return newTCPConn(fd, ln.lc.KeepAlive, ln.lc.KeepAliveConfig, testPreHookSetKeepAlive, testHookSetKeepAlive), nil
  60  }
  61  
  62  func (ln *TCPListener) close() error {
  63  	if err := ln.fd.pfd.Close(); err != nil {
  64  		return err
  65  	}
  66  	if _, err := ln.fd.ctl.WriteString("hangup"); err != nil {
  67  		ln.fd.ctl.Close()
  68  		return err
  69  	}
  70  	if err := ln.fd.ctl.Close(); err != nil {
  71  		return err
  72  	}
  73  	return nil
  74  }
  75  
  76  func (ln *TCPListener) file() (*os.File, error) {
  77  	f, err := ln.dup()
  78  	if err != nil {
  79  		return nil, err
  80  	}
  81  	return f, nil
  82  }
  83  
  84  func (sl *sysListener) listenTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) {
  85  	fd, err := listenPlan9(ctx, sl.network, laddr)
  86  	if err != nil {
  87  		return nil, err
  88  	}
  89  	return &TCPListener{fd: fd, lc: sl.ListenConfig}, nil
  90  }
  91