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