]> Cypherpunks.ru repositories - gostls13.git/blob - src/internal/poll/fd_unixjs.go
net: implement wasip1 FileListener and FileConn
[gostls13.git] / src / internal / poll / fd_unixjs.go
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 }