...
Run Format

Source file src/net/net.go

Documentation: net

     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  /*
     6  Package net provides a portable interface for network I/O, including
     7  TCP/IP, UDP, domain name resolution, and Unix domain sockets.
     8  
     9  Although the package provides access to low-level networking
    10  primitives, most clients will need only the basic interface provided
    11  by the Dial, Listen, and Accept functions and the associated
    12  Conn and Listener interfaces. The crypto/tls package uses
    13  the same interfaces and similar Dial and Listen functions.
    14  
    15  The Dial function connects to a server:
    16  
    17  	conn, err := net.Dial("tcp", "golang.org:80")
    18  	if err != nil {
    19  		// handle error
    20  	}
    21  	fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
    22  	status, err := bufio.NewReader(conn).ReadString('\n')
    23  	// ...
    24  
    25  The Listen function creates servers:
    26  
    27  	ln, err := net.Listen("tcp", ":8080")
    28  	if err != nil {
    29  		// handle error
    30  	}
    31  	for {
    32  		conn, err := ln.Accept()
    33  		if err != nil {
    34  			// handle error
    35  		}
    36  		go handleConnection(conn)
    37  	}
    38  
    39  Name Resolution
    40  
    41  The method for resolving domain names, whether indirectly with functions like Dial
    42  or directly with functions like LookupHost and LookupAddr, varies by operating system.
    43  
    44  On Unix systems, the resolver has two options for resolving names.
    45  It can use a pure Go resolver that sends DNS requests directly to the servers
    46  listed in /etc/resolv.conf, or it can use a cgo-based resolver that calls C
    47  library routines such as getaddrinfo and getnameinfo.
    48  
    49  By default the pure Go resolver is used, because a blocked DNS request consumes
    50  only a goroutine, while a blocked C call consumes an operating system thread.
    51  When cgo is available, the cgo-based resolver is used instead under a variety of
    52  conditions: on systems that do not let programs make direct DNS requests (OS X),
    53  when the LOCALDOMAIN environment variable is present (even if empty),
    54  when the RES_OPTIONS or HOSTALIASES environment variable is non-empty,
    55  when the ASR_CONFIG environment variable is non-empty (OpenBSD only),
    56  when /etc/resolv.conf or /etc/nsswitch.conf specify the use of features that the
    57  Go resolver does not implement, and when the name being looked up ends in .local
    58  or is an mDNS name.
    59  
    60  The resolver decision can be overridden by setting the netdns value of the
    61  GODEBUG environment variable (see package runtime) to go or cgo, as in:
    62  
    63  	export GODEBUG=netdns=go    # force pure Go resolver
    64  	export GODEBUG=netdns=cgo   # force cgo resolver
    65  
    66  The decision can also be forced while building the Go source tree
    67  by setting the netgo or netcgo build tag.
    68  
    69  A numeric netdns setting, as in GODEBUG=netdns=1, causes the resolver
    70  to print debugging information about its decisions.
    71  To force a particular resolver while also printing debugging information,
    72  join the two settings by a plus sign, as in GODEBUG=netdns=go+1.
    73  
    74  On Plan 9, the resolver always accesses /net/cs and /net/dns.
    75  
    76  On Windows, the resolver always uses C library functions, such as GetAddrInfo and DnsQuery.
    77  
    78  */
    79  package net
    80  
    81  import (
    82  	"context"
    83  	"errors"
    84  	"internal/poll"
    85  	"io"
    86  	"os"
    87  	"syscall"
    88  	"time"
    89  )
    90  
    91  // netGo and netCgo contain the state of the build tags used
    92  // to build this binary, and whether cgo is available.
    93  // conf.go mirrors these into conf for easier testing.
    94  var (
    95  	netGo  bool // set true in cgo_stub.go for build tag "netgo" (or no cgo)
    96  	netCgo bool // set true in conf_netcgo.go for build tag "netcgo"
    97  )
    98  
    99  // Addr represents a network end point address.
   100  //
   101  // The two methods Network and String conventionally return strings
   102  // that can be passed as the arguments to Dial, but the exact form
   103  // and meaning of the strings is up to the implementation.
   104  type Addr interface {
   105  	Network() string // name of the network (for example, "tcp", "udp")
   106  	String() string  // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80")
   107  }
   108  
   109  // Conn is a generic stream-oriented network connection.
   110  //
   111  // Multiple goroutines may invoke methods on a Conn simultaneously.
   112  type Conn interface {
   113  	// Read reads data from the connection.
   114  	// Read can be made to time out and return an Error with Timeout() == true
   115  	// after a fixed time limit; see SetDeadline and SetReadDeadline.
   116  	Read(b []byte) (n int, err error)
   117  
   118  	// Write writes data to the connection.
   119  	// Write can be made to time out and return an Error with Timeout() == true
   120  	// after a fixed time limit; see SetDeadline and SetWriteDeadline.
   121  	Write(b []byte) (n int, err error)
   122  
   123  	// Close closes the connection.
   124  	// Any blocked Read or Write operations will be unblocked and return errors.
   125  	Close() error
   126  
   127  	// LocalAddr returns the local network address.
   128  	LocalAddr() Addr
   129  
   130  	// RemoteAddr returns the remote network address.
   131  	RemoteAddr() Addr
   132  
   133  	// SetDeadline sets the read and write deadlines associated
   134  	// with the connection. It is equivalent to calling both
   135  	// SetReadDeadline and SetWriteDeadline.
   136  	//
   137  	// A deadline is an absolute time after which I/O operations
   138  	// fail with a timeout (see type Error) instead of
   139  	// blocking. The deadline applies to all future and pending
   140  	// I/O, not just the immediately following call to Read or
   141  	// Write. After a deadline has been exceeded, the connection
   142  	// can be refreshed by setting a deadline in the future.
   143  	//
   144  	// An idle timeout can be implemented by repeatedly extending
   145  	// the deadline after successful Read or Write calls.
   146  	//
   147  	// A zero value for t means I/O operations will not time out.
   148  	SetDeadline(t time.Time) error
   149  
   150  	// SetReadDeadline sets the deadline for future Read calls
   151  	// and any currently-blocked Read call.
   152  	// A zero value for t means Read will not time out.
   153  	SetReadDeadline(t time.Time) error
   154  
   155  	// SetWriteDeadline sets the deadline for future Write calls
   156  	// and any currently-blocked Write call.
   157  	// Even if write times out, it may return n > 0, indicating that
   158  	// some of the data was successfully written.
   159  	// A zero value for t means Write will not time out.
   160  	SetWriteDeadline(t time.Time) error
   161  }
   162  
   163  type conn struct {
   164  	fd *netFD
   165  }
   166  
   167  func (c *conn) ok() bool { return c != nil && c.fd != nil }
   168  
   169  // Implementation of the Conn interface.
   170  
   171  // Read implements the Conn Read method.
   172  func (c *conn) Read(b []byte) (int, error) {
   173  	if !c.ok() {
   174  		return 0, syscall.EINVAL
   175  	}
   176  	n, err := c.fd.Read(b)
   177  	if err != nil && err != io.EOF {
   178  		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   179  	}
   180  	return n, err
   181  }
   182  
   183  // Write implements the Conn Write method.
   184  func (c *conn) Write(b []byte) (int, error) {
   185  	if !c.ok() {
   186  		return 0, syscall.EINVAL
   187  	}
   188  	n, err := c.fd.Write(b)
   189  	if err != nil {
   190  		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   191  	}
   192  	return n, err
   193  }
   194  
   195  // Close closes the connection.
   196  func (c *conn) Close() error {
   197  	if !c.ok() {
   198  		return syscall.EINVAL
   199  	}
   200  	err := c.fd.Close()
   201  	if err != nil {
   202  		err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   203  	}
   204  	return err
   205  }
   206  
   207  // LocalAddr returns the local network address.
   208  // The Addr returned is shared by all invocations of LocalAddr, so
   209  // do not modify it.
   210  func (c *conn) LocalAddr() Addr {
   211  	if !c.ok() {
   212  		return nil
   213  	}
   214  	return c.fd.laddr
   215  }
   216  
   217  // RemoteAddr returns the remote network address.
   218  // The Addr returned is shared by all invocations of RemoteAddr, so
   219  // do not modify it.
   220  func (c *conn) RemoteAddr() Addr {
   221  	if !c.ok() {
   222  		return nil
   223  	}
   224  	return c.fd.raddr
   225  }
   226  
   227  // SetDeadline implements the Conn SetDeadline method.
   228  func (c *conn) SetDeadline(t time.Time) error {
   229  	if !c.ok() {
   230  		return syscall.EINVAL
   231  	}
   232  	if err := c.fd.pfd.SetDeadline(t); err != nil {
   233  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   234  	}
   235  	return nil
   236  }
   237  
   238  // SetReadDeadline implements the Conn SetReadDeadline method.
   239  func (c *conn) SetReadDeadline(t time.Time) error {
   240  	if !c.ok() {
   241  		return syscall.EINVAL
   242  	}
   243  	if err := c.fd.pfd.SetReadDeadline(t); err != nil {
   244  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   245  	}
   246  	return nil
   247  }
   248  
   249  // SetWriteDeadline implements the Conn SetWriteDeadline method.
   250  func (c *conn) SetWriteDeadline(t time.Time) error {
   251  	if !c.ok() {
   252  		return syscall.EINVAL
   253  	}
   254  	if err := c.fd.pfd.SetWriteDeadline(t); err != nil {
   255  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   256  	}
   257  	return nil
   258  }
   259  
   260  // SetReadBuffer sets the size of the operating system's
   261  // receive buffer associated with the connection.
   262  func (c *conn) SetReadBuffer(bytes int) error {
   263  	if !c.ok() {
   264  		return syscall.EINVAL
   265  	}
   266  	if err := setReadBuffer(c.fd, bytes); err != nil {
   267  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   268  	}
   269  	return nil
   270  }
   271  
   272  // SetWriteBuffer sets the size of the operating system's
   273  // transmit buffer associated with the connection.
   274  func (c *conn) SetWriteBuffer(bytes int) error {
   275  	if !c.ok() {
   276  		return syscall.EINVAL
   277  	}
   278  	if err := setWriteBuffer(c.fd, bytes); err != nil {
   279  		return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
   280  	}
   281  	return nil
   282  }
   283  
   284  // File sets the underlying os.File to blocking mode and returns a copy.
   285  // It is the caller's responsibility to close f when finished.
   286  // Closing c does not affect f, and closing f does not affect c.
   287  //
   288  // The returned os.File's file descriptor is different from the connection's.
   289  // Attempting to change properties of the original using this duplicate
   290  // may or may not have the desired effect.
   291  //
   292  // On Unix systems this will cause the SetDeadline methods to stop working.
   293  func (c *conn) File() (f *os.File, err error) {
   294  	f, err = c.fd.dup()
   295  	if err != nil {
   296  		err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
   297  	}
   298  	return
   299  }
   300  
   301  // PacketConn is a generic packet-oriented network connection.
   302  //
   303  // Multiple goroutines may invoke methods on a PacketConn simultaneously.
   304  type PacketConn interface {
   305  	// ReadFrom reads a packet from the connection,
   306  	// copying the payload into b. It returns the number of
   307  	// bytes copied into b and the return address that
   308  	// was on the packet.
   309  	// ReadFrom can be made to time out and return
   310  	// an Error with Timeout() == true after a fixed time limit;
   311  	// see SetDeadline and SetReadDeadline.
   312  	ReadFrom(b []byte) (n int, addr Addr, err error)
   313  
   314  	// WriteTo writes a packet with payload b to addr.
   315  	// WriteTo can be made to time out and return
   316  	// an Error with Timeout() == true after a fixed time limit;
   317  	// see SetDeadline and SetWriteDeadline.
   318  	// On packet-oriented connections, write timeouts are rare.
   319  	WriteTo(b []byte, addr Addr) (n int, err error)
   320  
   321  	// Close closes the connection.
   322  	// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
   323  	Close() error
   324  
   325  	// LocalAddr returns the local network address.
   326  	LocalAddr() Addr
   327  
   328  	// SetDeadline sets the read and write deadlines associated
   329  	// with the connection. It is equivalent to calling both
   330  	// SetReadDeadline and SetWriteDeadline.
   331  	//
   332  	// A deadline is an absolute time after which I/O operations
   333  	// fail with a timeout (see type Error) instead of
   334  	// blocking. The deadline applies to all future and pending
   335  	// I/O, not just the immediately following call to ReadFrom or
   336  	// WriteTo. After a deadline has been exceeded, the connection
   337  	// can be refreshed by setting a deadline in the future.
   338  	//
   339  	// An idle timeout can be implemented by repeatedly extending
   340  	// the deadline after successful ReadFrom or WriteTo calls.
   341  	//
   342  	// A zero value for t means I/O operations will not time out.
   343  	SetDeadline(t time.Time) error
   344  
   345  	// SetReadDeadline sets the deadline for future ReadFrom calls
   346  	// and any currently-blocked ReadFrom call.
   347  	// A zero value for t means ReadFrom will not time out.
   348  	SetReadDeadline(t time.Time) error
   349  
   350  	// SetWriteDeadline sets the deadline for future WriteTo calls
   351  	// and any currently-blocked WriteTo call.
   352  	// Even if write times out, it may return n > 0, indicating that
   353  	// some of the data was successfully written.
   354  	// A zero value for t means WriteTo will not time out.
   355  	SetWriteDeadline(t time.Time) error
   356  }
   357  
   358  var listenerBacklog = maxListenerBacklog()
   359  
   360  // A Listener is a generic network listener for stream-oriented protocols.
   361  //
   362  // Multiple goroutines may invoke methods on a Listener simultaneously.
   363  type Listener interface {
   364  	// Accept waits for and returns the next connection to the listener.
   365  	Accept() (Conn, error)
   366  
   367  	// Close closes the listener.
   368  	// Any blocked Accept operations will be unblocked and return errors.
   369  	Close() error
   370  
   371  	// Addr returns the listener's network address.
   372  	Addr() Addr
   373  }
   374  
   375  // An Error represents a network error.
   376  type Error interface {
   377  	error
   378  	Timeout() bool   // Is the error a timeout?
   379  	Temporary() bool // Is the error temporary?
   380  }
   381  
   382  // Various errors contained in OpError.
   383  var (
   384  	// For connection setup operations.
   385  	errNoSuitableAddress = errors.New("no suitable address found")
   386  
   387  	// For connection setup and write operations.
   388  	errMissingAddress = errors.New("missing address")
   389  
   390  	// For both read and write operations.
   391  	errCanceled         = errors.New("operation was canceled")
   392  	ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection")
   393  )
   394  
   395  // mapErr maps from the context errors to the historical internal net
   396  // error values.
   397  //
   398  // TODO(bradfitz): get rid of this after adjusting tests and making
   399  // context.DeadlineExceeded implement net.Error?
   400  func mapErr(err error) error {
   401  	switch err {
   402  	case context.Canceled:
   403  		return errCanceled
   404  	case context.DeadlineExceeded:
   405  		return poll.ErrTimeout
   406  	default:
   407  		return err
   408  	}
   409  }
   410  
   411  // OpError is the error type usually returned by functions in the net
   412  // package. It describes the operation, network type, and address of
   413  // an error.
   414  type OpError struct {
   415  	// Op is the operation which caused the error, such as
   416  	// "read" or "write".
   417  	Op string
   418  
   419  	// Net is the network type on which this error occurred,
   420  	// such as "tcp" or "udp6".
   421  	Net string
   422  
   423  	// For operations involving a remote network connection, like
   424  	// Dial, Read, or Write, Source is the corresponding local
   425  	// network address.
   426  	Source Addr
   427  
   428  	// Addr is the network address for which this error occurred.
   429  	// For local operations, like Listen or SetDeadline, Addr is
   430  	// the address of the local endpoint being manipulated.
   431  	// For operations involving a remote network connection, like
   432  	// Dial, Read, or Write, Addr is the remote address of that
   433  	// connection.
   434  	Addr Addr
   435  
   436  	// Err is the error that occurred during the operation.
   437  	Err error
   438  }
   439  
   440  func (e *OpError) Error() string {
   441  	if e == nil {
   442  		return "<nil>"
   443  	}
   444  	s := e.Op
   445  	if e.Net != "" {
   446  		s += " " + e.Net
   447  	}
   448  	if e.Source != nil {
   449  		s += " " + e.Source.String()
   450  	}
   451  	if e.Addr != nil {
   452  		if e.Source != nil {
   453  			s += "->"
   454  		} else {
   455  			s += " "
   456  		}
   457  		s += e.Addr.String()
   458  	}
   459  	s += ": " + e.Err.Error()
   460  	return s
   461  }
   462  
   463  var (
   464  	// aLongTimeAgo is a non-zero time, far in the past, used for
   465  	// immediate cancelation of dials.
   466  	aLongTimeAgo = time.Unix(1, 0)
   467  
   468  	// nonDeadline and noCancel are just zero values for
   469  	// readability with functions taking too many parameters.
   470  	noDeadline = time.Time{}
   471  	noCancel   = (chan struct{})(nil)
   472  )
   473  
   474  type timeout interface {
   475  	Timeout() bool
   476  }
   477  
   478  func (e *OpError) Timeout() bool {
   479  	if ne, ok := e.Err.(*os.SyscallError); ok {
   480  		t, ok := ne.Err.(timeout)
   481  		return ok && t.Timeout()
   482  	}
   483  	t, ok := e.Err.(timeout)
   484  	return ok && t.Timeout()
   485  }
   486  
   487  type temporary interface {
   488  	Temporary() bool
   489  }
   490  
   491  func (e *OpError) Temporary() bool {
   492  	if ne, ok := e.Err.(*os.SyscallError); ok {
   493  		t, ok := ne.Err.(temporary)
   494  		return ok && t.Temporary()
   495  	}
   496  	t, ok := e.Err.(temporary)
   497  	return ok && t.Temporary()
   498  }
   499  
   500  // A ParseError is the error type of literal network address parsers.
   501  type ParseError struct {
   502  	// Type is the type of string that was expected, such as
   503  	// "IP address", "CIDR address".
   504  	Type string
   505  
   506  	// Text is the malformed text string.
   507  	Text string
   508  }
   509  
   510  func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
   511  
   512  type AddrError struct {
   513  	Err  string
   514  	Addr string
   515  }
   516  
   517  func (e *AddrError) Error() string {
   518  	if e == nil {
   519  		return "<nil>"
   520  	}
   521  	s := e.Err
   522  	if e.Addr != "" {
   523  		s = "address " + e.Addr + ": " + s
   524  	}
   525  	return s
   526  }
   527  
   528  func (e *AddrError) Timeout() bool   { return false }
   529  func (e *AddrError) Temporary() bool { return false }
   530  
   531  type UnknownNetworkError string
   532  
   533  func (e UnknownNetworkError) Error() string   { return "unknown network " + string(e) }
   534  func (e UnknownNetworkError) Timeout() bool   { return false }
   535  func (e UnknownNetworkError) Temporary() bool { return false }
   536  
   537  type InvalidAddrError string
   538  
   539  func (e InvalidAddrError) Error() string   { return string(e) }
   540  func (e InvalidAddrError) Timeout() bool   { return false }
   541  func (e InvalidAddrError) Temporary() bool { return false }
   542  
   543  // DNSConfigError represents an error reading the machine's DNS configuration.
   544  // (No longer used; kept for compatibility.)
   545  type DNSConfigError struct {
   546  	Err error
   547  }
   548  
   549  func (e *DNSConfigError) Error() string   { return "error reading DNS config: " + e.Err.Error() }
   550  func (e *DNSConfigError) Timeout() bool   { return false }
   551  func (e *DNSConfigError) Temporary() bool { return false }
   552  
   553  // Various errors contained in DNSError.
   554  var (
   555  	errNoSuchHost = errors.New("no such host")
   556  )
   557  
   558  // DNSError represents a DNS lookup error.
   559  type DNSError struct {
   560  	Err         string // description of the error
   561  	Name        string // name looked for
   562  	Server      string // server used
   563  	IsTimeout   bool   // if true, timed out; not all timeouts set this
   564  	IsTemporary bool   // if true, error is temporary; not all errors set this
   565  }
   566  
   567  func (e *DNSError) Error() string {
   568  	if e == nil {
   569  		return "<nil>"
   570  	}
   571  	s := "lookup " + e.Name
   572  	if e.Server != "" {
   573  		s += " on " + e.Server
   574  	}
   575  	s += ": " + e.Err
   576  	return s
   577  }
   578  
   579  // Timeout reports whether the DNS lookup is known to have timed out.
   580  // This is not always known; a DNS lookup may fail due to a timeout
   581  // and return a DNSError for which Timeout returns false.
   582  func (e *DNSError) Timeout() bool { return e.IsTimeout }
   583  
   584  // Temporary reports whether the DNS error is known to be temporary.
   585  // This is not always known; a DNS lookup may fail due to a temporary
   586  // error and return a DNSError for which Temporary returns false.
   587  func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
   588  
   589  type writerOnly struct {
   590  	io.Writer
   591  }
   592  
   593  // Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
   594  // applicable.
   595  func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
   596  	// Use wrapper to hide existing r.ReadFrom from io.Copy.
   597  	return io.Copy(writerOnly{w}, r)
   598  }
   599  
   600  // Limit the number of concurrent cgo-using goroutines, because
   601  // each will block an entire operating system thread. The usual culprit
   602  // is resolving many DNS names in separate goroutines but the DNS
   603  // server is not responding. Then the many lookups each use a different
   604  // thread, and the system or the program runs out of threads.
   605  
   606  var threadLimit = make(chan struct{}, 500)
   607  
   608  func acquireThread() {
   609  	threadLimit <- struct{}{}
   610  }
   611  
   612  func releaseThread() {
   613  	<-threadLimit
   614  }
   615  
   616  // buffersWriter is the interface implemented by Conns that support a
   617  // "writev"-like batch write optimization.
   618  // writeBuffers should fully consume and write all chunks from the
   619  // provided Buffers, else it should report a non-nil error.
   620  type buffersWriter interface {
   621  	writeBuffers(*Buffers) (int64, error)
   622  }
   623  
   624  // Buffers contains zero or more runs of bytes to write.
   625  //
   626  // On certain machines, for certain types of connections, this is
   627  // optimized into an OS-specific batch write operation (such as
   628  // "writev").
   629  type Buffers [][]byte
   630  
   631  var (
   632  	_ io.WriterTo = (*Buffers)(nil)
   633  	_ io.Reader   = (*Buffers)(nil)
   634  )
   635  
   636  func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) {
   637  	if wv, ok := w.(buffersWriter); ok {
   638  		return wv.writeBuffers(v)
   639  	}
   640  	for _, b := range *v {
   641  		nb, err := w.Write(b)
   642  		n += int64(nb)
   643  		if err != nil {
   644  			v.consume(n)
   645  			return n, err
   646  		}
   647  	}
   648  	v.consume(n)
   649  	return n, nil
   650  }
   651  
   652  func (v *Buffers) Read(p []byte) (n int, err error) {
   653  	for len(p) > 0 && len(*v) > 0 {
   654  		n0 := copy(p, (*v)[0])
   655  		v.consume(int64(n0))
   656  		p = p[n0:]
   657  		n += n0
   658  	}
   659  	if len(*v) == 0 {
   660  		err = io.EOF
   661  	}
   662  	return
   663  }
   664  
   665  func (v *Buffers) consume(n int64) {
   666  	for len(*v) > 0 {
   667  		ln0 := int64(len((*v)[0]))
   668  		if ln0 > n {
   669  			(*v)[0] = (*v)[0][n:]
   670  			return
   671  		}
   672  		n -= ln0
   673  		*v = (*v)[1:]
   674  	}
   675  }
   676  

View as plain text