1//! wasi_snapshot_preview1 spec available (in witx format) here:
2//! * typenames -- https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/witx/typenames.witx
3//! * module -- https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/witx/wasi_snapshot_preview1.witx
4//! Note that libc API does *not* go in this file. wasi libc API goes into std/c.zig instead.
5const builtin = @import("builtin");
6const std = @import("std");
7const assert = std.debug.assert;
8
9comptime {
10 if (builtin.os.tag == .wasi) {
11 assert(@alignOf(i8) == 1);
12 assert(@alignOf(u8) == 1);
13 assert(@alignOf(i16) == 2);
14 assert(@alignOf(u16) == 2);
15 assert(@alignOf(i32) == 4);
16 assert(@alignOf(u32) == 4);
17 assert(@alignOf(i64) == 8);
18 assert(@alignOf(u64) == 8);
19 }
20}
21
22pub const iovec_t = std.posix.iovec;
23pub const ciovec_t = std.posix.iovec_const;
24
25pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;
26pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
27
28pub extern "wasi_snapshot_preview1" fn clock_res_get(clock_id: clockid_t, resolution: *timestamp_t) errno_t;
29pub extern "wasi_snapshot_preview1" fn clock_time_get(clock_id: clockid_t, precision: timestamp_t, timestamp: *timestamp_t) errno_t;
30
31pub extern "wasi_snapshot_preview1" fn environ_get(environ: [*][*:0]u8, environ_buf: [*]u8) errno_t;
32pub extern "wasi_snapshot_preview1" fn environ_sizes_get(environ_count: *usize, environ_buf_size: *usize) errno_t;
33
34pub extern "wasi_snapshot_preview1" fn fd_advise(fd: fd_t, offset: filesize_t, len: filesize_t, advice: advice_t) errno_t;
35pub extern "wasi_snapshot_preview1" fn fd_allocate(fd: fd_t, offset: filesize_t, len: filesize_t) errno_t;
36pub extern "wasi_snapshot_preview1" fn fd_close(fd: fd_t) errno_t;
37pub extern "wasi_snapshot_preview1" fn fd_datasync(fd: fd_t) errno_t;
38pub extern "wasi_snapshot_preview1" fn fd_pread(fd: fd_t, iovs: [*]const iovec_t, iovs_len: usize, offset: filesize_t, nread: *usize) errno_t;
39pub extern "wasi_snapshot_preview1" fn fd_pwrite(fd: fd_t, iovs: [*]const ciovec_t, iovs_len: usize, offset: filesize_t, nwritten: *usize) errno_t;
40pub extern "wasi_snapshot_preview1" fn fd_read(fd: fd_t, iovs: [*]const iovec_t, iovs_len: usize, nread: *usize) errno_t;
41pub extern "wasi_snapshot_preview1" fn fd_readdir(fd: fd_t, buf: [*]u8, buf_len: usize, cookie: dircookie_t, bufused: *usize) errno_t;
42pub extern "wasi_snapshot_preview1" fn fd_renumber(from: fd_t, to: fd_t) errno_t;
43pub extern "wasi_snapshot_preview1" fn fd_seek(fd: fd_t, offset: filedelta_t, whence: whence_t, newoffset: *filesize_t) errno_t;
44pub extern "wasi_snapshot_preview1" fn fd_sync(fd: fd_t) errno_t;
45pub extern "wasi_snapshot_preview1" fn fd_tell(fd: fd_t, newoffset: *filesize_t) errno_t;
46pub extern "wasi_snapshot_preview1" fn fd_write(fd: fd_t, iovs: [*]const ciovec_t, iovs_len: usize, nwritten: *usize) errno_t;
47
48pub extern "wasi_snapshot_preview1" fn fd_fdstat_get(fd: fd_t, buf: *fdstat_t) errno_t;
49pub extern "wasi_snapshot_preview1" fn fd_fdstat_set_flags(fd: fd_t, flags: fdflags_t) errno_t;
50pub extern "wasi_snapshot_preview1" fn fd_fdstat_set_rights(fd: fd_t, fs_rights_base: rights_t, fs_rights_inheriting: rights_t) errno_t;
51
52pub extern "wasi_snapshot_preview1" fn fd_filestat_get(fd: fd_t, buf: *filestat_t) errno_t;
53pub extern "wasi_snapshot_preview1" fn fd_filestat_set_size(fd: fd_t, st_size: filesize_t) errno_t;
54pub extern "wasi_snapshot_preview1" fn fd_filestat_set_times(fd: fd_t, st_atim: timestamp_t, st_mtim: timestamp_t, fstflags: fstflags_t) errno_t;
55
56pub extern "wasi_snapshot_preview1" fn fd_prestat_get(fd: fd_t, buf: *prestat_t) errno_t;
57pub extern "wasi_snapshot_preview1" fn fd_prestat_dir_name(fd: fd_t, path: [*]u8, path_len: usize) errno_t;
58
59pub extern "wasi_snapshot_preview1" fn path_create_directory(fd: fd_t, path: [*]const u8, path_len: usize) errno_t;
60pub extern "wasi_snapshot_preview1" fn path_filestat_get(fd: fd_t, flags: lookupflags_t, path: [*]const u8, path_len: usize, buf: *filestat_t) errno_t;
61pub extern "wasi_snapshot_preview1" fn path_filestat_set_times(fd: fd_t, flags: lookupflags_t, path: [*]const u8, path_len: usize, st_atim: timestamp_t, st_mtim: timestamp_t, fstflags: fstflags_t) errno_t;
62pub extern "wasi_snapshot_preview1" fn path_link(old_fd: fd_t, old_flags: lookupflags_t, old_path: [*]const u8, old_path_len: usize, new_fd: fd_t, new_path: [*]const u8, new_path_len: usize) errno_t;
63pub extern "wasi_snapshot_preview1" fn path_open(dirfd: fd_t, dirflags: lookupflags_t, path: [*]const u8, path_len: usize, oflags: oflags_t, fs_rights_base: rights_t, fs_rights_inheriting: rights_t, fs_flags: fdflags_t, fd: *fd_t) errno_t;
64pub extern "wasi_snapshot_preview1" fn path_readlink(fd: fd_t, path: [*]const u8, path_len: usize, buf: [*]u8, buf_len: usize, bufused: *usize) errno_t;
65pub extern "wasi_snapshot_preview1" fn path_remove_directory(fd: fd_t, path: [*]const u8, path_len: usize) errno_t;
66pub extern "wasi_snapshot_preview1" fn path_rename(old_fd: fd_t, old_path: [*]const u8, old_path_len: usize, new_fd: fd_t, new_path: [*]const u8, new_path_len: usize) errno_t;
67pub extern "wasi_snapshot_preview1" fn path_symlink(old_path: [*]const u8, old_path_len: usize, fd: fd_t, new_path: [*]const u8, new_path_len: usize) errno_t;
68pub extern "wasi_snapshot_preview1" fn path_unlink_file(fd: fd_t, path: [*]const u8, path_len: usize) errno_t;
69
70pub extern "wasi_snapshot_preview1" fn poll_oneoff(in: *const subscription_t, out: *event_t, nsubscriptions: usize, nevents: *usize) errno_t;
71
72pub extern "wasi_snapshot_preview1" fn proc_exit(rval: exitcode_t) noreturn;
73
74pub extern "wasi_snapshot_preview1" fn random_get(buf: [*]u8, buf_len: usize) errno_t;
75
76pub extern "wasi_snapshot_preview1" fn sched_yield() errno_t;
77
78pub extern "wasi_snapshot_preview1" fn sock_accept(sock: fd_t, flags: fdflags_t, result_fd: *fd_t) errno_t;
79pub extern "wasi_snapshot_preview1" fn sock_recv(sock: fd_t, ri_data: [*]iovec_t, ri_data_len: usize, ri_flags: riflags_t, ro_datalen: *usize, ro_flags: *roflags_t) errno_t;
80pub extern "wasi_snapshot_preview1" fn sock_send(sock: fd_t, si_data: [*]const ciovec_t, si_data_len: usize, si_flags: siflags_t, so_datalen: *usize) errno_t;
81pub extern "wasi_snapshot_preview1" fn sock_shutdown(sock: fd_t, how: sdflags_t) errno_t;
82
83// As defined in the wasi_snapshot_preview1 spec file:
84// https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/typenames.witx
85pub const advice_t = enum(u8) {
86 NORMAL = 0,
87 SEQUENTIAL = 1,
88 RANDOM = 2,
89 WILLNEED = 3,
90 DONTNEED = 4,
91 NOREUSE = 5,
92};
93
94pub const clockid_t = enum(u32) {
95 REALTIME = 0,
96 MONOTONIC = 1,
97 PROCESS_CPUTIME_ID = 2,
98 THREAD_CPUTIME_ID = 3,
99};
100
101pub const device_t = u64;
102
103pub const dircookie_t = u64;
104pub const DIRCOOKIE_START: dircookie_t = 0;
105
106pub const dirnamlen_t = u32;
107
108pub const dirent_t = extern struct {
109 next: dircookie_t,
110 ino: inode_t,
111 namlen: dirnamlen_t,
112 type: filetype_t,
113};
114
115pub const errno_t = enum(u16) {
116 SUCCESS = 0,
117 @"2BIG" = 1,
118 ACCES = 2,
119 ADDRINUSE = 3,
120 ADDRNOTAVAIL = 4,
121 AFNOSUPPORT = 5,
122 /// This is also the error code used for `WOULDBLOCK`.
123 AGAIN = 6,
124 ALREADY = 7,
125 BADF = 8,
126 BADMSG = 9,
127 BUSY = 10,
128 CANCELED = 11,
129 CHILD = 12,
130 CONNABORTED = 13,
131 CONNREFUSED = 14,
132 CONNRESET = 15,
133 DEADLK = 16,
134 DESTADDRREQ = 17,
135 DOM = 18,
136 DQUOT = 19,
137 EXIST = 20,
138 FAULT = 21,
139 FBIG = 22,
140 HOSTUNREACH = 23,
141 IDRM = 24,
142 ILSEQ = 25,
143 INPROGRESS = 26,
144 INTR = 27,
145 INVAL = 28,
146 IO = 29,
147 ISCONN = 30,
148 ISDIR = 31,
149 LOOP = 32,
150 MFILE = 33,
151 MLINK = 34,
152 MSGSIZE = 35,
153 MULTIHOP = 36,
154 NAMETOOLONG = 37,
155 NETDOWN = 38,
156 NETRESET = 39,
157 NETUNREACH = 40,
158 NFILE = 41,
159 NOBUFS = 42,
160 NODEV = 43,
161 NOENT = 44,
162 NOEXEC = 45,
163 NOLCK = 46,
164 NOLINK = 47,
165 NOMEM = 48,
166 NOMSG = 49,
167 NOPROTOOPT = 50,
168 NOSPC = 51,
169 NOSYS = 52,
170 NOTCONN = 53,
171 NOTDIR = 54,
172 NOTEMPTY = 55,
173 NOTRECOVERABLE = 56,
174 NOTSOCK = 57,
175 /// This is also the code used for `NOTSUP`.
176 OPNOTSUPP = 58,
177 NOTTY = 59,
178 NXIO = 60,
179 OVERFLOW = 61,
180 OWNERDEAD = 62,
181 PERM = 63,
182 PIPE = 64,
183 PROTO = 65,
184 PROTONOSUPPORT = 66,
185 PROTOTYPE = 67,
186 RANGE = 68,
187 ROFS = 69,
188 SPIPE = 70,
189 SRCH = 71,
190 STALE = 72,
191 TIMEDOUT = 73,
192 TXTBSY = 74,
193 XDEV = 75,
194 NOTCAPABLE = 76,
195 _,
196};
197
198pub const event_t = extern struct {
199 userdata: userdata_t,
200 @"error": errno_t,
201 type: eventtype_t,
202 fd_readwrite: eventfdreadwrite_t,
203};
204
205pub const eventfdreadwrite_t = extern struct {
206 nbytes: filesize_t,
207 flags: eventrwflags_t,
208};
209
210pub const eventrwflags_t = u16;
211pub const EVENT_FD_READWRITE_HANGUP: eventrwflags_t = 0x0001;
212
213pub const eventtype_t = enum(u8) {
214 CLOCK = 0,
215 FD_READ = 1,
216 FD_WRITE = 2,
217};
218
219pub const exitcode_t = u32;
220
221pub const fd_t = i32;
222
223pub const fdflags_t = packed struct(u16) {
224 APPEND: bool = false,
225 DSYNC: bool = false,
226 NONBLOCK: bool = false,
227 RSYNC: bool = false,
228 SYNC: bool = false,
229 _: u11 = 0,
230};
231
232pub const fdstat_t = extern struct {
233 fs_filetype: filetype_t,
234 fs_flags: fdflags_t,
235 fs_rights_base: rights_t,
236 fs_rights_inheriting: rights_t,
237};
238
239pub const filedelta_t = i64;
240
241pub const filesize_t = u64;
242
243pub const filestat_t = extern struct {
244 dev: device_t,
245 ino: inode_t,
246 filetype: filetype_t,
247 nlink: linkcount_t,
248 size: filesize_t,
249 atim: timestamp_t,
250 mtim: timestamp_t,
251 ctim: timestamp_t,
252};
253
254pub const filetype_t = enum(u8) {
255 UNKNOWN,
256 BLOCK_DEVICE,
257 CHARACTER_DEVICE,
258 DIRECTORY,
259 REGULAR_FILE,
260 SOCKET_DGRAM,
261 SOCKET_STREAM,
262 SYMBOLIC_LINK,
263 _,
264};
265
266pub const fstflags_t = packed struct(u16) {
267 ATIM: bool = false,
268 ATIM_NOW: bool = false,
269 MTIM: bool = false,
270 MTIM_NOW: bool = false,
271 _: u12 = 0,
272};
273
274pub const inode_t = u64;
275
276pub const linkcount_t = u64;
277
278pub const lookupflags_t = packed struct(u32) {
279 SYMLINK_FOLLOW: bool = false,
280 _: u31 = 0,
281};
282
283pub const oflags_t = packed struct(u16) {
284 CREAT: bool = false,
285 DIRECTORY: bool = false,
286 EXCL: bool = false,
287 TRUNC: bool = false,
288 _: u12 = 0,
289};
290
291pub const preopentype_t = enum(u8) {
292 DIR = 0,
293};
294
295pub const prestat_t = extern struct {
296 pr_type: preopentype_t,
297 u: prestat_u_t,
298};
299
300pub const prestat_dir_t = extern struct {
301 pr_name_len: usize,
302};
303
304pub const prestat_u_t = extern union {
305 dir: prestat_dir_t,
306};
307
308pub const riflags_t = u16;
309pub const roflags_t = u16;
310
311pub const SOCK = struct {
312 pub const RECV_PEEK: riflags_t = 0x0001;
313 pub const RECV_WAITALL: riflags_t = 0x0002;
314
315 pub const RECV_DATA_TRUNCATED: roflags_t = 0x0001;
316};
317
318pub const rights_t = packed struct(u64) {
319 /// The right to invoke fd_datasync. If PATH_OPEN is set, includes the right to invoke
320 /// path_open with fdflags_t.dsync.
321 FD_DATASYNC: bool = false,
322 /// The right to invoke fd_read and sock_recv. If FD_SEEK is set, includes the right to invoke
323 /// fd_pread.
324 FD_READ: bool = false,
325 /// The right to invoke fd_seek. This flag implies FD_TELL.
326 FD_SEEK: bool = false,
327 /// The right to invoke fd_fdstat_set_flags.
328 FD_FDSTAT_SET_FLAGS: bool = false,
329 /// The right to invoke fd_sync. If PATH_OPEN is set, includes the right to invoke path_open
330 /// with fdflags_t.RSYNC and fdflags_t.DSYNC.
331 FD_SYNC: bool = false,
332 /// The right to invoke fd_seek in such a way that the file offset remains unaltered (i.e.
333 /// whence_t.CUR with offset zero), or to invoke fd_tell.
334 FD_TELL: bool = false,
335 /// The right to invoke fd_write and sock_send. If FD_SEEK is set, includes the right to invoke
336 /// fd_pwrite.
337 FD_WRITE: bool = false,
338 /// The right to invoke fd_advise.
339 FD_ADVISE: bool = false,
340 /// The right to invoke fd_allocate.
341 FD_ALLOCATE: bool = false,
342 /// The right to invoke path_create_directory.
343 PATH_CREATE_DIRECTORY: bool = false,
344 /// If PATH_OPEN is set, the right to invoke path_open with oflags_t.CREAT.
345 PATH_CREATE_FILE: bool = false,
346 /// The right to invoke path_link with the file descriptor as the source directory.
347 PATH_LINK_SOURCE: bool = false,
348 /// The right to invoke path_link with the file descriptor as the target directory.
349 PATH_LINK_TARGET: bool = false,
350 /// The right to invoke path_open.
351 PATH_OPEN: bool = false,
352 /// The right to invoke fd_readdir.
353 FD_READDIR: bool = false,
354 /// The right to invoke path_readlink.
355 PATH_READLINK: bool = false,
356 /// The right to invoke path_rename with the file descriptor as the source directory.
357 PATH_RENAME_SOURCE: bool = false,
358 /// The right to invoke path_rename with the file descriptor as the target directory.
359 PATH_RENAME_TARGET: bool = false,
360 /// The right to invoke path_filestat_get.
361 PATH_FILESTAT_GET: bool = false,
362 /// The right to change a file's size. If PATH_OPEN is set, includes the right to invoke
363 /// path_open with oflags_t.TRUNC. Note: there is no function named path_filestat_set_size.
364 /// This follows POSIX design, which only has ftruncate and does not provide ftruncateat. While
365 /// such function would be desirable from the API design perspective, there are virtually no
366 /// use cases for it since no code written for POSIX systems would use it. Moreover,
367 /// implementing it would require multiple syscalls, leading to inferior performance.
368 PATH_FILESTAT_SET_SIZE: bool = false,
369 /// The right to invoke path_filestat_set_times.
370 PATH_FILESTAT_SET_TIMES: bool = false,
371 /// The right to invoke fd_filestat_get.
372 FD_FILESTAT_GET: bool = false,
373 /// The right to invoke fd_filestat_set_size.
374 FD_FILESTAT_SET_SIZE: bool = false,
375 /// The right to invoke fd_filestat_set_times.
376 FD_FILESTAT_SET_TIMES: bool = false,
377 /// The right to invoke path_symlink.
378 PATH_SYMLINK: bool = false,
379 /// The right to invoke path_remove_directory.
380 PATH_REMOVE_DIRECTORY: bool = false,
381 /// The right to invoke path_unlink_file.
382 PATH_UNLINK_FILE: bool = false,
383 /// If FD_READ is set, includes the right to invoke poll_oneoff to subscribe to
384 /// eventtype_t.FD_READ. If FD_WRITE is set, includes the right to invoke poll_oneoff to
385 /// subscribe to eventtype_t.FD_WRITE.
386 POLL_FD_READWRITE: bool = false,
387 /// The right to invoke sock_shutdown.
388 SOCK_SHUTDOWN: bool = false,
389 /// The right to invoke sock_accept.
390 SOCK_ACCEPT: bool = false,
391 _: u34 = 0,
392};
393
394pub const sdflags_t = packed struct(u8) {
395 RD: bool = false,
396 WR: bool = false,
397 _: u6 = 0,
398};
399
400pub const siflags_t = u16;
401
402pub const signal_t = enum(u8) {
403 NONE = 0,
404 HUP = 1,
405 INT = 2,
406 QUIT = 3,
407 ILL = 4,
408 TRAP = 5,
409 ABRT = 6,
410 BUS = 7,
411 FPE = 8,
412 KILL = 9,
413 USR1 = 10,
414 SEGV = 11,
415 USR2 = 12,
416 PIPE = 13,
417 ALRM = 14,
418 TERM = 15,
419 CHLD = 16,
420 CONT = 17,
421 STOP = 18,
422 TSTP = 19,
423 TTIN = 20,
424 TTOU = 21,
425 URG = 22,
426 XCPU = 23,
427 XFSZ = 24,
428 VTALRM = 25,
429 PROF = 26,
430 WINCH = 27,
431 POLL = 28,
432 PWR = 29,
433 SYS = 30,
434};
435
436pub const subclockflags_t = u16;
437pub const SUBSCRIPTION_CLOCK_ABSTIME: subclockflags_t = 0x0001;
438
439pub const subscription_t = extern struct {
440 userdata: userdata_t,
441 u: subscription_u_t,
442};
443
444pub const subscription_clock_t = extern struct {
445 id: clockid_t,
446 timeout: timestamp_t,
447 precision: timestamp_t,
448 flags: subclockflags_t,
449};
450
451pub const subscription_fd_readwrite_t = extern struct {
452 fd: fd_t,
453};
454
455pub const subscription_u_t = extern struct {
456 tag: eventtype_t,
457 u: subscription_u_u_t,
458};
459
460pub const subscription_u_u_t = extern union {
461 clock: subscription_clock_t,
462 fd_read: subscription_fd_readwrite_t,
463 fd_write: subscription_fd_readwrite_t,
464};
465
466/// Nanoseconds.
467pub const timestamp_t = u64;
468
469pub const userdata_t = u64;
470
471pub const whence_t = enum(u8) { SET, CUR, END };