github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/experimental/sys/file.go (about) 1 package sys 2 3 import "github.com/wasilibs/wazerox/sys" 4 5 // File is a writeable fs.File bridge backed by syscall functions needed for ABI 6 // including WASI and runtime.GOOS=js. 7 // 8 // Implementations should embed UnimplementedFile for forward compatability. Any 9 // unsupported method or parameter should return ENOSYS. 10 // 11 // # Errors 12 // 13 // All methods that can return an error return a Errno, which is zero 14 // on success. 15 // 16 // Restricting to Errno matches current WebAssembly host functions, 17 // which are constrained to well-known error codes. For example, `GOOS=js` maps 18 // hard coded values and panics otherwise. More commonly, WASI maps syscall 19 // errors to u32 numeric values. 20 // 21 // # Notes 22 // 23 // - You must call Close to avoid file resource conflicts. For example, 24 // Windows cannot delete the underlying directory while a handle to it 25 // remains open. 26 // - A writable filesystem abstraction is not yet implemented as of Go 1.20. 27 // See https://github.com/golang/go/issues/45757 28 type File interface { 29 // Dev returns the device ID (Stat_t.Dev) of this file, zero if unknown or 30 // an error retrieving it. 31 // 32 // # Errors 33 // 34 // Possible errors are those from Stat, except ENOSYS should not 35 // be returned. Zero should be returned if there is no implementation. 36 // 37 // # Notes 38 // 39 // - Implementations should cache this result. 40 // - This combined with Ino can implement os.SameFile. 41 Dev() (uint64, Errno) 42 43 // Ino returns the serial number (Stat_t.Ino) of this file, zero if unknown 44 // or an error retrieving it. 45 // 46 // # Errors 47 // 48 // Possible errors are those from Stat, except ENOSYS should not 49 // be returned. Zero should be returned if there is no implementation. 50 // 51 // # Notes 52 // 53 // - Implementations should cache this result. 54 // - This combined with Dev can implement os.SameFile. 55 Ino() (sys.Inode, Errno) 56 57 // IsDir returns true if this file is a directory or an error there was an 58 // error retrieving this information. 59 // 60 // # Errors 61 // 62 // Possible errors are those from Stat, except ENOSYS should not 63 // be returned. false should be returned if there is no implementation. 64 // 65 // # Notes 66 // 67 // - Implementations should cache this result. 68 IsDir() (bool, Errno) 69 70 // IsAppend returns true if the file was opened with O_APPEND, or 71 // SetAppend was successfully enabled on this file. 72 // 73 // # Notes 74 // 75 // - This might not match the underlying state of the file descriptor if 76 // the file was not opened via OpenFile. 77 IsAppend() bool 78 79 // SetAppend toggles the append mode (O_APPEND) of this file. 80 // 81 // # Errors 82 // 83 // A zero Errno is success. The below are expected otherwise: 84 // - ENOSYS: the implementation does not support this function. 85 // - EBADF: the file or directory was closed. 86 // 87 // # Notes 88 // 89 // - There is no `O_APPEND` for `fcntl` in POSIX, so implementations may 90 // have to re-open the underlying file to apply this. See 91 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html 92 SetAppend(enable bool) Errno 93 94 // Stat is similar to syscall.Fstat. 95 // 96 // # Errors 97 // 98 // A zero Errno is success. The below are expected otherwise: 99 // - ENOSYS: the implementation does not support this function. 100 // - EBADF: the file or directory was closed. 101 // 102 // # Notes 103 // 104 // - This is like syscall.Fstat and `fstatat` with `AT_FDCWD` in POSIX. 105 // See https://pubs.opengroup.org/onlinepubs/9699919799/functions/stat.html 106 // - A fs.FileInfo backed implementation sets atim, mtim and ctim to the 107 // same value. 108 // - Windows allows you to stat a closed directory. 109 Stat() (sys.Stat_t, Errno) 110 111 // Read attempts to read all bytes in the file into `buf`, and returns the 112 // count read even on error. 113 // 114 // # Errors 115 // 116 // A zero Errno is success. The below are expected otherwise: 117 // - ENOSYS: the implementation does not support this function. 118 // - EBADF: the file or directory was closed or not readable. 119 // - EISDIR: the file was a directory. 120 // 121 // # Notes 122 // 123 // - This is like io.Reader and `read` in POSIX, preferring semantics of 124 // io.Reader. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html 125 // - Unlike io.Reader, there is no io.EOF returned on end-of-file. To 126 // read the file completely, the caller must repeat until `n` is zero. 127 Read(buf []byte) (n int, errno Errno) 128 129 // Pread attempts to read all bytes in the file into `p`, starting at the 130 // offset `off`, and returns the count read even on error. 131 // 132 // # Errors 133 // 134 // A zero Errno is success. The below are expected otherwise: 135 // - ENOSYS: the implementation does not support this function. 136 // - EBADF: the file or directory was closed or not readable. 137 // - EINVAL: the offset was negative. 138 // - EISDIR: the file was a directory. 139 // 140 // # Notes 141 // 142 // - This is like io.ReaderAt and `pread` in POSIX, preferring semantics 143 // of io.ReaderAt. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html 144 // - Unlike io.ReaderAt, there is no io.EOF returned on end-of-file. To 145 // read the file completely, the caller must repeat until `n` is zero. 146 Pread(buf []byte, off int64) (n int, errno Errno) 147 148 // Seek attempts to set the next offset for Read or Write and returns the 149 // resulting absolute offset or an error. 150 // 151 // # Parameters 152 // 153 // The `offset` parameters is interpreted in terms of `whence`: 154 // - io.SeekStart: relative to the start of the file, e.g. offset=0 sets 155 // the next Read or Write to the beginning of the file. 156 // - io.SeekCurrent: relative to the current offset, e.g. offset=16 sets 157 // the next Read or Write 16 bytes past the prior. 158 // - io.SeekEnd: relative to the end of the file, e.g. offset=-1 sets the 159 // next Read or Write to the last byte in the file. 160 // 161 // # Behavior when a directory 162 // 163 // The only supported use case for a directory is seeking to `offset` zero 164 // (`whence` = io.SeekStart). This should have the same behavior as 165 // os.File, which resets any internal state used by Readdir. 166 // 167 // # Errors 168 // 169 // A zero Errno is success. The below are expected otherwise: 170 // - ENOSYS: the implementation does not support this function. 171 // - EBADF: the file or directory was closed or not readable. 172 // - EINVAL: the offset was negative. 173 // 174 // # Notes 175 // 176 // - This is like io.Seeker and `fseek` in POSIX, preferring semantics 177 // of io.Seeker. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/fseek.html 178 Seek(offset int64, whence int) (newOffset int64, errno Errno) 179 180 // Readdir reads the contents of the directory associated with file and 181 // returns a slice of up to n Dirent values in an arbitrary order. This is 182 // a stateful function, so subsequent calls return any next values. 183 // 184 // If n > 0, Readdir returns at most n entries or an error. 185 // If n <= 0, Readdir returns all remaining entries or an error. 186 // 187 // # Errors 188 // 189 // A zero Errno is success. The below are expected otherwise: 190 // - ENOSYS: the implementation does not support this function. 191 // - EBADF: the file was closed or not a directory. 192 // - ENOENT: the directory could not be read (e.g. deleted). 193 // 194 // # Notes 195 // 196 // - This is like `Readdir` on os.File, but unlike `readdir` in POSIX. 197 // See https://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html 198 // - Unlike os.File, there is no io.EOF returned on end-of-directory. To 199 // read the directory completely, the caller must repeat until the 200 // count read (`len(dirents)`) is less than `n`. 201 // - See /RATIONALE.md for design notes. 202 Readdir(n int) (dirents []Dirent, errno Errno) 203 204 // Write attempts to write all bytes in `p` to the file, and returns the 205 // count written even on error. 206 // 207 // # Errors 208 // 209 // A zero Errno is success. The below are expected otherwise: 210 // - ENOSYS: the implementation does not support this function. 211 // - EBADF: the file was closed, not writeable, or a directory. 212 // 213 // # Notes 214 // 215 // - This is like io.Writer and `write` in POSIX, preferring semantics of 216 // io.Writer. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html 217 Write(buf []byte) (n int, errno Errno) 218 219 // Pwrite attempts to write all bytes in `p` to the file at the given 220 // offset `off`, and returns the count written even on error. 221 // 222 // # Errors 223 // 224 // A zero Errno is success. The below are expected otherwise: 225 // - ENOSYS: the implementation does not support this function. 226 // - EBADF: the file or directory was closed or not writeable. 227 // - EINVAL: the offset was negative. 228 // - EISDIR: the file was a directory. 229 // 230 // # Notes 231 // 232 // - This is like io.WriterAt and `pwrite` in POSIX, preferring semantics 233 // of io.WriterAt. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html 234 Pwrite(buf []byte, off int64) (n int, errno Errno) 235 236 // Truncate truncates a file to a specified length. 237 // 238 // # Errors 239 // 240 // A zero Errno is success. The below are expected otherwise: 241 // - ENOSYS: the implementation does not support this function. 242 // - EBADF: the file or directory was closed. 243 // - EINVAL: the `size` is negative. 244 // - EISDIR: the file was a directory. 245 // 246 // # Notes 247 // 248 // - This is like syscall.Ftruncate and `ftruncate` in POSIX. See 249 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html 250 // - Windows does not error when calling Truncate on a closed file. 251 Truncate(size int64) Errno 252 253 // Sync synchronizes changes to the file. 254 // 255 // # Errors 256 // 257 // A zero Errno is success. The below are expected otherwise: 258 // - EBADF: the file or directory was closed. 259 // 260 // # Notes 261 // 262 // - This is like syscall.Fsync and `fsync` in POSIX. See 263 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html 264 // - This returns with no error instead of ENOSYS when 265 // unimplemented. This prevents fake filesystems from erring. 266 // - Windows does not error when calling Sync on a closed file. 267 Sync() Errno 268 269 // Datasync synchronizes the data of a file. 270 // 271 // # Errors 272 // 273 // A zero Errno is success. The below are expected otherwise: 274 // - EBADF: the file or directory was closed. 275 // 276 // # Notes 277 // 278 // - This is like syscall.Fdatasync and `fdatasync` in POSIX. See 279 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html 280 // - This returns with no error instead of ENOSYS when 281 // unimplemented. This prevents fake filesystems from erring. 282 // - As this is commonly missing, some implementations dispatch to Sync. 283 Datasync() Errno 284 285 // Utimens set file access and modification times of this file, at 286 // nanosecond precision. 287 // 288 // # Parameters 289 // 290 // The `atim` and `mtim` parameters refer to access and modification time 291 // stamps as defined in sys.Stat_t. To retain one or the other, substitute 292 // it with the pseudo-timestamp UTIME_OMIT. 293 // 294 // # Errors 295 // 296 // A zero Errno is success. The below are expected otherwise: 297 // - ENOSYS: the implementation does not support this function. 298 // - EBADF: the file or directory was closed. 299 // 300 // # Notes 301 // 302 // - This is like syscall.UtimesNano and `futimens` in POSIX. See 303 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html 304 // - Windows requires files to be open with O_RDWR, which means you 305 // cannot use this to update timestamps on a directory (EPERM). 306 Utimens(atim, mtim int64) Errno 307 308 // Close closes the underlying file. 309 // 310 // A zero Errno is returned if unimplemented or success. 311 // 312 // # Notes 313 // 314 // - This is like syscall.Close and `close` in POSIX. See 315 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html 316 Close() Errno 317 }