package  pollimport  (	"internal/itoa" 	"internal/syscall/unix" 	"io" 	"sync/atomic" 	"syscall" )type  FD  struct  {		fdmu  fdMutex 		Sysfd  int 		SysFile 		pd  pollDesc 		csema  uint32 		isBlocking  uint32 		IsStream  bool 		ZeroReadIsEOF  bool 		isFile  bool }func  (fd  *FD ) Init net  string , pollable  bool ) error  {	fd .SysFile .init ()		if  net  == "file"  {		fd .isFile  = true 	}	if  !pollable  {		fd .isBlocking  = 1 		return  nil 	}	err  := fd .pd .init (fd )	if  err  != nil  {				fd .isBlocking  = 1 	}	return  err }func  (fd  *FD ) destroy error  {		fd .pd .close ()	err  := fd .SysFile .destroy (fd .Sysfd )	fd .Sysfd  = -1 	runtime_Semrelease (&fd .csema )	return  err }func  (fd  *FD ) Close error  {	if  !fd .fdmu .increfAndClose () {		return  errClosing (fd .isFile )	}		fd .pd .evict ()		err  := fd .decref ()		if  fd .isBlocking  == 0  {		runtime_Semacquire (&fd .csema )	}	return  err }func  (fd  *FD ) SetBlocking error  {	if  err  := fd .incref (); err  != nil  {		return  err 	}	defer  fd .decref ()		atomic .StoreUint32 (&fd .isBlocking , 1 )	return  syscall .SetNonblock (fd .Sysfd , false )}const  maxRW  = 1  << 30 func  (fd  *FD ) Read p  []byte ) (int , error ) {	if  err  := fd .readLock (); err  != nil  {		return  0 , err 	}	defer  fd .readUnlock ()	if  len (p ) == 0  {				return  0 , nil 	}	if  err  := fd .pd .prepareRead (fd .isFile ); err  != nil  {		return  0 , err 	}	if  fd .IsStream  && len (p ) > maxRW  {		p  = p [:maxRW ]	}	for  {		n , err  := ignoringEINTRIO (syscall .Read , fd .Sysfd , p )		if  err  != nil  {			n  = 0 			if  err  == syscall .EAGAIN  && fd .pd .pollable () {				if  err  = fd .pd .waitRead (fd .isFile ); err  == nil  {					continue 				}			}		}		err  = fd .eofError (n , err )		return  n , err 	}}func  (fd  *FD ) Pread p  []byte , off  int64 ) (int , error ) {		if  err  := fd .incref (); err  != nil  {		return  0 , err 	}	if  fd .IsStream  && len (p ) > maxRW  {		p  = p [:maxRW ]	}	var  (		n    int 		err  error 	)	for  {		n , err  = syscall .Pread (fd .Sysfd , p , off )		if  err  != syscall .EINTR  {			break 		}	}	if  err  != nil  {		n  = 0 	}	fd .decref ()	err  = fd .eofError (n , err )	return  n , err }func  (fd  *FD ) ReadFrom p  []byte ) (int , syscall .Sockaddr , error ) {	if  err  := fd .readLock (); err  != nil  {		return  0 , nil , err 	}	defer  fd .readUnlock ()	if  err  := fd .pd .prepareRead (fd .isFile ); err  != nil  {		return  0 , nil , err 	}	for  {		n , sa , err  := syscall .Recvfrom (fd .Sysfd , p , 0 )		if  err  != nil  {			if  err  == syscall .EINTR  {				continue 			}			n  = 0 			if  err  == syscall .EAGAIN  && fd .pd .pollable () {				if  err  = fd .pd .waitRead (fd .isFile ); err  == nil  {					continue 				}			}		}		err  = fd .eofError (n , err )		return  n , sa , err 	}}func  (fd  *FD ) ReadFromInet4 p  []byte , from  *syscall .SockaddrInet4 ) (int , error ) {	if  err  := fd .readLock (); err  != nil  {		return  0 , err 	}	defer  fd .readUnlock ()	if  err  := fd .pd .prepareRead (fd .isFile ); err  != nil  {		return  0 , err 	}	for  {		n , err  := unix .RecvfromInet4 (fd .Sysfd , p , 0 , from )		if  err  != nil  {			if  err  == syscall .EINTR  {				continue 			}			n  = 0 			if  err  == syscall .EAGAIN  && fd .pd .pollable () {				if  err  = fd .pd .waitRead (fd .isFile ); err  == nil  {					continue 				}			}		}		err  = fd .eofError (n , err )		return  n , err 	}}func  (fd  *FD ) ReadFromInet6 p  []byte , from  *syscall .SockaddrInet6 ) (int , error ) {	if  err  := fd .readLock (); err  != nil  {		return  0 , err 	}	defer  fd .readUnlock ()	if  err  := fd .pd .prepareRead (fd .isFile ); err  != nil  {		return  0 , err 	}	for  {		n , err  := unix .RecvfromInet6 (fd .Sysfd , p , 0 , from )		if  err  != nil  {			if  err  == syscall .EINTR  {				continue 			}			n  = 0 			if  err  == syscall .EAGAIN  && fd .pd .pollable () {				if  err  = fd .pd .waitRead (fd .isFile ); err  == nil  {					continue 				}			}		}		err  = fd .eofError (n , err )		return  n , err 	}}func  (fd  *FD ) ReadMsg p  []byte , oob  []byte , flags  int ) (int , int , int , syscall .Sockaddr , error ) {	if  err  := fd .readLock (); err  != nil  {		return  0 , 0 , 0 , nil , err 	}	defer  fd .readUnlock ()	if  err  := fd .pd .prepareRead (fd .isFile ); err  != nil  {		return  0 , 0 , 0 , nil , err 	}	for  {		n , oobn , sysflags , sa , err  := syscall .Recvmsg (fd .Sysfd , p , oob , flags )		if  err  != nil  {			if  err  == syscall .EINTR  {				continue 			}						if  err  == syscall .EAGAIN  && fd .pd .pollable () {				if  err  = fd .pd .waitRead (fd .isFile ); err  == nil  {					continue 				}			}		}		err  = fd .eofError (n , err )		return  n , oobn , sysflags , sa , err 	}}func  (fd  *FD ) ReadMsgInet4 p  []byte , oob  []byte , flags  int , sa4  *syscall .SockaddrInet4 ) (int , int , int , error ) {	if  err  := fd .readLock (); err  != nil  {		return  0 , 0 , 0 , err 	}	defer  fd .readUnlock ()	if  err  := fd .pd .prepareRead (fd .isFile ); err  != nil  {		return  0 , 0 , 0 , err 	}	for  {		n , oobn , sysflags , err  := unix .RecvmsgInet4 (fd .Sysfd , p , oob , flags , sa4 )		if  err  != nil  {			if  err  == syscall .EINTR  {				continue 			}						if  err  == syscall .EAGAIN  && fd .pd .pollable () {				if  err  = fd .pd .waitRead (fd .isFile ); err  == nil  {					continue 				}			}		}		err  = fd .eofError (n , err )		return  n , oobn , sysflags , err 	}}func  (fd  *FD ) ReadMsgInet6 p  []byte , oob  []byte , flags  int , sa6  *syscall .SockaddrInet6 ) (int , int , int , error ) {	if  err  := fd .readLock (); err  != nil  {		return  0 , 0 , 0 , err 	}	defer  fd .readUnlock ()	if  err  := fd .pd .prepareRead (fd .isFile ); err  != nil  {		return  0 , 0 , 0 , err 	}	for  {		n , oobn , sysflags , err  := unix .RecvmsgInet6 (fd .Sysfd , p , oob , flags , sa6 )		if  err  != nil  {			if  err  == syscall .EINTR  {				continue 			}						if  err  == syscall .EAGAIN  && fd .pd .pollable () {				if  err  = fd .pd .waitRead (fd .isFile ); err  == nil  {					continue 				}			}		}		err  = fd .eofError (n , err )		return  n , oobn , sysflags , err 	}}func  (fd  *FD ) Write p  []byte ) (int , error ) {	if  err  := fd .writeLock (); err  != nil  {		return  0 , err 	}	defer  fd .writeUnlock ()	if  err  := fd .pd .prepareWrite (fd .isFile ); err  != nil  {		return  0 , err 	}	var  nn  int 	for  {		max  := len (p )		if  fd .IsStream  && max -nn  > maxRW  {			max  = nn  + maxRW 		}		n , err  := ignoringEINTRIO (syscall .Write , fd .Sysfd , p [nn :max ])		if  n  > 0  {			if  n  > max -nn  {								panic ("invalid return from write: got "  + itoa .Itoa (n ) + " from a write of "  + itoa .Itoa (max -nn ))			}			nn  += n 		}		if  nn  == len (p ) {			return  nn , err 		}		if  err  == syscall .EAGAIN  && fd .pd .pollable () {			if  err  = fd .pd .waitWrite (fd .isFile ); err  == nil  {				continue 			}		}		if  err  != nil  {			return  nn , err 		}		if  n  == 0  {			return  nn , io .ErrUnexpectedEOF 		}	}}func  (fd  *FD ) Pwrite p  []byte , off  int64 ) (int , error ) {		if  err  := fd .incref (); err  != nil  {		return  0 , err 	}	defer  fd .decref ()	var  nn  int 	for  {		max  := len (p )		if  fd .IsStream  && max -nn  > maxRW  {			max  = nn  + maxRW 		}		n , err  := syscall .Pwrite (fd .Sysfd , p [nn :max ], off +int64 (nn ))		if  err  == syscall .EINTR  {			continue 		}		if  n  > 0  {			nn  += n 		}		if  nn  == len (p ) {			return  nn , err 		}		if  err  != nil  {			return  nn , err 		}		if  n  == 0  {			return  nn , io .ErrUnexpectedEOF 		}	}}func  (fd  *FD ) WriteToInet4 p  []byte , sa  *syscall .SockaddrInet4 ) (int , error ) {	if  err  := fd .writeLock (); err  != nil  {		return  0 , err 	}	defer  fd .writeUnlock ()	if  err  := fd .pd .prepareWrite (fd .isFile ); err  != nil  {		return  0 , err 	}	for  {		err  := unix .SendtoInet4 (fd .Sysfd , p , 0 , sa )		if  err  == syscall .EINTR  {			continue 		}		if  err  == syscall .EAGAIN  && fd .pd .pollable () {			if  err  = fd .pd .waitWrite (fd .isFile ); err  == nil  {				continue 			}		}		if  err  != nil  {			return  0 , err 		}		return  len (p ), nil 	}}func  (fd  *FD ) WriteToInet6 p  []byte , sa  *syscall .SockaddrInet6 ) (int , error ) {	if  err  := fd .writeLock (); err  != nil  {		return  0 , err 	}	defer  fd .writeUnlock ()	if  err  := fd .pd .prepareWrite (fd .isFile ); err  != nil  {		return  0 , err 	}	for  {		err  := unix .SendtoInet6 (fd .Sysfd , p , 0 , sa )		if  err  == syscall .EINTR  {			continue 		}		if  err  == syscall .EAGAIN  && fd .pd .pollable () {			if  err  = fd .pd .waitWrite (fd .isFile ); err  == nil  {				continue 			}		}		if  err  != nil  {			return  0 , err 		}		return  len (p ), nil 	}}func  (fd  *FD ) WriteTo p  []byte , sa  syscall .Sockaddr ) (int , error ) {	if  err  := fd .writeLock (); err  != nil  {		return  0 , err 	}	defer  fd .writeUnlock ()	if  err  := fd .pd .prepareWrite (fd .isFile ); err  != nil  {		return  0 , err 	}	for  {		err  := syscall .Sendto (fd .Sysfd , p , 0 , sa )		if  err  == syscall .EINTR  {			continue 		}		if  err  == syscall .EAGAIN  && fd .pd .pollable () {			if  err  = fd .pd .waitWrite (fd .isFile ); err  == nil  {				continue 			}		}		if  err  != nil  {			return  0 , err 		}		return  len (p ), nil 	}}func  (fd  *FD ) WriteMsg p  []byte , oob  []byte , sa  syscall .Sockaddr ) (int , int , error ) {	if  err  := fd .writeLock (); err  != nil  {		return  0 , 0 , err 	}	defer  fd .writeUnlock ()	if  err  := fd .pd .prepareWrite (fd .isFile ); err  != nil  {		return  0 , 0 , err 	}	for  {		n , err  := syscall .SendmsgN (fd .Sysfd , p , oob , sa , 0 )		if  err  == syscall .EINTR  {			continue 		}		if  err  == syscall .EAGAIN  && fd .pd .pollable () {			if  err  = fd .pd .waitWrite (fd .isFile ); err  == nil  {				continue 			}		}		if  err  != nil  {			return  n , 0 , err 		}		return  n , len (oob ), err 	}}func  (fd  *FD ) WriteMsgInet4 p  []byte , oob  []byte , sa  *syscall .SockaddrInet4 ) (int , int , error ) {	if  err  := fd .writeLock (); err  != nil  {		return  0 , 0 , err 	}	defer  fd .writeUnlock ()	if  err  := fd .pd .prepareWrite (fd .isFile ); err  != nil  {		return  0 , 0 , err 	}	for  {		n , err  := unix .SendmsgNInet4 (fd .Sysfd , p , oob , sa , 0 )		if  err  == syscall .EINTR  {			continue 		}		if  err  == syscall .EAGAIN  && fd .pd .pollable () {			if  err  = fd .pd .waitWrite (fd .isFile ); err  == nil  {				continue 			}		}		if  err  != nil  {			return  n , 0 , err 		}		return  n , len (oob ), err 	}}func  (fd  *FD ) WriteMsgInet6 p  []byte , oob  []byte , sa  *syscall .SockaddrInet6 ) (int , int , error ) {	if  err  := fd .writeLock (); err  != nil  {		return  0 , 0 , err 	}	defer  fd .writeUnlock ()	if  err  := fd .pd .prepareWrite (fd .isFile ); err  != nil  {		return  0 , 0 , err 	}	for  {		n , err  := unix .SendmsgNInet6 (fd .Sysfd , p , oob , sa , 0 )		if  err  == syscall .EINTR  {			continue 		}		if  err  == syscall .EAGAIN  && fd .pd .pollable () {			if  err  = fd .pd .waitWrite (fd .isFile ); err  == nil  {				continue 			}		}		if  err  != nil  {			return  n , 0 , err 		}		return  n , len (oob ), err 	}}func  (fd  *FD ) Accept int , syscall .Sockaddr , string , error ) {	if  err  := fd .readLock (); err  != nil  {		return  -1 , nil , "" , err 	}	defer  fd .readUnlock ()	if  err  := fd .pd .prepareRead (fd .isFile ); err  != nil  {		return  -1 , nil , "" , err 	}	for  {		s , rsa , errcall , err  := accept (fd .Sysfd )		if  err  == nil  {			return  s , rsa , "" , err 		}		switch  err  {		case  syscall .EINTR :			continue 		case  syscall .EAGAIN :			if  fd .pd .pollable () {				if  err  = fd .pd .waitRead (fd .isFile ); err  == nil  {					continue 				}			}		case  syscall .ECONNABORTED :						continue 		}		return  -1 , nil , errcall , err 	}}func  (fd  *FD ) Fchmod mode  uint32 ) error  {	if  err  := fd .incref (); err  != nil  {		return  err 	}	defer  fd .decref ()	return  ignoringEINTR (func () error  {		return  syscall .Fchmod (fd .Sysfd , mode )	})}func  (fd  *FD ) Fstat s  *syscall .Stat_t ) error  {	if  err  := fd .incref (); err  != nil  {		return  err 	}	defer  fd .decref ()	return  ignoringEINTR (func () error  {		return  syscall .Fstat (fd .Sysfd , s )	})}var  dupCloexecUnsupported  atomic .Bool func  DupCloseOnExec fd  int ) (int , string , error ) {	if  syscall .F_DUPFD_CLOEXEC  != 0  && !dupCloexecUnsupported .Load () {		r0 , err  := unix .Fcntl (fd , syscall .F_DUPFD_CLOEXEC , 0 )		if  err  == nil  {			return  r0 , "" , nil 		}		switch  err  {		case  syscall .EINVAL , syscall .ENOSYS :						dupCloexecUnsupported .Store (true )		default :			return  -1 , "fcntl" , err 		}	}	return  dupCloseOnExecOld (fd )}func  (fd  *FD ) Dup int , string , error ) {	if  err  := fd .incref (); err  != nil  {		return  -1 , "" , err 	}	defer  fd .decref ()	return  DupCloseOnExec (fd .Sysfd )}func  (fd  *FD ) WaitWrite error  {	return  fd .pd .waitWrite (fd .isFile )}func  (fd  *FD ) WriteOnce p  []byte ) (int , error ) {	if  err  := fd .writeLock (); err  != nil  {		return  0 , err 	}	defer  fd .writeUnlock ()	return  ignoringEINTRIO (syscall .Write , fd .Sysfd , p )}func  (fd  *FD ) RawRead f  func (uintptr ) bool ) error  {	if  err  := fd .readLock (); err  != nil  {		return  err 	}	defer  fd .readUnlock ()	if  err  := fd .pd .prepareRead (fd .isFile ); err  != nil  {		return  err 	}	for  {		if  f (uintptr (fd .Sysfd )) {			return  nil 		}		if  err  := fd .pd .waitRead (fd .isFile ); err  != nil  {			return  err 		}	}}func  (fd  *FD ) RawWrite f  func (uintptr ) bool ) error  {	if  err  := fd .writeLock (); err  != nil  {		return  err 	}	defer  fd .writeUnlock ()	if  err  := fd .pd .prepareWrite (fd .isFile ); err  != nil  {		return  err 	}	for  {		if  f (uintptr (fd .Sysfd )) {			return  nil 		}		if  err  := fd .pd .waitWrite (fd .isFile ); err  != nil  {			return  err 		}	}}func  ignoringEINTRIO fn  func (fd  int , p  []byte ) (int , error ), fd  int , p  []byte ) (int , error ) {	for  {		n , err  := fn (fd , p )		if  err  != syscall .EINTR  {			return  n , err 		}	}} The pages are generated with Golds v0.7.6 . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .