github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/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  	// Semaphore signaled when file is closed.
    30  	csema uint32
    31  
    32  	// Whether this is a streaming descriptor, as opposed to a
    33  	// packet-based descriptor like a UDP socket. Immutable.
    34  	IsStream bool
    35  
    36  	// Whether a zero byte read indicates EOF. This is false for a
    37  	// message based socket connection.
    38  	ZeroReadIsEOF bool
    39  
    40  	// Whether this is a file rather than a network socket.
    41  	isFile bool
    42  }
    43  
    44  // Init initializes the FD. The Sysfd field should already be set.
    45  // This can be called multiple times on a single FD.
    46  // The net argument is a network name from the net package (e.g., "tcp"),
    47  // or "file".
    48  // Set pollable to true if fd should be managed by runtime netpoll.
    49  func (fd *FD) Init(net string, pollable bool) error {
    50  	// We don't actually care about the various network types.
    51  	if net == "file" {
    52  		fd.isFile = true
    53  	}
    54  	if !pollable {
    55  		return nil
    56  	}
    57  	return fd.pd.init(fd)
    58  }
    59  
    60  // Destroy closes the file descriptor. This is called when there are
    61  // no remaining references.
    62  func (fd *FD) destroy() error {
    63  	// Poller may want to unregister fd in readiness notification mechanism,
    64  	// so this must be executed before CloseFunc.
    65  	fd.pd.close()
    66  	err := CloseFunc(fd.Sysfd)
    67  	fd.Sysfd = -1
    68  	runtime_Semrelease(&fd.csema)
    69  	return err
    70  }
    71  
    72  // Close closes the FD. The underlying file descriptor is closed by the
    73  // destroy method when there are no remaining references.
    74  func (fd *FD) Close() error {
    75  	if !fd.fdmu.increfAndClose() {
    76  		return errClosing(fd.isFile)
    77  	}
    78  	// Unblock any I/O.  Once it all unblocks and returns,
    79  	// so that it cannot be referring to fd.sysfd anymore,
    80  	// the final decref will close fd.sysfd. This should happen
    81  	// fairly quickly, since all the I/O is non-blocking, and any
    82  	// attempts to block in the pollDesc will return errClosing(fd.isFile).
    83  	fd.pd.evict()
    84  	// The call to decref will call destroy if there are no other
    85  	// references.
    86  	err := fd.decref()
    87  	// Wait until the descriptor is closed. If this was the only
    88  	// reference, it is already closed.
    89  	runtime_Semacquire(&fd.csema)
    90  	return err
    91  }
    92  
    93  // Shutdown wraps the shutdown network call.
    94  func (fd *FD) Shutdown(how int) error {
    95  	if err := fd.incref(); err != nil {
    96  		return err
    97  	}
    98  	defer fd.decref()
    99  	return syscall.Shutdown(fd.Sysfd, how)
   100  }
   101  
   102  // Darwin and FreeBSD can't read or write 2GB+ files at a time,
   103  // even on 64-bit systems.
   104  // The same is true of socket implementations on many systems.
   105  // See golang.org/issue/7812 and golang.org/issue/16266.
   106  // Use 1GB instead of, say, 2GB-1, to keep subsequent reads aligned.
   107  const maxRW = 1 << 30
   108  
   109  // Read implements io.Reader.
   110  func (fd *FD) Read(p []byte) (int, error) {
   111  	if err := fd.readLock(); err != nil {
   112  		return 0, err
   113  	}
   114  	defer fd.readUnlock()
   115  	if len(p) == 0 {
   116  		// If the caller wanted a zero byte read, return immediately
   117  		// without trying (but after acquiring the readLock).
   118  		// Otherwise syscall.Read returns 0, nil which looks like
   119  		// io.EOF.
   120  		// TODO(bradfitz): make it wait for readability? (Issue 15735)
   121  		return 0, nil
   122  	}
   123  	if err := fd.pd.prepareRead(fd.isFile); err != nil {
   124  		return 0, err
   125  	}
   126  	if fd.IsStream && len(p) > maxRW {
   127  		p = p[:maxRW]
   128  	}
   129  	for {
   130  		n, err := syscall.Read(fd.Sysfd, p)
   131  		if err != nil {
   132  			n = 0
   133  			if err == syscall.EAGAIN && fd.pd.pollable() {
   134  				if err = fd.pd.waitRead(fd.isFile); err == nil {
   135  					continue
   136  				}
   137  			}
   138  		}
   139  		err = fd.eofError(n, err)
   140  		return n, err
   141  	}
   142  }
   143  
   144  // Pread wraps the pread system call.
   145  func (fd *FD) Pread(p []byte, off int64) (int, error) {
   146  	// Call incref, not readLock, because since pread specifies the
   147  	// offset it is independent from other reads.
   148  	// Similarly, using the poller doesn't make sense for pread.
   149  	if err := fd.incref(); err != nil {
   150  		return 0, err
   151  	}
   152  	if fd.IsStream && len(p) > maxRW {
   153  		p = p[:maxRW]
   154  	}
   155  	n, err := syscall.Pread(fd.Sysfd, p, off)
   156  	if err != nil {
   157  		n = 0
   158  	}
   159  	fd.decref()
   160  	err = fd.eofError(n, err)
   161  	return n, err
   162  }
   163  
   164  // ReadFrom wraps the recvfrom network call.
   165  func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) {
   166  	if err := fd.readLock(); err != nil {
   167  		return 0, nil, err
   168  	}
   169  	defer fd.readUnlock()
   170  	if err := fd.pd.prepareRead(fd.isFile); err != nil {
   171  		return 0, nil, err
   172  	}
   173  	for {
   174  		n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0)
   175  		if err != nil {
   176  			n = 0
   177  			if err == syscall.EAGAIN && fd.pd.pollable() {
   178  				if err = fd.pd.waitRead(fd.isFile); err == nil {
   179  					continue
   180  				}
   181  			}
   182  		}
   183  		err = fd.eofError(n, err)
   184  		return n, sa, err
   185  	}
   186  }
   187  
   188  // ReadMsg wraps the recvmsg network call.
   189  func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) {
   190  	if err := fd.readLock(); err != nil {
   191  		return 0, 0, 0, nil, err
   192  	}
   193  	defer fd.readUnlock()
   194  	if err := fd.pd.prepareRead(fd.isFile); err != nil {
   195  		return 0, 0, 0, nil, err
   196  	}
   197  	for {
   198  		n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0)
   199  		if err != nil {
   200  			// TODO(dfc) should n and oobn be set to 0
   201  			if err == syscall.EAGAIN && fd.pd.pollable() {
   202  				if err = fd.pd.waitRead(fd.isFile); err == nil {
   203  					continue
   204  				}
   205  			}
   206  		}
   207  		err = fd.eofError(n, err)
   208  		return n, oobn, flags, sa, err
   209  	}
   210  }
   211  
   212  // Write implements io.Writer.
   213  func (fd *FD) Write(p []byte) (int, error) {
   214  	if err := fd.writeLock(); err != nil {
   215  		return 0, err
   216  	}
   217  	defer fd.writeUnlock()
   218  	if err := fd.pd.prepareWrite(fd.isFile); err != nil {
   219  		return 0, err
   220  	}
   221  	var nn int
   222  	for {
   223  		max := len(p)
   224  		if fd.IsStream && max-nn > maxRW {
   225  			max = nn + maxRW
   226  		}
   227  		n, err := syscall.Write(fd.Sysfd, p[nn:max])
   228  		if n > 0 {
   229  			nn += n
   230  		}
   231  		if nn == len(p) {
   232  			return nn, err
   233  		}
   234  		if err == syscall.EAGAIN && fd.pd.pollable() {
   235  			if err = fd.pd.waitWrite(fd.isFile); err == nil {
   236  				continue
   237  			}
   238  		}
   239  		if err != nil {
   240  			return nn, err
   241  		}
   242  		if n == 0 {
   243  			return nn, io.ErrUnexpectedEOF
   244  		}
   245  	}
   246  }
   247  
   248  // Pwrite wraps the pwrite system call.
   249  func (fd *FD) Pwrite(p []byte, off int64) (int, error) {
   250  	// Call incref, not writeLock, because since pwrite specifies the
   251  	// offset it is independent from other writes.
   252  	// Similarly, using the poller doesn't make sense for pwrite.
   253  	if err := fd.incref(); err != nil {
   254  		return 0, err
   255  	}
   256  	defer fd.decref()
   257  	var nn int
   258  	for {
   259  		max := len(p)
   260  		if fd.IsStream && max-nn > maxRW {
   261  			max = nn + maxRW
   262  		}
   263  		n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn))
   264  		if n > 0 {
   265  			nn += n
   266  		}
   267  		if nn == len(p) {
   268  			return nn, err
   269  		}
   270  		if err != nil {
   271  			return nn, err
   272  		}
   273  		if n == 0 {
   274  			return nn, io.ErrUnexpectedEOF
   275  		}
   276  	}
   277  }
   278  
   279  // WriteTo wraps the sendto network call.
   280  func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) {
   281  	if err := fd.writeLock(); err != nil {
   282  		return 0, err
   283  	}
   284  	defer fd.writeUnlock()
   285  	if err := fd.pd.prepareWrite(fd.isFile); err != nil {
   286  		return 0, err
   287  	}
   288  	for {
   289  		err := syscall.Sendto(fd.Sysfd, p, 0, sa)
   290  		if err == syscall.EAGAIN && fd.pd.pollable() {
   291  			if err = fd.pd.waitWrite(fd.isFile); err == nil {
   292  				continue
   293  			}
   294  		}
   295  		if err != nil {
   296  			return 0, err
   297  		}
   298  		return len(p), nil
   299  	}
   300  }
   301  
   302  // WriteMsg wraps the sendmsg network call.
   303  func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
   304  	if err := fd.writeLock(); err != nil {
   305  		return 0, 0, err
   306  	}
   307  	defer fd.writeUnlock()
   308  	if err := fd.pd.prepareWrite(fd.isFile); err != nil {
   309  		return 0, 0, err
   310  	}
   311  	for {
   312  		n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0)
   313  		if err == syscall.EAGAIN && fd.pd.pollable() {
   314  			if err = fd.pd.waitWrite(fd.isFile); err == nil {
   315  				continue
   316  			}
   317  		}
   318  		if err != nil {
   319  			return n, 0, err
   320  		}
   321  		return n, len(oob), err
   322  	}
   323  }
   324  
   325  // Accept wraps the accept network call.
   326  func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) {
   327  	if err := fd.readLock(); err != nil {
   328  		return -1, nil, "", err
   329  	}
   330  	defer fd.readUnlock()
   331  
   332  	if err := fd.pd.prepareRead(fd.isFile); err != nil {
   333  		return -1, nil, "", err
   334  	}
   335  	for {
   336  		s, rsa, errcall, err := accept(fd.Sysfd)
   337  		if err == nil {
   338  			return s, rsa, "", err
   339  		}
   340  		switch err {
   341  		case syscall.EAGAIN:
   342  			if fd.pd.pollable() {
   343  				if err = fd.pd.waitRead(fd.isFile); err == nil {
   344  					continue
   345  				}
   346  			}
   347  		case syscall.ECONNABORTED:
   348  			// This means that a socket on the listen
   349  			// queue was closed before we Accept()ed it;
   350  			// it's a silly error, so try again.
   351  			continue
   352  		}
   353  		return -1, nil, errcall, err
   354  	}
   355  }
   356  
   357  // Seek wraps syscall.Seek.
   358  func (fd *FD) Seek(offset int64, whence int) (int64, error) {
   359  	if err := fd.incref(); err != nil {
   360  		return 0, err
   361  	}
   362  	defer fd.decref()
   363  	return syscall.Seek(fd.Sysfd, offset, whence)
   364  }
   365  
   366  // ReadDirent wraps syscall.ReadDirent.
   367  // We treat this like an ordinary system call rather than a call
   368  // that tries to fill the buffer.
   369  func (fd *FD) ReadDirent(buf []byte) (int, error) {
   370  	if err := fd.incref(); err != nil {
   371  		return 0, err
   372  	}
   373  	defer fd.decref()
   374  	for {
   375  		n, err := syscall.ReadDirent(fd.Sysfd, buf)
   376  		if err != nil {
   377  			n = 0
   378  			if err == syscall.EAGAIN && fd.pd.pollable() {
   379  				if err = fd.pd.waitRead(fd.isFile); err == nil {
   380  					continue
   381  				}
   382  			}
   383  		}
   384  		// Do not call eofError; caller does not expect to see io.EOF.
   385  		return n, err
   386  	}
   387  }
   388  
   389  // Fchdir wraps syscall.Fchdir.
   390  func (fd *FD) Fchdir() error {
   391  	if err := fd.incref(); err != nil {
   392  		return err
   393  	}
   394  	defer fd.decref()
   395  	return syscall.Fchdir(fd.Sysfd)
   396  }
   397  
   398  // Fstat wraps syscall.Fstat
   399  func (fd *FD) Fstat(s *syscall.Stat_t) error {
   400  	if err := fd.incref(); err != nil {
   401  		return err
   402  	}
   403  	defer fd.decref()
   404  	return syscall.Fstat(fd.Sysfd, s)
   405  }
   406  
   407  // On Unix variants only, expose the IO event for the net code.
   408  
   409  // WaitWrite waits until data can be read from fd.
   410  func (fd *FD) WaitWrite() error {
   411  	return fd.pd.waitWrite(fd.isFile)
   412  }
   413  
   414  // WriteOnce is for testing only. It makes a single write call.
   415  func (fd *FD) WriteOnce(p []byte) (int, error) {
   416  	if err := fd.writeLock(); err != nil {
   417  		return 0, err
   418  	}
   419  	defer fd.writeUnlock()
   420  	return syscall.Write(fd.Sysfd, p)
   421  }
   422  
   423  // RawControl invokes the user-defined function f for a non-IO
   424  // operation.
   425  func (fd *FD) RawControl(f func(uintptr)) error {
   426  	if err := fd.incref(); err != nil {
   427  		return err
   428  	}
   429  	defer fd.decref()
   430  	f(uintptr(fd.Sysfd))
   431  	return nil
   432  }
   433  
   434  // RawRead invokes the user-defined function f for a read operation.
   435  func (fd *FD) RawRead(f func(uintptr) bool) error {
   436  	if err := fd.readLock(); err != nil {
   437  		return err
   438  	}
   439  	defer fd.readUnlock()
   440  	if err := fd.pd.prepareRead(fd.isFile); err != nil {
   441  		return err
   442  	}
   443  	for {
   444  		if f(uintptr(fd.Sysfd)) {
   445  			return nil
   446  		}
   447  		if err := fd.pd.waitRead(fd.isFile); err != nil {
   448  			return err
   449  		}
   450  	}
   451  }
   452  
   453  // RawWrite invokes the user-defined function f for a write operation.
   454  func (fd *FD) RawWrite(f func(uintptr) bool) error {
   455  	if err := fd.writeLock(); err != nil {
   456  		return err
   457  	}
   458  	defer fd.writeUnlock()
   459  	if err := fd.pd.prepareWrite(fd.isFile); err != nil {
   460  		return err
   461  	}
   462  	for {
   463  		if f(uintptr(fd.Sysfd)) {
   464  			return nil
   465  		}
   466  		if err := fd.pd.waitWrite(fd.isFile); err != nil {
   467  			return err
   468  		}
   469  	}
   470  }