tcpsock_plan9.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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. package net
  5. import (
  6. "io"
  7. "os"
  8. "syscall"
  9. "time"
  10. )
  11. // TCPConn is an implementation of the Conn interface for TCP network
  12. // connections.
  13. type TCPConn struct {
  14. conn
  15. }
  16. func newTCPConn(fd *netFD) *TCPConn {
  17. return &TCPConn{conn{fd}}
  18. }
  19. // ReadFrom implements the io.ReaderFrom ReadFrom method.
  20. func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
  21. return genericReadFrom(c, r)
  22. }
  23. // CloseRead shuts down the reading side of the TCP connection.
  24. // Most callers should just use Close.
  25. func (c *TCPConn) CloseRead() error {
  26. if !c.ok() {
  27. return syscall.EINVAL
  28. }
  29. return c.fd.closeRead()
  30. }
  31. // CloseWrite shuts down the writing side of the TCP connection.
  32. // Most callers should just use Close.
  33. func (c *TCPConn) CloseWrite() error {
  34. if !c.ok() {
  35. return syscall.EINVAL
  36. }
  37. return c.fd.closeWrite()
  38. }
  39. // SetLinger sets the behavior of Close on a connection which still
  40. // has data waiting to be sent or to be acknowledged.
  41. //
  42. // If sec < 0 (the default), the operating system finishes sending the
  43. // data in the background.
  44. //
  45. // If sec == 0, the operating system discards any unsent or
  46. // unacknowledged data.
  47. //
  48. // If sec > 0, the data is sent in the background as with sec < 0. On
  49. // some operating systems after sec seconds have elapsed any remaining
  50. // unsent data may be discarded.
  51. func (c *TCPConn) SetLinger(sec int) error {
  52. return syscall.EPLAN9
  53. }
  54. // SetKeepAlive sets whether the operating system should send
  55. // keepalive messages on the connection.
  56. func (c *TCPConn) SetKeepAlive(keepalive bool) error {
  57. if !c.ok() {
  58. return syscall.EPLAN9
  59. }
  60. return setKeepAlive(c.fd, keepalive)
  61. }
  62. // SetKeepAlivePeriod sets period between keep alives.
  63. func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
  64. if !c.ok() {
  65. return syscall.EPLAN9
  66. }
  67. return setKeepAlivePeriod(c.fd, d)
  68. }
  69. // SetNoDelay controls whether the operating system should delay
  70. // packet transmission in hopes of sending fewer packets (Nagle's
  71. // algorithm). The default is true (no delay), meaning that data is
  72. // sent as soon as possible after a Write.
  73. func (c *TCPConn) SetNoDelay(noDelay bool) error {
  74. return syscall.EPLAN9
  75. }
  76. // DialTCP connects to the remote address raddr on the network net,
  77. // which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is
  78. // used as the local address for the connection.
  79. func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
  80. return dialTCP(net, laddr, raddr, noDeadline)
  81. }
  82. func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, error) {
  83. if !deadline.IsZero() {
  84. panic("net.dialTCP: deadline not implemented on Plan 9")
  85. }
  86. switch net {
  87. case "tcp", "tcp4", "tcp6":
  88. default:
  89. return nil, &OpError{"dial", net, raddr, UnknownNetworkError(net)}
  90. }
  91. if raddr == nil {
  92. return nil, &OpError{"dial", net, nil, errMissingAddress}
  93. }
  94. fd, err := dialPlan9(net, laddr, raddr)
  95. if err != nil {
  96. return nil, err
  97. }
  98. return newTCPConn(fd), nil
  99. }
  100. // TCPListener is a TCP network listener. Clients should typically
  101. // use variables of type Listener instead of assuming TCP.
  102. type TCPListener struct {
  103. fd *netFD
  104. }
  105. // AcceptTCP accepts the next incoming call and returns the new
  106. // connection.
  107. func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
  108. if l == nil || l.fd == nil || l.fd.ctl == nil {
  109. return nil, syscall.EINVAL
  110. }
  111. fd, err := l.fd.acceptPlan9()
  112. if err != nil {
  113. return nil, err
  114. }
  115. return newTCPConn(fd), nil
  116. }
  117. // Accept implements the Accept method in the Listener interface; it
  118. // waits for the next call and returns a generic Conn.
  119. func (l *TCPListener) Accept() (Conn, error) {
  120. if l == nil || l.fd == nil || l.fd.ctl == nil {
  121. return nil, syscall.EINVAL
  122. }
  123. c, err := l.AcceptTCP()
  124. if err != nil {
  125. return nil, err
  126. }
  127. return c, nil
  128. }
  129. // Close stops listening on the TCP address.
  130. // Already Accepted connections are not closed.
  131. func (l *TCPListener) Close() error {
  132. if l == nil || l.fd == nil || l.fd.ctl == nil {
  133. return syscall.EINVAL
  134. }
  135. if _, err := l.fd.ctl.WriteString("hangup"); err != nil {
  136. l.fd.ctl.Close()
  137. return &OpError{"close", l.fd.ctl.Name(), l.fd.laddr, err}
  138. }
  139. return l.fd.ctl.Close()
  140. }
  141. // Addr returns the listener's network address, a *TCPAddr.
  142. func (l *TCPListener) Addr() Addr { return l.fd.laddr }
  143. // SetDeadline sets the deadline associated with the listener.
  144. // A zero time value disables the deadline.
  145. func (l *TCPListener) SetDeadline(t time.Time) error {
  146. if l == nil || l.fd == nil || l.fd.ctl == nil {
  147. return syscall.EINVAL
  148. }
  149. return l.fd.setDeadline(t)
  150. }
  151. // File returns a copy of the underlying os.File, set to blocking
  152. // mode. It is the caller's responsibility to close f when finished.
  153. // Closing l does not affect f, and closing f does not affect l.
  154. //
  155. // The returned os.File's file descriptor is different from the
  156. // connection's. Attempting to change properties of the original
  157. // using this duplicate may or may not have the desired effect.
  158. func (l *TCPListener) File() (f *os.File, err error) { return l.dup() }
  159. // ListenTCP announces on the TCP address laddr and returns a TCP
  160. // listener. Net must be "tcp", "tcp4", or "tcp6". If laddr has a
  161. // port of 0, ListenTCP will choose an available port. The caller can
  162. // use the Addr method of TCPListener to retrieve the chosen address.
  163. func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
  164. switch net {
  165. case "tcp", "tcp4", "tcp6":
  166. default:
  167. return nil, &OpError{"listen", net, laddr, UnknownNetworkError(net)}
  168. }
  169. if laddr == nil {
  170. laddr = &TCPAddr{}
  171. }
  172. fd, err := listenPlan9(net, laddr)
  173. if err != nil {
  174. return nil, err
  175. }
  176. return &TCPListener{fd}, nil
  177. }