...

Source file src/internal/poll/fd_unix.go

     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 aix darwin dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris
     6	
     7	package poll
     8	
     9	import (
    10		"io"
    11		"runtime"
    12		"sync/atomic"
    13		"syscall"
    14	)
    15	
    16	// FD is a file descriptor. The net and os packages use this type as a
    17	// field of a larger type representing a network connection or OS file.
    18	type FD struct {
    19		// Lock sysfd and serialize access to Read and Write methods.
    20		fdmu fdMutex
    21	
    22		// System file descriptor. Immutable until Close.
    23		Sysfd int
    24	
    25		// I/O poller.
    26		pd pollDesc
    27	
    28		// Writev cache.
    29		iovecs *[]syscall.Iovec
    30	
    31		// Semaphore signaled when file is closed.
    32		csema uint32
    33	
    34		// Non-zero if this file has been set to blocking mode.
    35		isBlocking uint32
    36	
    37		// Whether this is a streaming descriptor, as opposed to a
    38		// packet-based descriptor like a UDP socket. Immutable.
    39		IsStream bool
    40	
    41		// Whether a zero byte read indicates EOF. This is false for a
    42		// message based socket connection.
    43		ZeroReadIsEOF bool
    44	
    45		// Whether this is a file rather than a network socket.
    46		isFile bool
    47	}
    48	
    49	// Init initializes the FD. The Sysfd field should already be set.
    50	// This can be called multiple times on a single FD.
    51	// The net argument is a network name from the net package (e.g., "tcp"),
    52	// or "file".
    53	// Set pollable to true if fd should be managed by runtime netpoll.
    54	func (fd *FD) Init(net string, pollable bool) error {
    55		// We don't actually care about the various network types.
    56		if net == "file" {
    57			fd.isFile = true
    58		}
    59		if !pollable {
    60			fd.isBlocking = 1
    61			return nil
    62		}
    63		err := fd.pd.init(fd)
    64		if err != nil {
    65			// If we could not initialize the runtime poller,
    66			// assume we are using blocking mode.
    67			fd.isBlocking = 1
    68		}
    69		return err
    70	}
    71	
    72	// Destroy closes the file descriptor. This is called when there are
    73	// no remaining references.
    74	func (fd *FD) destroy() error {
    75		// Poller may want to unregister fd in readiness notification mechanism,
    76		// so this must be executed before CloseFunc.
    77		fd.pd.close()
    78		err := CloseFunc(fd.Sysfd)
    79		fd.Sysfd = -1
    80		runtime_Semrelease(&fd.csema)
    81		return err
    82	}
    83	
    84	// Close closes the FD. The underlying file descriptor is closed by the
    85	// destroy method when there are no remaining references.
    86	func (fd *FD) Close() error {
    87		if !fd.fdmu.increfAndClose() {
    88			return errClosing(fd.isFile)
    89		}
    90	
    91		// Unblock any I/O.  Once it all unblocks and returns,
    92		// so that it cannot be referring to fd.sysfd anymore,
    93		// the final decref will close fd.sysfd. This should happen
    94		// fairly quickly, since all the I/O is non-blocking, and any
    95		// attempts to block in the pollDesc will return errClosing(fd.isFile).
    96		fd.pd.evict()
    97	
    98		// The call to decref will call destroy if there are no other
    99		// references.
   100		err := fd.decref()
   101	
   102		// Wait until the descriptor is closed. If this was the only
   103		// reference, it is already closed. Only wait if the file has
   104		// not been set to blocking mode, as otherwise any current I/O
   105		// may be blocking, and that would block the Close.
   106		// No need for an atomic read of isBlocking, increfAndClose means
   107		// we have exclusive access to fd.
   108		if fd.isBlocking == 0 {
   109			runtime_Semacquire(&fd.csema)
   110		}
   111	
   112		return err
   113	}
   114	
   115	// Shutdown wraps the shutdown network call.
   116	func (fd *FD) Shutdown(how int) error {
   117		if err := fd.incref(); err != nil {
   118			return err
   119		}
   120		defer fd.decref()
   121		return syscall.Shutdown(fd.Sysfd, how)
   122	}
   123	
   124	// SetBlocking puts the file into blocking mode.
   125	func (fd *FD) SetBlocking() error {
   126		if err := fd.incref(); err != nil {
   127			return err
   128		}
   129		defer fd.decref()
   130		// Atomic store so that concurrent calls to SetBlocking
   131		// do not cause a race condition. isBlocking only ever goes
   132		// from 0 to 1 so there is no real race here.
   133		atomic.StoreUint32(&fd.isBlocking, 1)
   134		return syscall.SetNonblock(fd.Sysfd, false)
   135	}
   136	
   137	// Darwin and FreeBSD can't read or write 2GB+ files at a time,
   138	// even on 64-bit systems.
   139	// The same is true of socket implementations on many systems.
   140	// See golang.org/issue/7812 and golang.org/issue/16266.
   141	// Use 1GB instead of, say, 2GB-1, to keep subsequent reads aligned.
   142	const maxRW = 1 << 30
   143	
   144	// Read implements io.Reader.
   145	func (fd *FD) Read(p []byte) (int, error) {
   146		if err := fd.readLock(); err != nil {
   147			return 0, err
   148		}
   149		defer fd.readUnlock()
   150		if len(p) == 0 {
   151			// If the caller wanted a zero byte read, return immediately
   152			// without trying (but after acquiring the readLock).
   153			// Otherwise syscall.Read returns 0, nil which looks like
   154			// io.EOF.
   155			// TODO(bradfitz): make it wait for readability? (Issue 15735)
   156			return 0, nil
   157		}
   158		if err := fd.pd.prepareRead(fd.isFile); err != nil {
   159			return 0, err
   160		}
   161		if fd.IsStream && len(p) > maxRW {
   162			p = p[:maxRW]
   163		}
   164		for {
   165			n, err := syscall.Read(fd.Sysfd, p)
   166			if err != nil {
   167				n = 0
   168				if err == syscall.EAGAIN && fd.pd.pollable() {
   169					if err = fd.pd.waitRead(fd.isFile); err == nil {
   170						continue
   171					}
   172				}
   173	
   174				// On MacOS we can see EINTR here if the user
   175				// pressed ^Z.  See issue #22838.
   176				if runtime.GOOS == "darwin" && err == syscall.EINTR {
   177					continue
   178				}
   179			}
   180			err = fd.eofError(n, err)
   181			return n, err
   182		}
   183	}
   184	
   185	// Pread wraps the pread system call.
   186	func (fd *FD) Pread(p []byte, off int64) (int, error) {
   187		// Call incref, not readLock, because since pread specifies the
   188		// offset it is independent from other reads.
   189		// Similarly, using the poller doesn't make sense for pread.
   190		if err := fd.incref(); err != nil {
   191			return 0, err
   192		}
   193		if fd.IsStream && len(p) > maxRW {
   194			p = p[:maxRW]
   195		}
   196		n, err := syscall.Pread(fd.Sysfd, p, off)
   197		if err != nil {
   198			n = 0
   199		}
   200		fd.decref()
   201		err = fd.eofError(n, err)
   202		return n, err
   203	}
   204	
   205	// ReadFrom wraps the recvfrom network call.
   206	func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) {
   207		if err := fd.readLock(); err != nil {
   208			return 0, nil, err
   209		}
   210		defer fd.readUnlock()
   211		if err := fd.pd.prepareRead(fd.isFile); err != nil {
   212			return 0, nil, err
   213		}
   214		for {
   215			n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0)
   216			if err != nil {
   217				n = 0
   218				if err == syscall.EAGAIN && fd.pd.pollable() {
   219					if err = fd.pd.waitRead(fd.isFile); err == nil {
   220						continue
   221					}
   222				}
   223			}
   224			err = fd.eofError(n, err)
   225			return n, sa, err
   226		}
   227	}
   228	
   229	// ReadMsg wraps the recvmsg network call.
   230	func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) {
   231		if err := fd.readLock(); err != nil {
   232			return 0, 0, 0, nil, err
   233		}
   234		defer fd.readUnlock()
   235		if err := fd.pd.prepareRead(fd.isFile); err != nil {
   236			return 0, 0, 0, nil, err
   237		}
   238		for {
   239			n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0)
   240			if err != nil {
   241				// TODO(dfc) should n and oobn be set to 0
   242				if err == syscall.EAGAIN && fd.pd.pollable() {
   243					if err = fd.pd.waitRead(fd.isFile); err == nil {
   244						continue
   245					}
   246				}
   247			}
   248			err = fd.eofError(n, err)
   249			return n, oobn, flags, sa, err
   250		}
   251	}
   252	
   253	// Write implements io.Writer.
   254	func (fd *FD) Write(p []byte) (int, error) {
   255		if err := fd.writeLock(); err != nil {
   256			return 0, err
   257		}
   258		defer fd.writeUnlock()
   259		if err := fd.pd.prepareWrite(fd.isFile); err != nil {
   260			return 0, err
   261		}
   262		var nn int
   263		for {
   264			max := len(p)
   265			if fd.IsStream && max-nn > maxRW {
   266				max = nn + maxRW
   267			}
   268			n, err := syscall.Write(fd.Sysfd, p[nn:max])
   269			if n > 0 {
   270				nn += n
   271			}
   272			if nn == len(p) {
   273				return nn, err
   274			}
   275			if err == syscall.EAGAIN && fd.pd.pollable() {
   276				if err = fd.pd.waitWrite(fd.isFile); err == nil {
   277					continue
   278				}
   279			}
   280			if err != nil {
   281				return nn, err
   282			}
   283			if n == 0 {
   284				return nn, io.ErrUnexpectedEOF
   285			}
   286		}
   287	}
   288	
   289	// Pwrite wraps the pwrite system call.
   290	func (fd *FD) Pwrite(p []byte, off int64) (int, error) {
   291		// Call incref, not writeLock, because since pwrite specifies the
   292		// offset it is independent from other writes.
   293		// Similarly, using the poller doesn't make sense for pwrite.
   294		if err := fd.incref(); err != nil {
   295			return 0, err
   296		}
   297		defer fd.decref()
   298		var nn int
   299		for {
   300			max := len(p)
   301			if fd.IsStream && max-nn > maxRW {
   302				max = nn + maxRW
   303			}
   304			n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn))
   305			if n > 0 {
   306				nn += n
   307			}
   308			if nn == len(p) {
   309				return nn, err
   310			}
   311			if err != nil {
   312				return nn, err
   313			}
   314			if n == 0 {
   315				return nn, io.ErrUnexpectedEOF
   316			}
   317		}
   318	}
   319	
   320	// WriteTo wraps the sendto network call.
   321	func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) {
   322		if err := fd.writeLock(); err != nil {
   323			return 0, err
   324		}
   325		defer fd.writeUnlock()
   326		if err := fd.pd.prepareWrite(fd.isFile); err != nil {
   327			return 0, err
   328		}
   329		for {
   330			err := syscall.Sendto(fd.Sysfd, p, 0, sa)
   331			if err == syscall.EAGAIN && fd.pd.pollable() {
   332				if err = fd.pd.waitWrite(fd.isFile); err == nil {
   333					continue
   334				}
   335			}
   336			if err != nil {
   337				return 0, err
   338			}
   339			return len(p), nil
   340		}
   341	}
   342	
   343	// WriteMsg wraps the sendmsg network call.
   344	func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
   345		if err := fd.writeLock(); err != nil {
   346			return 0, 0, err
   347		}
   348		defer fd.writeUnlock()
   349		if err := fd.pd.prepareWrite(fd.isFile); err != nil {
   350			return 0, 0, err
   351		}
   352		for {
   353			n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0)
   354			if err == syscall.EAGAIN && fd.pd.pollable() {
   355				if err = fd.pd.waitWrite(fd.isFile); err == nil {
   356					continue
   357				}
   358			}
   359			if err != nil {
   360				return n, 0, err
   361			}
   362			return n, len(oob), err
   363		}
   364	}
   365	
   366	// Accept wraps the accept network call.
   367	func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) {
   368		if err := fd.readLock(); err != nil {
   369			return -1, nil, "", err
   370		}
   371		defer fd.readUnlock()
   372	
   373		if err := fd.pd.prepareRead(fd.isFile); err != nil {
   374			return -1, nil, "", err
   375		}
   376		for {
   377			s, rsa, errcall, err := accept(fd.Sysfd)
   378			if err == nil {
   379				return s, rsa, "", err
   380			}
   381			switch err {
   382			case syscall.EAGAIN:
   383				if fd.pd.pollable() {
   384					if err = fd.pd.waitRead(fd.isFile); err == nil {
   385						continue
   386					}
   387				}
   388			case syscall.ECONNABORTED:
   389				// This means that a socket on the listen
   390				// queue was closed before we Accept()ed it;
   391				// it's a silly error, so try again.
   392				continue
   393			}
   394			return -1, nil, errcall, err
   395		}
   396	}
   397	
   398	// Seek wraps syscall.Seek.
   399	func (fd *FD) Seek(offset int64, whence int) (int64, error) {
   400		if err := fd.incref(); err != nil {
   401			return 0, err
   402		}
   403		defer fd.decref()
   404		return syscall.Seek(fd.Sysfd, offset, whence)
   405	}
   406	
   407	// ReadDirent wraps syscall.ReadDirent.
   408	// We treat this like an ordinary system call rather than a call
   409	// that tries to fill the buffer.
   410	func (fd *FD) ReadDirent(buf []byte) (int, error) {
   411		if err := fd.incref(); err != nil {
   412			return 0, err
   413		}
   414		defer fd.decref()
   415		for {
   416			n, err := syscall.ReadDirent(fd.Sysfd, buf)
   417			if err != nil {
   418				n = 0
   419				if err == syscall.EAGAIN && fd.pd.pollable() {
   420					if err = fd.pd.waitRead(fd.isFile); err == nil {
   421						continue
   422					}
   423				}
   424			}
   425			// Do not call eofError; caller does not expect to see io.EOF.
   426			return n, err
   427		}
   428	}
   429	
   430	// Fchdir wraps syscall.Fchdir.
   431	func (fd *FD) Fchdir() error {
   432		if err := fd.incref(); err != nil {
   433			return err
   434		}
   435		defer fd.decref()
   436		return syscall.Fchdir(fd.Sysfd)
   437	}
   438	
   439	// Fstat wraps syscall.Fstat
   440	func (fd *FD) Fstat(s *syscall.Stat_t) error {
   441		if err := fd.incref(); err != nil {
   442			return err
   443		}
   444		defer fd.decref()
   445		return syscall.Fstat(fd.Sysfd, s)
   446	}
   447	
   448	// tryDupCloexec indicates whether F_DUPFD_CLOEXEC should be used.
   449	// If the kernel doesn't support it, this is set to 0.
   450	var tryDupCloexec = int32(1)
   451	
   452	// DupCloseOnExec dups fd and marks it close-on-exec.
   453	func DupCloseOnExec(fd int) (int, string, error) {
   454		if atomic.LoadInt32(&tryDupCloexec) == 1 {
   455			r0, e1 := fcntl(fd, syscall.F_DUPFD_CLOEXEC, 0)
   456			if e1 == nil {
   457				return r0, "", nil
   458			}
   459			switch e1.(syscall.Errno) {
   460			case syscall.EINVAL, syscall.ENOSYS:
   461				// Old kernel, or js/wasm (which returns
   462				// ENOSYS). Fall back to the portable way from
   463				// now on.
   464				atomic.StoreInt32(&tryDupCloexec, 0)
   465			default:
   466				return -1, "fcntl", e1
   467			}
   468		}
   469		return dupCloseOnExecOld(fd)
   470	}
   471	
   472	// dupCloseOnExecUnixOld is the traditional way to dup an fd and
   473	// set its O_CLOEXEC bit, using two system calls.
   474	func dupCloseOnExecOld(fd int) (int, string, error) {
   475		syscall.ForkLock.RLock()
   476		defer syscall.ForkLock.RUnlock()
   477		newfd, err := syscall.Dup(fd)
   478		if err != nil {
   479			return -1, "dup", err
   480		}
   481		syscall.CloseOnExec(newfd)
   482		return newfd, "", nil
   483	}
   484	
   485	// Dup duplicates the file descriptor.
   486	func (fd *FD) Dup() (int, string, error) {
   487		if err := fd.incref(); err != nil {
   488			return -1, "", err
   489		}
   490		defer fd.decref()
   491		return DupCloseOnExec(fd.Sysfd)
   492	}
   493	
   494	// On Unix variants only, expose the IO event for the net code.
   495	
   496	// WaitWrite waits until data can be read from fd.
   497	func (fd *FD) WaitWrite() error {
   498		return fd.pd.waitWrite(fd.isFile)
   499	}
   500	
   501	// WriteOnce is for testing only. It makes a single write call.
   502	func (fd *FD) WriteOnce(p []byte) (int, error) {
   503		if err := fd.writeLock(); err != nil {
   504			return 0, err
   505		}
   506		defer fd.writeUnlock()
   507		return syscall.Write(fd.Sysfd, p)
   508	}
   509	
   510	// RawControl invokes the user-defined function f for a non-IO
   511	// operation.
   512	func (fd *FD) RawControl(f func(uintptr)) error {
   513		if err := fd.incref(); err != nil {
   514			return err
   515		}
   516		defer fd.decref()
   517		f(uintptr(fd.Sysfd))
   518		return nil
   519	}
   520	
   521	// RawRead invokes the user-defined function f for a read operation.
   522	func (fd *FD) RawRead(f func(uintptr) bool) error {
   523		if err := fd.readLock(); err != nil {
   524			return err
   525		}
   526		defer fd.readUnlock()
   527		if err := fd.pd.prepareRead(fd.isFile); err != nil {
   528			return err
   529		}
   530		for {
   531			if f(uintptr(fd.Sysfd)) {
   532				return nil
   533			}
   534			if err := fd.pd.waitRead(fd.isFile); err != nil {
   535				return err
   536			}
   537		}
   538	}
   539	
   540	// RawWrite invokes the user-defined function f for a write operation.
   541	func (fd *FD) RawWrite(f func(uintptr) bool) error {
   542		if err := fd.writeLock(); err != nil {
   543			return err
   544		}
   545		defer fd.writeUnlock()
   546		if err := fd.pd.prepareWrite(fd.isFile); err != nil {
   547			return err
   548		}
   549		for {
   550			if f(uintptr(fd.Sysfd)) {
   551				return nil
   552			}
   553			if err := fd.pd.waitWrite(fd.isFile); err != nil {
   554				return err
   555			}
   556		}
   557	}
   558	

View as plain text