go.dedis.ch/onet/v3@v3.2.11-0.20210930124529-e36530bca7ef/simul/platform/fd_darwin.go (about)

     1  package platform
     2  
     3  import (
     4  	"syscall"
     5  
     6  	"go.dedis.ch/onet/v3/log"
     7  	"golang.org/x/sys/unix"
     8  	"golang.org/x/xerrors"
     9  )
    10  
    11  func init() {
    12  	var rLimit syscall.Rlimit
    13  	err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
    14  	if err != nil {
    15  		log.Fatal("Error Getting Rlimit ", err)
    16  	}
    17  
    18  	// We observed that with Go 1.11.5, we were getting
    19  	// 24576, and then with Go 1.12, we started getting "invalid argument".
    20  	// See https://github.com/golang/go/issues/30401
    21  
    22  	// On Darwin, the real fd max is given by sysctl.
    23  	res, err := unix.Sysctl("kern.maxfilesperproc")
    24  	if err != nil || len(res) != 3 {
    25  		// In case of error, fall back to something reasonable.
    26  		res = "10240"
    27  	}
    28  	// res is type string, but according to sysctl(3), it should be interpreted
    29  	// as an int32. It seems to be little-endian. And for some reason, there are only
    30  	// 3 bytes.
    31  	rLimit.Max = uint64(res[0]) | uint64(res[1])<<8 | uint64(res[2])<<16
    32  
    33  	if rLimit.Cur < rLimit.Max {
    34  		rLimit.Cur = rLimit.Max
    35  		err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit)
    36  		if err != nil {
    37  			log.Warn("Error Setting Rlimit:", err)
    38  		}
    39  	}
    40  
    41  	err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
    42  	log.Info("File descriptor limit is:", rLimit.Cur)
    43  }
    44  
    45  // CheckOutOfFileDescriptors tries to duplicate the stdout file descriptor
    46  // and throws an error if it cannot do it. This is a horrible hack mainly for
    47  // MacOSX where the file descriptor limit is quite low and we need to tell
    48  // people running simulations what they can do about it.
    49  func CheckOutOfFileDescriptors() error {
    50  	// Check if we're out of file descriptors
    51  	newFS, err := syscall.Dup(syscall.Stdout)
    52  	if err != nil {
    53  		return xerrors.New(`Out of file descriptors. You might want to do something like this for Mac OSX:
    54      sudo sysctl -w kern.maxfiles=122880
    55      sudo sysctl -w kern.maxfilesperproc=102400
    56      sudo sysctl -w kern.ipc.somaxconn=20480`)
    57  	}
    58  	if err = syscall.Close(newFS); err != nil {
    59  		return xerrors.New("Couldn't close new file descriptor: " + err.Error())
    60  	}
    61  	return nil
    62  }