1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
package sys
import (
"io"
"os"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/fsapi"
"github.com/tetratelabs/wazero/internal/sysfs"
"github.com/tetratelabs/wazero/sys"
)
// StdinFile is a fs.ModeDevice file for use implementing FdStdin.
// This is safer than reading from os.DevNull as it can never overrun
// operating system file descriptors.
type StdinFile struct {
noopStdinFile
io.Reader
}
// Read implements the same method as documented on sys.File
func (f *StdinFile) Read(buf []byte) (int, experimentalsys.Errno) {
n, err := f.Reader.Read(buf)
return n, experimentalsys.UnwrapOSError(err)
}
type writerFile struct {
noopStdoutFile
w io.Writer
}
// Write implements the same method as documented on sys.File
func (f *writerFile) Write(buf []byte) (int, experimentalsys.Errno) {
n, err := f.w.Write(buf)
return n, experimentalsys.UnwrapOSError(err)
}
// noopStdinFile is a fs.ModeDevice file for use implementing FdStdin. This is
// safer than reading from os.DevNull as it can never overrun operating system
// file descriptors.
type noopStdinFile struct {
noopStdioFile
}
// Read implements the same method as documented on sys.File
func (noopStdinFile) Read([]byte) (int, experimentalsys.Errno) {
return 0, 0 // Always EOF
}
// Poll implements the same method as documented on fsapi.File
func (noopStdinFile) Poll(flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) {
if flag != fsapi.POLLIN {
return false, experimentalsys.ENOTSUP
}
return true, 0 // always ready to read nothing
}
// noopStdoutFile is a fs.ModeDevice file for use implementing FdStdout and
// FdStderr.
type noopStdoutFile struct {
noopStdioFile
}
// Write implements the same method as documented on sys.File
func (noopStdoutFile) Write(buf []byte) (int, experimentalsys.Errno) {
return len(buf), 0 // same as io.Discard
}
type noopStdioFile struct {
experimentalsys.UnimplementedFile
}
// Stat implements the same method as documented on sys.File
func (noopStdioFile) Stat() (sys.Stat_t, experimentalsys.Errno) {
return sys.Stat_t{Mode: modeDevice, Nlink: 1}, 0
}
// IsDir implements the same method as documented on sys.File
func (noopStdioFile) IsDir() (bool, experimentalsys.Errno) {
return false, 0
}
// Close implements the same method as documented on sys.File
func (noopStdioFile) Close() (errno experimentalsys.Errno) { return }
// IsNonblock implements the same method as documented on fsapi.File
func (noopStdioFile) IsNonblock() bool {
return false
}
// SetNonblock implements the same method as documented on fsapi.File
func (noopStdioFile) SetNonblock(bool) experimentalsys.Errno {
return experimentalsys.ENOSYS
}
// Poll implements the same method as documented on fsapi.File
func (noopStdioFile) Poll(fsapi.Pflag, int32) (ready bool, errno experimentalsys.Errno) {
return false, experimentalsys.ENOSYS
}
func stdinFileEntry(r io.Reader) (*FileEntry, error) {
if r == nil {
return &FileEntry{Name: "stdin", IsPreopen: true, File: &noopStdinFile{}}, nil
} else if f, ok := r.(*os.File); ok {
if f, err := sysfs.NewStdioFile(true, f); err != nil {
return nil, err
} else {
return &FileEntry{Name: "stdin", IsPreopen: true, File: f}, nil
}
} else {
return &FileEntry{Name: "stdin", IsPreopen: true, File: &StdinFile{Reader: r}}, nil
}
}
func stdioWriterFileEntry(name string, w io.Writer) (*FileEntry, error) {
if w == nil {
return &FileEntry{Name: name, IsPreopen: true, File: &noopStdoutFile{}}, nil
} else if f, ok := w.(*os.File); ok {
if f, err := sysfs.NewStdioFile(false, f); err != nil {
return nil, err
} else {
return &FileEntry{Name: name, IsPreopen: true, File: f}, nil
}
} else {
return &FileEntry{Name: name, IsPreopen: true, File: &writerFile{w: w}}, nil
}
}
|