github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/internal/poll/fd_unix.go (about)

     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  // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
     6  
     7  package poll
     8  
     9  import (
    10  	"io"
    11  	"syscall"
    12  )
    13  
    14  // FD is a file descriptor. The net and os packages use this type as a
    15  // field of a larger type representing a network connection or OS file.
    16  type FD struct {
    17  	// Lock sysfd and serialize access to Read and Write methods.
    18  	fdmu fdMutex
    19  
    20  	// System file descriptor. Immutable until Close.
    21  	Sysfd int
    22  
    23  	// I/O poller.
    24  	pd pollDesc
    25  
    26  	// Writev cache.
    27  	iovecs *[]syscall.Iovec
    28  
    29  	// Whether this is a streaming descriptor, as opposed to a
    30  	// packet-based descriptor like a UDP socket. Immutable.
    31  	IsStream bool
    32  
    33  	// Whether a zero byte read indicates EOF. This is false for a
    34  	// message based socket connection.
    35  	ZeroReadIsEOF bool
    36  }
    37  
    38  // Init initializes the FD. The Sysfd field should already be set.
    39  // This can be called multiple times on a single FD.
    40  func (fd *FD) Init() error {
    41  	return fd.pd.init(fd)
    42  }
    43  
    44  // Destroy closes the file descriptor. This is called when there are
    45  // no remaining references.
    46  func (fd *FD) destroy() error {
    47  	// Poller may want to unregister fd in readiness notification mechanism,
    48  	// so this must be executed before CloseFunc.
    49  	fd.pd.close()
    50  	err := CloseFunc(fd.Sysfd)
    51  	fd.Sysfd = -1
    52  	return err
    53  }
    54  
    55  // Close closes the FD. The underlying file descriptor is closed by the
    56  // destroy method when there are no remaining references.
    57  func (fd *FD) Close() error {
    58  	if !fd.fdmu.increfAndClose() {
    59  		return ErrClosing
    60  	}
    61  	// Unblock any I/O.  Once it all unblocks and returns,
    62  	// so that it cannot be referring to fd.sysfd anymore,
    63  	// the final decref will close fd.sysfd. This should happen
    64  	// fairly quickly, since all the I/O is non-blocking, and any
    65  	// attempts to block in the pollDesc will return ErrClosing.
    66  	fd.pd.evict()
    67  	// The call to decref will call destroy if there are no other
    68  	// references.
    69  	return fd.decref()
    70  }
    71  
    72  // Shutdown wraps the shutdown network call.
    73  func (fd *FD) Shutdown(how int) error {
    74  	if err := fd.incref(); err != nil {
    75  		return err
    76  	}
    77  	defer fd.decref()
    78  	return syscall.Shutdown(fd.Sysfd, how)
    79  }
    80  
    81  // Darwin and FreeBSD can't read or write 2GB+ files at a time,
    82  // even on 64-bit systems.
    83  // The same is true of socket implementations on many systems.
    84  // See golang.org/issue/7812 and golang.org/issue/16266.
    85  // Use 1GB instead of, say, 2GB-1, to keep subsequent reads aligned.
    86  const maxRW = 1 << 30
    87  
    88  // Read implements io.Reader.
    89  func (fd *FD) Read(p []byte) (int, error) {
    90  	if err := fd.readLock(); err != nil {
    91  		return 0, err
    92  	}
    93  	defer fd.readUnlock()
    94  	if len(p) == 0 {
    95  		// If the caller wanted a zero byte read, return immediately
    96  		// without trying (but after acquiring the readLock).
    97  		// Otherwise syscall.Read returns 0, nil which looks like
    98  		// io.EOF.
    99  		// TODO(bradfitz): make it wait for readability? (Issue 15735)
   100  		return 0, nil
   101  	}
   102  	if err := fd.pd.prepareRead(); err != nil {
   103  		return 0, err
   104  	}
   105  	if fd.IsStream && len(p) > maxRW {
   106  		p = p[:maxRW]
   107  	}
   108  	for {
   109  		n, err := syscall.Read(fd.Sysfd, p)
   110  		if err != nil {
   111  			n = 0
   112  			if err == syscall.EAGAIN {
   113  				if err = fd.pd.waitRead(); err == nil {
   114  					continue
   115  				}
   116  			}
   117  		}
   118  		err = fd.eofError(n, err)
   119  		return n, err
   120  	}
   121  }
   122  
   123  // Pread wraps the pread system call.
   124  func (fd *FD) Pread(p []byte, off int64) (int, error) {
   125  	if err := fd.readLock(); err != nil {
   126  		return 0, err
   127  	}
   128  	defer fd.readUnlock()
   129  	if err := fd.pd.prepareRead(); err != nil {
   130  		return 0, err
   131  	}
   132  	if fd.IsStream && len(p) > maxRW {
   133  		p = p[:maxRW]
   134  	}
   135  	for {
   136  		n, err := syscall.Pread(fd.Sysfd, p, off)
   137  		if err != nil {
   138  			n = 0
   139  			if err == syscall.EAGAIN {
   140  				if err = fd.pd.waitRead(); err == nil {
   141  					continue
   142  				}
   143  			}
   144  		}
   145  		err = fd.eofError(n, err)
   146  		return n, err
   147  	}
   148  }
   149  
   150  // ReadFrom wraps the recvfrom network call.
   151  func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) {
   152  	if err := fd.readLock(); err != nil {
   153  		return 0, nil, err
   154  	}
   155  	defer fd.readUnlock()
   156  	if err := fd.pd.prepareRead(); err != nil {
   157  		return 0, nil, err
   158  	}
   159  	for {
   160  		n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0)
   161  		if err != nil {
   162  			n = 0
   163  			if err == syscall.EAGAIN {
   164  				if err = fd.pd.waitRead(); err == nil {
   165  					continue
   166  				}
   167  			}
   168  		}
   169  		err = fd.eofError(n, err)
   170  		return n, sa, err
   171  	}
   172  }
   173  
   174  // ReadMsg wraps the recvmsg network call.
   175  func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) {
   176  	if err := fd.readLock(); err != nil {
   177  		return 0, 0, 0, nil, err
   178  	}
   179  	defer fd.readUnlock()
   180  	if err := fd.pd.prepareRead(); err != nil {
   181  		return 0, 0, 0, nil, err
   182  	}
   183  	for {
   184  		n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0)
   185  		if err != nil {
   186  			// TODO(dfc) should n and oobn be set to 0
   187  			if err == syscall.EAGAIN {
   188  				if err = fd.pd.waitRead(); err == nil {
   189  					continue
   190  				}
   191  			}
   192  		}
   193  		err = fd.eofError(n, err)
   194  		return n, oobn, flags, sa, err
   195  	}
   196  }
   197  
   198  // Write implements io.Writer.
   199  func (fd *FD) Write(p []byte) (int, error) {
   200  	if err := fd.writeLock(); err != nil {
   201  		return 0, err
   202  	}
   203  	defer fd.writeUnlock()
   204  	if err := fd.pd.prepareWrite(); err != nil {
   205  		return 0, err
   206  	}
   207  	var nn int
   208  	for {
   209  		max := len(p)
   210  		if fd.IsStream && max-nn > maxRW {
   211  			max = nn + maxRW
   212  		}
   213  		n, err := syscall.Write(fd.Sysfd, p[nn:max])
   214  		if n > 0 {
   215  			nn += n
   216  		}
   217  		if nn == len(p) {
   218  			return nn, err
   219  		}
   220  		if err == syscall.EAGAIN {
   221  			if err = fd.pd.waitWrite(); err == nil {
   222  				continue
   223  			}
   224  		}
   225  		if err != nil {
   226  			return nn, err
   227  		}
   228  		if n == 0 {
   229  			return nn, io.ErrUnexpectedEOF
   230  		}
   231  	}
   232  }
   233  
   234  // Pwrite wraps the pwrite system call.
   235  func (fd *FD) Pwrite(p []byte, off int64) (int, error) {
   236  	if err := fd.writeLock(); err != nil {
   237  		return 0, err
   238  	}
   239  	defer fd.writeUnlock()
   240  	if err := fd.pd.prepareWrite(); err != nil {
   241  		return 0, err
   242  	}
   243  	var nn int
   244  	for {
   245  		max := len(p)
   246  		if fd.IsStream && max-nn > maxRW {
   247  			max = nn + maxRW
   248  		}
   249  		n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn))
   250  		if n > 0 {
   251  			nn += n
   252  		}
   253  		if nn == len(p) {
   254  			return nn, err
   255  		}
   256  		if err == syscall.EAGAIN {
   257  			if err = fd.pd.waitWrite(); err == nil {
   258  				continue
   259  			}
   260  		}
   261  		if err != nil {
   262  			return nn, err
   263  		}
   264  		if n == 0 {
   265  			return nn, io.ErrUnexpectedEOF
   266  		}
   267  	}
   268  }
   269  
   270  // WriteTo wraps the sendto network call.
   271  func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) {
   272  	if err := fd.writeLock(); err != nil {
   273  		return 0, err
   274  	}
   275  	defer fd.writeUnlock()
   276  	if err := fd.pd.prepareWrite(); err != nil {
   277  		return 0, err
   278  	}
   279  	for {
   280  		err := syscall.Sendto(fd.Sysfd, p, 0, sa)
   281  		if err == syscall.EAGAIN {
   282  			if err = fd.pd.waitWrite(); err == nil {
   283  				continue
   284  			}
   285  		}
   286  		if err != nil {
   287  			return 0, err
   288  		}
   289  		return len(p), nil
   290  	}
   291  }
   292  
   293  // WriteMsg wraps the sendmsg network call.
   294  func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
   295  	if err := fd.writeLock(); err != nil {
   296  		return 0, 0, err
   297  	}
   298  	defer fd.writeUnlock()
   299  	if err := fd.pd.prepareWrite(); err != nil {
   300  		return 0, 0, err
   301  	}
   302  	for {
   303  		n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0)
   304  		if err == syscall.EAGAIN {
   305  			if err = fd.pd.waitWrite(); err == nil {
   306  				continue
   307  			}
   308  		}
   309  		if err != nil {
   310  			return n, 0, err
   311  		}
   312  		return n, len(oob), err
   313  	}
   314  }
   315  
   316  // Accept wraps the accept network call.
   317  func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) {
   318  	if err := fd.readLock(); err != nil {
   319  		return -1, nil, "", err
   320  	}
   321  	defer fd.readUnlock()
   322  
   323  	if err := fd.pd.prepareRead(); err != nil {
   324  		return -1, nil, "", err
   325  	}
   326  	for {
   327  		s, rsa, errcall, err := accept(fd.Sysfd)
   328  		if err == nil {
   329  			return s, rsa, "", err
   330  		}
   331  		switch err {
   332  		case syscall.EAGAIN:
   333  			if err = fd.pd.waitRead(); err == nil {
   334  				continue
   335  			}
   336  		case syscall.ECONNABORTED:
   337  			// This means that a socket on the listen
   338  			// queue was closed before we Accept()ed it;
   339  			// it's a silly error, so try again.
   340  			continue
   341  		}
   342  		return -1, nil, errcall, err
   343  	}
   344  }
   345  
   346  // Seek wraps syscall.Seek.
   347  func (fd *FD) Seek(offset int64, whence int) (int64, error) {
   348  	if err := fd.incref(); err != nil {
   349  		return 0, err
   350  	}
   351  	defer fd.decref()
   352  	return syscall.Seek(fd.Sysfd, offset, whence)
   353  }
   354  
   355  // ReadDirent wraps syscall.ReadDirent.
   356  // We treat this like an ordinary system call rather than a call
   357  // that tries to fill the buffer.
   358  func (fd *FD) ReadDirent(buf []byte) (int, error) {
   359  	if err := fd.incref(); err != nil {
   360  		return 0, err
   361  	}
   362  	defer fd.decref()
   363  	for {
   364  		n, err := syscall.ReadDirent(fd.Sysfd, buf)
   365  		if err != nil {
   366  			n = 0
   367  			if err == syscall.EAGAIN {
   368  				if err = fd.pd.waitRead(); err == nil {
   369  					continue
   370  				}
   371  			}
   372  		}
   373  		// Do not call eofError; caller does not expect to see io.EOF.
   374  		return n, err
   375  	}
   376  }
   377  
   378  // Fchdir wraps syscall.Fchdir.
   379  func (fd *FD) Fchdir() error {
   380  	if err := fd.incref(); err != nil {
   381  		return err
   382  	}
   383  	defer fd.decref()
   384  	return syscall.Fchdir(fd.Sysfd)
   385  }
   386  
   387  // Fstat wraps syscall.Fstat
   388  func (fd *FD) Fstat(s *syscall.Stat_t) error {
   389  	if err := fd.incref(); err != nil {
   390  		return err
   391  	}
   392  	defer fd.decref()
   393  	return syscall.Fstat(fd.Sysfd, s)
   394  }
   395  
   396  // On Unix variants only, expose the IO event for the net code.
   397  
   398  // WaitWrite waits until data can be read from fd.
   399  func (fd *FD) WaitWrite() error {
   400  	return fd.pd.waitWrite()
   401  }