github.com/bir3/gocompiler@v0.9.2202/src/internal/poll/fd_unixjs.go (about) 1 // Copyright 2023 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) 6 7 package poll 8 9 import "syscall" 10 11 type SysFile struct { 12 // Writev cache. 13 iovecs *[]syscall.Iovec 14 } 15 16 func (s *SysFile) init() {} 17 18 func (s *SysFile) destroy(fd int) error { 19 // We don't use ignoringEINTR here because POSIX does not define 20 // whether the descriptor is closed if close returns EINTR. 21 // If the descriptor is indeed closed, using a loop would race 22 // with some other goroutine opening a new descriptor. 23 // (The Linux kernel guarantees that it is closed on an EINTR error.) 24 return CloseFunc(fd) 25 } 26 27 // dupCloseOnExecOld is the traditional way to dup an fd and 28 // set its O_CLOEXEC bit, using two system calls. 29 func dupCloseOnExecOld(fd int) (int, string, error) { 30 syscall.ForkLock.RLock() 31 defer syscall.ForkLock.RUnlock() 32 newfd, err := syscall.Dup(fd) 33 if err != nil { 34 return -1, "dup", err 35 } 36 syscall.CloseOnExec(newfd) 37 return newfd, "", nil 38 } 39 40 // Fchdir wraps syscall.Fchdir. 41 func (fd *FD) Fchdir() error { 42 if err := fd.incref(); err != nil { 43 return err 44 } 45 defer fd.decref() 46 return syscall.Fchdir(fd.Sysfd) 47 } 48 49 // ReadDirent wraps syscall.ReadDirent. 50 // We treat this like an ordinary system call rather than a call 51 // that tries to fill the buffer. 52 func (fd *FD) ReadDirent(buf []byte) (int, error) { 53 if err := fd.incref(); err != nil { 54 return 0, err 55 } 56 defer fd.decref() 57 for { 58 n, err := ignoringEINTRIO(syscall.ReadDirent, fd.Sysfd, buf) 59 if err != nil { 60 n = 0 61 if err == syscall.EAGAIN && fd.pd.pollable() { 62 if err = fd.pd.waitRead(fd.isFile); err == nil { 63 continue 64 } 65 } 66 } 67 // Do not call eofError; caller does not expect to see io.EOF. 68 return n, err 69 } 70 } 71 72 // Seek wraps syscall.Seek. 73 func (fd *FD) Seek(offset int64, whence int) (int64, error) { 74 if err := fd.incref(); err != nil { 75 return 0, err 76 } 77 defer fd.decref() 78 return syscall.Seek(fd.Sysfd, offset, whence) 79 }