1;; WASI Preview. This is an evolution of the API that WASI initially
2;; launched with.
3;;
4;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi).
5;;
6;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/tree/master/docs/witx.md)
7;; for an explanation of what that means.
8
9(use "typenames.witx")
10
11;;; This API predated the convention of naming modules with a `wasi_unstable_`
12;;; prefix and a version number. It is preserved here for compatibility, but
13;;; we shouldn't follow this pattern in new APIs.
14(module $wasi_unstable
15  ;;; Linear memory to be accessed by WASI functions that need it.
16  (import "memory" (memory))
17
18  ;;; Read command-line argument data.
19  ;;; The size of the array should match that returned by `args_sizes_get`
20  (@interface func (export "args_get")
21    (param $argv (@witx pointer (@witx pointer u8)))
22    (param $argv_buf (@witx pointer u8))
23    (result $error $errno)
24  )
25  ;;; Return command-line argument data sizes.
26  (@interface func (export "args_sizes_get")
27    (result $error $errno)
28    ;;; The number of arguments.
29    (result $argc $size)
30    ;;; The size of the argument string data.
31    (result $argv_buf_size $size)
32  )
33
34  ;;; Read environment variable data.
35  ;;; The sizes of the buffers should match that returned by `environ_sizes_get`.
36  (@interface func (export "environ_get")
37    (param $environ (@witx pointer (@witx pointer u8)))
38    (param $environ_buf (@witx pointer u8))
39    (result $error $errno)
40  )
41  ;;; Return environment variable data sizes.
42  (@interface func (export "environ_sizes_get")
43    (result $error $errno)
44    ;;; The number of environment variable arguments.
45    (result $environc $size)
46    ;;; The size of the environment variable data.
47    (result $environ_buf_size $size)
48  )
49
50  ;;; Return the resolution of a clock.
51  ;;; Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return
52  ;;; `errno::inval`.
53  ;;; Note: This is similar to `clock_getres` in POSIX.
54  (@interface func (export "clock_res_get")
55    ;;; The clock for which to return the resolution.
56    (param $id $clockid)
57    (result $error $errno)
58    ;;; The resolution of the clock.
59    (result $resolution $timestamp)
60  )
61  ;;; Return the time value of a clock.
62  ;;; Note: This is similar to `clock_gettime` in POSIX.
63  (@interface func (export "clock_time_get")
64    ;;; The clock for which to return the time.
65    (param $id $clockid)
66    ;;; The maximum lag (exclusive) that the returned time value may have, compared to its actual value.
67    (param $precision $timestamp)
68    (result $error $errno)
69    ;;; The time value of the clock.
70    (result $time $timestamp)
71  )
72
73  ;;; Provide file advisory information on a file descriptor.
74  ;;; Note: This is similar to `posix_fadvise` in POSIX.
75  (@interface func (export "fd_advise")
76    (param $fd $fd)
77    ;;; The offset within the file to which the advisory applies.
78    (param $offset $filesize)
79    ;;; The length of the region to which the advisory applies.
80    (param $len $filesize)
81    ;;; The advice.
82    (param $advice $advice)
83    (result $error $errno)
84  )
85
86  ;;; Force the allocation of space in a file.
87  ;;; Note: This is similar to `posix_fallocate` in POSIX.
88  (@interface func (export "fd_allocate")
89    (param $fd $fd)
90    ;;; The offset at which to start the allocation.
91    (param $offset $filesize)
92    ;;; The length of the area that is allocated.
93    (param $len $filesize)
94    (result $error $errno)
95  )
96
97  ;;; Close a file descriptor.
98  ;;; Note: This is similar to `close` in POSIX.
99  (@interface func (export "fd_close")
100    (param $fd $fd)
101    (result $error $errno)
102  )
103
104  ;;; Synchronize the data of a file to disk.
105  ;;; Note: This is similar to `fdatasync` in POSIX.
106  (@interface func (export "fd_datasync")
107    (param $fd $fd)
108    (result $error $errno)
109  )
110
111  ;;; Get the attributes of a file descriptor.
112  ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields.
113  (@interface func (export "fd_fdstat_get")
114    (param $fd $fd)
115    (result $error $errno)
116    ;;; The buffer where the file descriptor's attributes are stored.
117    (result $stat $fdstat)
118  )
119
120  ;;; Adjust the flags associated with a file descriptor.
121  ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX.
122  (@interface func (export "fd_fdstat_set_flags")
123    (param $fd $fd)
124    ;;; The desired values of the file descriptor flags.
125    (param $flags $fdflags)
126    (result $error $errno)
127  )
128
129  ;;; Adjust the rights associated with a file descriptor.
130  ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights
131  (@interface func (export "fd_fdstat_set_rights")
132    (param $fd $fd)
133    ;;; The desired rights of the file descriptor.
134    (param $fs_rights_base $rights)
135    (param $fs_rights_inheriting $rights)
136    (result $error $errno)
137  )
138
139  ;;; Return the attributes of an open file.
140  (@interface func (export "fd_filestat_get")
141    (param $fd $fd)
142    (result $error $errno)
143    ;;; The buffer where the file's attributes are stored.
144    (result $buf $filestat)
145  )
146
147  ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
148  ;;; Note: This is similar to `ftruncate` in POSIX.
149  (@interface func (export "fd_filestat_set_size")
150    (param $fd $fd)
151    ;;; The desired file size.
152    (param $size $filesize)
153    (result $error $errno)
154  )
155
156  ;;; Adjust the timestamps of an open file or directory.
157  ;;; Note: This is similar to `futimens` in POSIX.
158  (@interface func (export "fd_filestat_set_times")
159    (param $fd $fd)
160    ;;; The desired values of the data access timestamp.
161    (param $atim $timestamp)
162    ;;; The desired values of the data modification timestamp.
163    (param $mtim $timestamp)
164    ;;; A bitmask indicating which timestamps to adjust.
165    (param $fst_flags $fstflags)
166    (result $error $errno)
167  )
168
169  ;;; Read from a file descriptor, without using and updating the file descriptor's offset.
170  ;;; Note: This is similar to `preadv` in POSIX.
171  (@interface func (export "fd_pread")
172    (param $fd $fd)
173    ;;; List of scatter/gather vectors in which to store data.
174    (param $iovs $iovec_array)
175    ;;; The offset within the file at which to read.
176    (param $offset $filesize)
177    (result $error $errno)
178    ;;; The number of bytes read.
179    (result $nread $size)
180  )
181
182  ;;; Return a description of the given preopened file descriptor.
183  (@interface func (export "fd_prestat_get")
184    (param $fd $fd)
185    (result $error $errno)
186    ;;; The buffer where the description is stored.
187    (result $buf $prestat)
188  )
189
190  ;;; Return a description of the given preopened file descriptor.
191  (@interface func (export "fd_prestat_dir_name")
192    (param $fd $fd)
193    ;;; A buffer into which to write the preopened directory name.
194    (param $path (@witx pointer u8))
195    (param $path_len $size)
196    (result $error $errno)
197  )
198
199  ;;; Write to a file descriptor, without using and updating the file descriptor's offset.
200  ;;; Note: This is similar to `pwritev` in POSIX.
201  (@interface func (export "fd_pwrite")
202    (param $fd $fd)
203    ;;; List of scatter/gather vectors from which to retrieve data.
204    (param $iovs $ciovec_array)
205    ;;; The offset within the file at which to write.
206    (param $offset $filesize)
207    (result $error $errno)
208    ;;; The number of bytes written.
209    (result $nwritten $size)
210  )
211
212  ;;; Read from a file descriptor.
213  ;;; Note: This is similar to `readv` in POSIX.
214  (@interface func (export "fd_read")
215    (param $fd $fd)
216    ;;; List of scatter/gather vectors to which to store data.
217    (param $iovs $iovec_array)
218    (result $error $errno)
219    ;;; The number of bytes read.
220    (result $nread $size)
221  )
222
223  ;;; Read directory entries from a directory.
224  ;;; When successful, the contents of the output buffer consist of a sequence of
225  ;;; directory entries. Each directory entry consists of a dirent_t object,
226  ;;; followed by dirent_t::d_namlen bytes holding the name of the directory
227  ;;; entry.
228  ;;
229  ;;; This function fills the output buffer as much as possible, potentially
230  ;;; truncating the last directory entry. This allows the caller to grow its
231  ;;; read buffer size in case it's too small to fit a single large directory
232  ;;; entry, or skip the oversized directory entry.
233  (@interface func (export "fd_readdir")
234    (param $fd $fd)
235    ;;; The buffer where directory entries are stored
236    (param $buf (@witx pointer u8))
237    (param $buf_len $size)
238    ;;; The location within the directory to start reading
239    (param $cookie $dircookie)
240    (result $error $errno)
241    ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.
242    (result $bufused $size)
243  )
244
245  ;;; Atomically replace a file descriptor by renumbering another file descriptor.
246  ;;
247  ;;; Due to the strong focus on thread safety, this environment does not provide
248  ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary
249  ;;; number, like `dup2()`. This would be prone to race conditions, as an actual
250  ;;; file descriptor with the same number could be allocated by a different
251  ;;; thread at the same time.
252  ;;
253  ;;; This function provides a way to atomically renumber file descriptors, which
254  ;;; would disappear if `dup2()` were to be removed entirely.
255  (@interface func (export "fd_renumber")
256    (param $fd $fd)
257    ;;; The file descriptor to overwrite.
258    (param $to $fd)
259    (result $error $errno)
260  )
261
262  ;;; Move the offset of a file descriptor.
263  ;;; Note: This is similar to `lseek` in POSIX.
264  (@interface func (export "fd_seek")
265    (param $fd $fd)
266    ;;; The number of bytes to move.
267    (param $offset $filedelta)
268    ;;; The base from which the offset is relative.
269    (param $whence $whence)
270    (result $error $errno)
271    ;;; The new offset of the file descriptor, relative to the start of the file.
272    (result $newoffset $filesize)
273  )
274
275  ;;; Synchronize the data and metadata of a file to disk.
276  ;;; Note: This is similar to `fsync` in POSIX.
277  (@interface func (export "fd_sync")
278    (param $fd $fd)
279    (result $error $errno)
280  )
281
282  ;;; Return the current offset of a file descriptor.
283  ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX.
284  (@interface func (export "fd_tell")
285    (param $fd $fd)
286    (result $error $errno)
287    ;;; The current offset of the file descriptor, relative to the start of the file.
288    (result $offset $filesize)
289  )
290
291  ;;; Write to a file descriptor.
292  ;;; Note: This is similar to `writev` in POSIX.
293  (@interface func (export "fd_write")
294    (param $fd $fd)
295    ;;; List of scatter/gather vectors from which to retrieve data.
296    (param $iovs $ciovec_array)
297    (result $error $errno)
298    ;;; The number of bytes written.
299    (result $nwritten $size)
300  )
301
302  ;;; Create a directory.
303  ;;; Note: This is similar to `mkdirat` in POSIX.
304  (@interface func (export "path_create_directory")
305    (param $fd $fd)
306    ;;; The path at which to create the directory.
307    (param $path string)
308    (result $error $errno)
309  )
310
311  ;;; Return the attributes of a file or directory.
312  ;;; Note: This is similar to `stat` in POSIX.
313  (@interface func (export "path_filestat_get")
314    (param $fd $fd)
315    ;;; Flags determining the method of how the path is resolved.
316    (param $flags $lookupflags)
317    ;;; The path of the file or directory to inspect.
318    (param $path string)
319    (result $error $errno)
320    ;;; The buffer where the file's attributes are stored.
321    (result $buf $filestat)
322  )
323
324  ;;; Adjust the timestamps of a file or directory.
325  ;;; Note: This is similar to `utimensat` in POSIX.
326  (@interface func (export "path_filestat_set_times")
327    (param $fd $fd)
328    ;;; Flags determining the method of how the path is resolved.
329    (param $flags $lookupflags)
330    ;;; The path of the file or directory to operate on.
331    (param $path string)
332    ;;; The desired values of the data access timestamp.
333    (param $atim $timestamp)
334    ;;; The desired values of the data modification timestamp.
335    (param $mtim $timestamp)
336    ;;; A bitmask indicating which timestamps to adjust.
337    (param $fst_flags $fstflags)
338    (result $error $errno)
339  )
340
341  ;;; Create a hard link.
342  ;;; Note: This is similar to `linkat` in POSIX.
343  (@interface func (export "path_link")
344    (param $old_fd $fd)
345    ;;; Flags determining the method of how the path is resolved.
346    (param $old_flags $lookupflags)
347    ;;; The source path from which to link.
348    (param $old_path string)
349    ;;; The working directory at which the resolution of the new path starts.
350    (param $new_fd $fd)
351    ;;; The destination path at which to create the hard link.
352    (param $new_path string)
353    (result $error $errno)
354  )
355
356  ;;; Open a file or directory.
357  ;;
358  ;;; The returned file descriptor is not guaranteed to be the lowest-numbered
359  ;;; file descriptor not currently open; it is randomized to prevent
360  ;;; applications from depending on making assumptions about indexes, since this
361  ;;; is error-prone in multi-threaded contexts. The returned file descriptor is
362  ;;; guaranteed to be less than 2**31.
363  ;;
364  ;;; Note: This is similar to `openat` in POSIX.
365  (@interface func (export "path_open")
366    (param $fd $fd)
367    ;;; Flags determining the method of how the path is resolved.
368    (param $dirflags $lookupflags)
369    ;;; The relative path of the file or directory to open, relative to the
370    ;;; `fd` directory.
371    (param $path string)
372    ;;; The method by which to open the file.
373    (param $oflags $oflags)
374    ;;; The initial rights of the newly created file descriptor. The
375    ;;; implementation is allowed to return a file descriptor with fewer rights
376    ;;; than specified, if and only if those rights do not apply to the type of
377    ;;; file being opened.
378    ;;
379    ;;; The *base* rights are rights that will apply to operations using the file
380    ;;; descriptor itself, while the *inheriting* rights are rights that apply to
381    ;;; file descriptors derived from it.
382    (param $fs_rights_base $rights)
383    (param $fs_rights_inherting $rights)
384    (param $fdflags $fdflags)
385    (result $error $errno)
386    ;;; The file descriptor of the file that has been opened.
387    (result $opened_fd $fd)
388  )
389
390  ;;; Read the contents of a symbolic link.
391  ;;; Note: This is similar to `readlinkat` in POSIX.
392  (@interface func (export "path_readlink")
393    (param $fd $fd)
394    ;;; The path of the symbolic link from which to read.
395    (param $path string)
396    ;;; The buffer to which to write the contents of the symbolic link.
397    (param $buf (@witx pointer u8))
398    (param $buf_len $size)
399    (result $error $errno)
400    ;;; The number of bytes placed in the buffer.
401    (result $bufused $size)
402  )
403
404  ;;; Remove a directory.
405  ;;; Return `errno::notempty` if the directory is not empty.
406  ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX.
407  (@interface func (export "path_remove_directory")
408    (param $fd $fd)
409    ;;; The path to a directory to remove.
410    (param $path string)
411    (result $error $errno)
412  )
413
414  ;;; Rename a file or directory.
415  ;;; Note: This is similar to `renameat` in POSIX.
416  (@interface func (export "path_rename")
417    (param $fd $fd)
418    ;;; The source path of the file or directory to rename.
419    (param $old_path string)
420    ;;; The working directory at which the resolution of the new path starts.
421    (param $new_fd $fd)
422    ;;; The destination path to which to rename the file or directory.
423    (param $new_path string)
424    (result $error $errno)
425  )
426
427  ;;; Create a symbolic link.
428  ;;; Note: This is similar to `symlinkat` in POSIX.
429  (@interface func (export "path_symlink")
430    ;;; The contents of the symbolic link.
431    (param $old_path string)
432    (param $fd $fd)
433    ;;; The destination path at which to create the symbolic link.
434    (param $new_path string)
435    (result $error $errno)
436  )
437
438
439  ;;; Unlink a file.
440  ;;; Return `errno::isdir` if the path refers to a directory.
441  ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX.
442  (@interface func (export "path_unlink_file")
443    (param $fd $fd)
444    ;;; The path to a file to unlink.
445    (param $path string)
446    (result $error $errno)
447  )
448
449  ;;; Concurrently poll for the occurrence of a set of events.
450  (@interface func (export "poll_oneoff")
451    ;;; The events to which to subscribe.
452    (param $in (@witx const_pointer $subscription))
453    ;;; The events that have occurred.
454    (param $out (@witx pointer $event))
455    ;;; Both the number of subscriptions and events.
456    (param $nsubscriptions $size)
457    (result $error $errno)
458    ;;; The number of events stored.
459    (result $nevents $size)
460  )
461
462  ;;; Terminate the process normally. An exit code of 0 indicates successful
463  ;;; termination of the program. The meanings of other values is dependent on
464  ;;; the environment.
465  (@interface func (export "proc_exit")
466    ;;; The exit code returned by the process.
467    (param $rval $exitcode)
468  )
469
470  ;;; Send a signal to the process of the calling thread.
471  ;;; Note: This is similar to `raise` in POSIX.
472  (@interface func (export "proc_raise")
473    ;;; The signal condition to trigger.
474    (param $sig $signal)
475    (result $error $errno)
476  )
477
478  ;;; Temporarily yield execution of the calling thread.
479  ;;; Note: This is similar to `sched_yield` in POSIX.
480  (@interface func (export "sched_yield")
481    (result $error $errno)
482  )
483
484  ;;; Write high-quality random data into a buffer.
485  ;;; This function blocks when the implementation is unable to immediately
486  ;;; provide sufficient high-quality random data.
487  ;;; This function may execute slowly, so when large mounts of random data are
488  ;;; required, it's advisable to use this function to seed a pseudo-random
489  ;;; number generator, rather than to provide the random data directly.
490  (@interface func (export "random_get")
491    ;;; The buffer to fill with random data.
492    (param $buf (@witx pointer u8))
493    (param $buf_len $size)
494    (result $error $errno)
495  )
496
497  ;;; Receive a message from a socket.
498  ;;; Note: This is similar to `recv` in POSIX, though it also supports reading
499  ;;; the data into multiple buffers in the manner of `readv`.
500  (@interface func (export "sock_recv")
501    (param $fd $fd)
502    ;;; List of scatter/gather vectors to which to store data.
503    (param $ri_data $iovec_array)
504    ;;; Message flags.
505    (param $ri_flags $riflags)
506    (result $error $errno)
507    ;;; Number of bytes stored in ri_data.
508    (result $ro_datalen $size)
509    ;;; Message flags.
510    (result $ro_flags $roflags)
511  )
512
513  ;;; Send a message on a socket.
514  ;;; Note: This is similar to `send` in POSIX, though it also supports writing
515  ;;; the data from multiple buffers in the manner of `writev`.
516  (@interface func (export "sock_send")
517    (param $fd $fd)
518    ;;; List of scatter/gather vectors to which to retrieve data
519    (param $si_data $ciovec_array)
520    ;;; Message flags.
521    (param $si_flags $siflags)
522    (result $error $errno)
523    ;;; Number of bytes transmitted.
524    (result $so_datalen $size)
525  )
526
527  ;;; Shut down socket send and receive channels.
528  ;;; Note: This is similar to `shutdown` in POSIX.
529  (@interface func (export "sock_shutdown")
530    (param $fd $fd)
531    ;;; Which channels on the socket to shut down.
532    (param $how $sdflags)
533    (result $error $errno)
534  )
535)
536