1package sysfs
2
3import (
4 "io/fs"
5
6 experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
7)
8
9type ReadFS struct {
10 experimentalsys.FS
11}
12
13// OpenFile implements the same method as documented on sys.FS
14func (r *ReadFS) OpenFile(path string, flag experimentalsys.Oflag, perm fs.FileMode) (experimentalsys.File, experimentalsys.Errno) {
15 // Mask the mutually exclusive bits as they determine write mode.
16 switch flag & (experimentalsys.O_RDONLY | experimentalsys.O_WRONLY | experimentalsys.O_RDWR) {
17 case experimentalsys.O_WRONLY, experimentalsys.O_RDWR:
18 // Return the correct error if a directory was opened for write.
19 if flag&experimentalsys.O_DIRECTORY != 0 {
20 return nil, experimentalsys.EISDIR
21 }
22 return nil, experimentalsys.ENOSYS
23 default: // sys.O_RDONLY (integer zero) so we are ok!
24 }
25
26 f, errno := r.FS.OpenFile(path, flag, perm)
27 if errno != 0 {
28 return nil, errno
29 }
30 return &readFile{f}, 0
31}
32
33// Mkdir implements the same method as documented on sys.FS
34func (r *ReadFS) Mkdir(path string, perm fs.FileMode) experimentalsys.Errno {
35 return experimentalsys.EROFS
36}
37
38// Chmod implements the same method as documented on sys.FS
39func (r *ReadFS) Chmod(path string, perm fs.FileMode) experimentalsys.Errno {
40 return experimentalsys.EROFS
41}
42
43// Rename implements the same method as documented on sys.FS
44func (r *ReadFS) Rename(from, to string) experimentalsys.Errno {
45 return experimentalsys.EROFS
46}
47
48// Rmdir implements the same method as documented on sys.FS
49func (r *ReadFS) Rmdir(path string) experimentalsys.Errno {
50 return experimentalsys.EROFS
51}
52
53// Link implements the same method as documented on sys.FS
54func (r *ReadFS) Link(_, _ string) experimentalsys.Errno {
55 return experimentalsys.EROFS
56}
57
58// Symlink implements the same method as documented on sys.FS
59func (r *ReadFS) Symlink(_, _ string) experimentalsys.Errno {
60 return experimentalsys.EROFS
61}
62
63// Unlink implements the same method as documented on sys.FS
64func (r *ReadFS) Unlink(path string) experimentalsys.Errno {
65 return experimentalsys.EROFS
66}
67
68// Utimens implements the same method as documented on sys.FS
69func (r *ReadFS) Utimens(path string, atim, mtim int64) experimentalsys.Errno {
70 return experimentalsys.EROFS
71}
72
73// compile-time check to ensure readFile implements api.File.
74var _ experimentalsys.File = (*readFile)(nil)
75
76type readFile struct {
77 experimentalsys.File
78}
79
80// Write implements the same method as documented on sys.File.
81func (r *readFile) Write([]byte) (int, experimentalsys.Errno) {
82 return 0, r.writeErr()
83}
84
85// Pwrite implements the same method as documented on sys.File.
86func (r *readFile) Pwrite([]byte, int64) (n int, errno experimentalsys.Errno) {
87 return 0, r.writeErr()
88}
89
90// Truncate implements the same method as documented on sys.File.
91func (r *readFile) Truncate(int64) experimentalsys.Errno {
92 return r.writeErr()
93}
94
95// Sync implements the same method as documented on sys.File.
96func (r *readFile) Sync() experimentalsys.Errno {
97 return experimentalsys.EBADF
98}
99
100// Datasync implements the same method as documented on sys.File.
101func (r *readFile) Datasync() experimentalsys.Errno {
102 return experimentalsys.EBADF
103}
104
105// Utimens implements the same method as documented on sys.File.
106func (r *readFile) Utimens(int64, int64) experimentalsys.Errno {
107 return experimentalsys.EBADF
108}
109
110func (r *readFile) writeErr() experimentalsys.Errno {
111 if isDir, errno := r.IsDir(); errno != 0 {
112 return errno
113 } else if isDir {
114 return experimentalsys.EISDIR
115 }
116 return experimentalsys.EBADF
117}