github.com/JimmyHuang454/JLS-go@v0.0.0-20230831150107-90d536585ba0/internal/poll/fd_posix.go (about) 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) || 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 }