github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/net/tcpsock_plan9.go (about) 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 (sd *sysDialer) dialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) { 18 if testHookDialTCP != nil { 19 return testHookDialTCP(ctx, sd.network, laddr, raddr) 20 } 21 return sd.doDialTCP(ctx, laddr, raddr) 22 } 23 24 func (sd *sysDialer) doDialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) { 25 switch sd.network { 26 case "tcp4": 27 // Plan 9 doesn't complain about [::]:0->127.0.0.1, so it's up to us. 28 if laddr != nil && len(laddr.IP) != 0 && laddr.IP.To4() == nil { 29 return nil, &AddrError{Err: "non-IPv4 local address", Addr: laddr.String()} 30 } 31 case "tcp", "tcp6": 32 default: 33 return nil, UnknownNetworkError(sd.network) 34 } 35 if raddr == nil { 36 return nil, errMissingAddress 37 } 38 fd, err := dialPlan9(ctx, sd.network, laddr, raddr) 39 if err != nil { 40 return nil, err 41 } 42 return newTCPConn(fd), nil 43 } 44 45 func (ln *TCPListener) ok() bool { return ln != nil && ln.fd != nil && ln.fd.ctl != nil } 46 47 func (ln *TCPListener) accept() (*TCPConn, error) { 48 fd, err := ln.fd.acceptPlan9() 49 if err != nil { 50 return nil, err 51 } 52 tc := newTCPConn(fd) 53 if ln.lc.KeepAlive >= 0 { 54 setKeepAlive(fd, true) 55 ka := ln.lc.KeepAlive 56 if ln.lc.KeepAlive == 0 { 57 ka = defaultTCPKeepAlive 58 } 59 setKeepAlivePeriod(fd, ka) 60 } 61 return tc, nil 62 } 63 64 func (ln *TCPListener) close() error { 65 if err := ln.fd.pfd.Close(); err != nil { 66 return err 67 } 68 if _, err := ln.fd.ctl.WriteString("hangup"); err != nil { 69 ln.fd.ctl.Close() 70 return err 71 } 72 if err := ln.fd.ctl.Close(); err != nil { 73 return err 74 } 75 return nil 76 } 77 78 func (ln *TCPListener) file() (*os.File, error) { 79 f, err := ln.dup() 80 if err != nil { 81 return nil, err 82 } 83 return f, nil 84 } 85 86 func (sl *sysListener) listenTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) { 87 fd, err := listenPlan9(ctx, sl.network, laddr) 88 if err != nil { 89 return nil, err 90 } 91 return &TCPListener{fd: fd, lc: sl.ListenConfig}, nil 92 }