fd_posix.mx raw

   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  //go:build unix || (js && wasm) || wasip1 || windows
   6  
   7  package poll
   8  
   9  import (
  10  	"io"
  11  	"syscall"
  12  )
  13  
  14  // eofError returns io.EOF when fd is available for reading end of
  15  // file.
  16  func (fd *FD) eofError(n int, err error) error {
  17  	if n == 0 && err == nil && fd.ZeroReadIsEOF {
  18  		return io.EOF
  19  	}
  20  	return err
  21  }
  22  
  23  // Shutdown wraps syscall.Shutdown.
  24  func (fd *FD) Shutdown(how int) error {
  25  	if err := fd.incref(); err != nil {
  26  		return err
  27  	}
  28  	defer fd.decref()
  29  	return syscall.Shutdown(fd.Sysfd, how)
  30  }
  31  
  32  // Fchown wraps syscall.Fchown.
  33  func (fd *FD) Fchown(uid, gid int) error {
  34  	if err := fd.incref(); err != nil {
  35  		return err
  36  	}
  37  	defer fd.decref()
  38  	return ignoringEINTR(func() error {
  39  		return syscall.Fchown(fd.Sysfd, uid, gid)
  40  	})
  41  }
  42  
  43  // Ftruncate wraps syscall.Ftruncate.
  44  func (fd *FD) Ftruncate(size int64) error {
  45  	if err := fd.incref(); err != nil {
  46  		return err
  47  	}
  48  	defer fd.decref()
  49  	return ignoringEINTR(func() error {
  50  		return syscall.Ftruncate(fd.Sysfd, size)
  51  	})
  52  }
  53  
  54  // RawControl invokes the user-defined function f for a non-IO
  55  // operation.
  56  func (fd *FD) RawControl(f func(uintptr)) error {
  57  	if err := fd.incref(); err != nil {
  58  		return err
  59  	}
  60  	defer fd.decref()
  61  	f(uintptr(fd.Sysfd))
  62  	return nil
  63  }
  64  
  65  // ignoringEINTR makes a function call and repeats it if it returns
  66  // an EINTR error. This appears to be required even though we install all
  67  // signal handlers with SA_RESTART: see #22838, #38033, #38836, #40846.
  68  // Also #20400 and #36644 are issues in which a signal handler is
  69  // installed without setting SA_RESTART. None of these are the common case,
  70  // but there are enough of them that it seems that we can't avoid
  71  // an EINTR loop.
  72  func ignoringEINTR(fn func() error) error {
  73  	for {
  74  		err := fn()
  75  		if err != syscall.EINTR {
  76  			return err
  77  		}
  78  	}
  79  }
  80  
  81  // ignoringEINTR2 is ignoringEINTR, but returning an additional value.
  82  func ignoringEINTR2[T any](fn func() (T, error)) (T, error) {
  83  	for {
  84  		v, err := fn()
  85  		if err != syscall.EINTR {
  86  			return v, err
  87  		}
  88  	}
  89  }
  90