src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/sys/eunix/waitforread.go (about)

     1  //go:build unix
     2  
     3  package eunix
     4  
     5  import (
     6  	"os"
     7  	"time"
     8  
     9  	"golang.org/x/sys/unix"
    10  )
    11  
    12  // WaitForRead blocks until any of the given files is ready to be read or
    13  // timeout. A negative timeout means no timeout. It returns a boolean array
    14  // indicating which files are ready to be read and any possible error.
    15  func WaitForRead(timeout time.Duration, files ...*os.File) (ready []bool, err error) {
    16  	maxfd := 0
    17  	fdset := &unix.FdSet{}
    18  	for _, file := range files {
    19  		fd := int(file.Fd())
    20  		if maxfd < fd {
    21  			maxfd = fd
    22  		}
    23  		fdset.Set(fd)
    24  	}
    25  	_, err = unix.Select(maxfd+1, fdset, nil, nil, optionalTimeval(timeout))
    26  	ready = make([]bool, len(files))
    27  	for i, file := range files {
    28  		ready[i] = fdset.IsSet(int(file.Fd()))
    29  	}
    30  	return ready, err
    31  }
    32  
    33  func optionalTimeval(d time.Duration) *unix.Timeval {
    34  	if d < 0 {
    35  		return nil
    36  	}
    37  	timeval := unix.NsecToTimeval(int64(d))
    38  	return &timeval
    39  }