github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/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  // dupCloseOnExecOld is the traditional way to dup an fd and
    17  // set its O_CLOEXEC bit, using two system calls.
    18  func dupCloseOnExecOld(fd int) (int, string, error) {
    19  	syscall.ForkLock.RLock()
    20  	defer syscall.ForkLock.RUnlock()
    21  	newfd, err := syscall.Dup(fd)
    22  	if err != nil {
    23  		return -1, "dup", err
    24  	}
    25  	syscall.CloseOnExec(newfd)
    26  	return newfd, "", nil
    27  }
    28  
    29  // Fchdir wraps syscall.Fchdir.
    30  func (fd *FD) Fchdir() error {
    31  	if err := fd.incref(); err != nil {
    32  		return err
    33  	}
    34  	defer fd.decref()
    35  	return syscall.Fchdir(fd.Sysfd)
    36  }
    37  
    38  // ReadDirent wraps syscall.ReadDirent.
    39  // We treat this like an ordinary system call rather than a call
    40  // that tries to fill the buffer.
    41  func (fd *FD) ReadDirent(buf []byte) (int, error) {
    42  	if err := fd.incref(); err != nil {
    43  		return 0, err
    44  	}
    45  	defer fd.decref()
    46  	for {
    47  		n, err := ignoringEINTRIO(syscall.ReadDirent, fd.Sysfd, buf)
    48  		if err != nil {
    49  			n = 0
    50  			if err == syscall.EAGAIN && fd.pd.pollable() {
    51  				if err = fd.pd.waitRead(fd.isFile); err == nil {
    52  					continue
    53  				}
    54  			}
    55  		}
    56  		// Do not call eofError; caller does not expect to see io.EOF.
    57  		return n, err
    58  	}
    59  }
    60  
    61  // Seek wraps syscall.Seek.
    62  func (fd *FD) Seek(offset int64, whence int) (int64, error) {
    63  	if err := fd.incref(); err != nil {
    64  		return 0, err
    65  	}
    66  	defer fd.decref()
    67  	return syscall.Seek(fd.Sysfd, offset, whence)
    68  }