wasi_types/lib.rs
1//! Rusty WASI type definitions based on
2//! [the spec](https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md)
3#![feature(non_exhaustive)]
4
5#[macro_use]
6extern crate bitflags;
7#[macro_use]
8extern crate proper;
9
10/// File or memory access pattern advisory information.
11#[repr(u8)]
12#[derive(Clone, Copy, PartialEq, Prim)]
13pub enum Advice {
14 /// The application has no advice to give on its behavior with respect to the specified data.
15 Normal,
16
17 /// The application expects to access the data sequentially from lower to higher offsets.
18 Sequential,
19
20 /// The application expects to access the specified data in a random order.
21 Random,
22
23 /// The application expects that it will not access the specified data in the near future.
24 DontNeed,
25
26 /// The application expects to access the specified data once and then not reuse it thereafter.
27 NoReuse,
28
29 /// The application expects to access the specified data in the near future.
30 WillNeed,
31}
32
33/// Identifiers for clocks.
34#[repr(u8)]
35#[derive(Clone, Copy, PartialEq, Prim)]
36pub enum ClockId {
37 /// The clock measuring real time. Time value zero corresponds with 1970-01-01T00:00:00Z.
38 RealTime,
39
40 /// The store-wide monotonic clock, which is defined as a clock measuring real time, whose
41 /// value cannot be adjusted and which cannot have negative clock jumps.
42 ///
43 /// The epoch of this clock is undefined. The absolute time value of this clock therefore
44 /// has no meaning.
45 Monotonic,
46
47 /// The CPU-time clock associated with the current process.
48 ProcessCpuTime,
49
50 /// The CPU-time clock associated with the current thread.
51 ThreadCpuTime,
52}
53
54/// Identifier for a device containing a file system. Can be used in combination with `Inode`
55/// to uniquely identify a file or directory in the filesystem.
56#[repr(C)]
57#[derive(Clone, Copy, Debug, PartialEq, Eq, Prim)]
58pub struct Device(u64);
59
60/// A reference to the offset of a directory entry.
61#[repr(C)]
62#[derive(Clone, Copy, Debug, PartialEq, Eq, Prim)]
63pub struct DirCookie(u64);
64
65impl DirCookie {
66 /// Creates a new `DirCookie` repreenting a permanent reference to the first directory entry
67 /// within a directory.
68 pub fn start() -> Self {
69 DirCookie(0)
70 }
71}
72
73/// A directory entry.
74#[repr(C)]
75#[derive(Clone, Copy, PartialEq, Eq)]
76pub struct DirEnt {
77 /// The offset of the next directory entry stored in this directory.
78 pub next: DirCookie,
79
80 /// The serial number of the file referred to by this directory entry.
81 pub inode: Inode,
82
83 /// The length of the name of the directory entry.
84 pub name_len: u32,
85
86 /// The type of the file referred to by this directory entry.
87 pub file_type: FileType,
88}
89
90/// Error codes returned by functions.
91#[repr(u16)]
92#[derive(Clone, Copy, Debug, PartialEq, Eq, Prim)]
93#[prim(ty = "u16")]
94#[non_exhaustive]
95pub enum ErrNo {
96 /// No error occurred. System call completed successfully.
97 Success,
98
99 /// Argument list too long.
100 TooBig,
101
102 /// Permission denied.
103 Access,
104
105 /// Address in use.
106 AddrInUse,
107
108 /// Address not available.
109 AddrNotAvail,
110
111 /// Address family not supported.
112 AfNoSupport,
113
114 /// Resource unavailable, or operation would block.
115 Again,
116
117 /// Connection already in progress.
118 Already,
119
120 /// Bad file descriptor.
121 BadF,
122
123 /// Bad message.
124 BadMsg,
125
126 /// Device or resource busy.
127 Busy,
128
129 /// Operation canceled.
130 Canceled,
131
132 /// No child processes.
133 Child,
134
135 /// Connection aborted.
136 ConnAborted,
137
138 /// Connection refused.
139 ConnRefused,
140
141 /// Connection reset.
142 ConnReset,
143
144 /// Resource deadlock would occur.
145 Deadlk,
146
147 /// Destination address required.
148 DestAddrReq,
149
150 /// Mathematics argument out of domain of function.
151 Domain,
152
153 /// Reserved. (Quota exceeded.)
154 DQuot,
155
156 /// File exists.
157 Exist,
158
159 /// Bad address.
160 Fault,
161
162 /// File too large.
163 FBig,
164
165 /// Host is unreachable.
166 HostUnreach,
167
168 /// Identifier removed.
169 IdRm,
170
171 /// Illegal byte sequence.
172 IlSeq,
173
174 /// Operation in progress.
175 InProgress,
176
177 /// Interrupted function.
178 Intr,
179
180 /// Invalid argument.
181 Inval,
182
183 /// I/O error.
184 Io,
185
186 /// Socket is connected.
187 IsConn,
188
189 /// Is a directory.
190 IsDir,
191
192 /// Too many levels of symbolic links.
193 Loop,
194
195 /// File descriptor value too large.
196 MFile,
197
198 /// Too many links.
199 MLink,
200
201 /// Message too large.
202 MsgSize,
203
204 /// Reserved. (Multihop attempted.)
205 Multihop,
206
207 /// Filename too long.
208 NameTooLong,
209
210 /// Network is down.
211 NetDown,
212
213 /// Connection aborted by network.
214 NetReset,
215
216 /// Network unreachable.
217 NetUnreach,
218
219 /// Too many files open in system.
220 NFile,
221
222 /// No buffer space available.
223 NoBufS,
224
225 /// No such device.
226 NoDev,
227
228 /// No such file or directory.
229 NoEnt,
230
231 /// Executable file format error.
232 NoExec,
233
234 /// No locks available.
235 NoLock,
236
237 /// Reserved. (Link has been severed.)
238 NoLink,
239
240 /// Not enough space.
241 NoMem,
242
243 /// No message of the desired type.
244 NoMsg,
245
246 /// Protocol not available.
247 NoProtoOpt,
248
249 /// No space left on device.
250 NoSpace,
251
252 /// Function not supported. (Always unsupported.)
253 NoSys,
254
255 /// The socket is not connected.
256 NotConn,
257
258 /// Not a directory or a symbolic link to a directory.
259 NotDir,
260
261 /// Directory not empty.
262 NotEmpty,
263
264 /// State not recoverable.
265 NotRecoverable,
266
267 /// Not a socket.
268 NotSock,
269
270 /// Not supported, or operation not supported on socket. (Transient unsupported.)
271 NotSup,
272
273 /// Inappropriate I/O control operation.
274 NoTty,
275
276 /// No such device or address.
277 NxIo,
278
279 /// Value too large to be stored in data type.
280 Overflow,
281
282 /// Previous owner died.
283 OwnerDead,
284
285 /// Operation not permitted.
286 Perm,
287
288 /// Broken pipe.
289 Pipe,
290
291 /// Protocol error.
292 Proto,
293
294 /// Protocol not supported.
295 ProtoNoSupport,
296
297 /// Protocol wrong type for socket.
298 ProtoType,
299
300 /// Result too large.
301 Range,
302
303 /// Read-only file system.
304 RoFs,
305
306 /// Invalid seek.
307 SPipe,
308
309 /// No such process.
310 Srch,
311
312 /// Reserved. (Stale file handle.)
313 Stale,
314
315 /// Connection timed out.
316 TimedOut,
317
318 /// Text file busy.
319 TxtBsy,
320
321 /// Cross-device link.
322 XDev,
323
324 /// Extension: Capabilities insufficient.
325 NotCapable,
326}
327
328impl From<std::io::Error> for ErrNo {
329 fn from(err: std::io::Error) -> Self {
330 use std::io::ErrorKind;
331 use ErrNo::*;
332 match err.kind() {
333 ErrorKind::NotFound => NoEnt,
334 ErrorKind::PermissionDenied => Access,
335 ErrorKind::ConnectionRefused => ConnRefused,
336 ErrorKind::ConnectionReset => ConnReset,
337 ErrorKind::ConnectionAborted => ConnAborted,
338 ErrorKind::NotConnected => NotConn,
339 ErrorKind::AddrInUse => AddrInUse,
340 ErrorKind::AddrNotAvailable => AddrNotAvail,
341 ErrorKind::BrokenPipe => Pipe,
342 ErrorKind::AlreadyExists => Exist,
343 ErrorKind::WouldBlock => Again,
344 ErrorKind::InvalidInput | ErrorKind::InvalidData => Inval,
345 ErrorKind::TimedOut => TimedOut,
346 ErrorKind::Interrupted => Intr,
347 ErrorKind::WriteZero | ErrorKind::Other | ErrorKind::UnexpectedEof | _ => Io,
348 // _ => ,
349 }
350 }
351}
352
353#[derive(Clone, Copy, Debug, PartialEq, Eq)]
354pub struct Event {
355 pub user_data: UserData,
356 pub error: ErrNo,
357 pub ty: EventType,
358 pub fd_state: Option<EventFdState>, // only valid when `ty \in {FdRead, FdWrite}`
359}
360
361#[repr(u8)]
362#[derive(Clone, Copy, Debug, PartialEq, Eq, Prim)]
363pub enum EventType {
364 /// The time value of clock `SubscriptionType::clock.clock_id` has reached timestamp
365 /// `Subscription::clock.timeout`.
366 Clock,
367
368 /// File descriptor `SubscriptionType::FdRw.fd` has data available for reading.
369 /// This event always triggers for regular files.
370 FdRead,
371
372 /// File descriptor `SubscriptionType::FdRw.fd` has capacity available for writing.
373 /// This event always triggers for regular files.
374 FdWrite,
375}
376
377/// The state of the file descriptor subscribed to with `EventType::FdRead` or `EventType::FdWrite`.
378#[repr(u16)]
379#[derive(Clone, Copy, Debug, PartialEq, Eq, Prim)]
380#[prim(ty = "u16")]
381pub enum EventRwFlags {
382 None,
383 Hangup,
384}
385
386pub type ExitCode = u32;
387
388#[repr(C)]
389#[derive(Clone, Copy, Debug, PartialEq, Eq)]
390pub struct EventFdState {
391 pub file_size: FileSize,
392 pub flags: EventRwFlags,
393}
394
395/// A file descriptor number.
396/// As in POSIX, 0, 1, and 2 are stdin, stdout, and stderr, respectively.
397/// File descriptors are not guaranteed to be contiguous or allocated in ascending order.
398/// Information about a file descriptor may be obtained through `fd_prestat_get`.
399#[repr(C)]
400#[derive(Clone, Copy, Debug, PartialEq, Eq, Prim)]
401pub struct Fd(u32);
402
403bitflags! {
404 #[derive(Default)]
405 pub struct FdFlags: u16 {
406 /// Append mode: Data written to the file is always appended to the file's end.
407 const APPEND = 1 << 0;
408
409 /// Write according to synchronized I/O data integrity completion.
410 /// Only the data stored in the file is synchronized.
411 const DSYNC = 1 << 1;
412
413 /// Non-blocking mode.
414 const NONBLOCK = 1 << 2;
415
416 /// Synchronized read I/O operations.
417 const RSYNC = 1 << 3;
418
419 /// Write according to synchronized I/O file integrity completion. In addition to synchronizing
420 /// the data stored in the file, the implementation may also synchronously update the file's
421 /// metadata.
422 const SYNC = 1 << 4;
423 }
424}
425
426bitflags! {
427 #[derive(Default)]
428 pub struct OpenFlags: u16 {
429 /// Create file if it does not exist.
430 const CREATE = 1 << 0;
431
432 /// Fail if not a directory.
433 const DIRECTORY = 1 << 1;
434
435 /// Fail if file already exists.
436 const EXCL = 1 << 2;
437
438 /// Truncate file to size 0.
439 const TRUNC = 1 << 3;
440 }
441}
442
443#[repr(C)]
444#[derive(Clone, Copy, Debug, PartialEq, Eq)]
445pub struct FdStat {
446 pub file_type: FileType,
447 pub flags: FdFlags,
448
449 /// Rights that apply to this file descriptor.
450 pub rights_base: Rights,
451
452 /// Maximum set of rights that may be installed on new file descriptors that are created
453 /// through this file descriptor.
454 pub rights_inheriting: Rights,
455}
456
457/// Relative offset within a file.
458pub type FileDelta = i64;
459
460/// The type of a file descriptor or file.
461#[repr(u8)]
462#[derive(Clone, Copy, Debug, PartialEq, Eq, Prim)]
463pub enum FileType {
464 Unknown,
465 BlockDevice,
466 CharacterDevice,
467 Directory,
468 RegularFile,
469 SocketDgram,
470 SocketStream,
471 SymbolicLink,
472}
473
474pub type FileSize = u64;
475
476/// File attributes.
477#[derive(Clone, Copy, Debug, PartialEq, Eq)]
478#[repr(C)]
479pub struct FileStat {
480 pub device: Device,
481 pub inode: Inode,
482 pub file_type: FileType,
483 pub num_links: LinkCount,
484 pub file_size: FileSize,
485 pub atime: Timestamp,
486 pub mtime: Timestamp,
487 pub ctime: Timestamp,
488}
489
490/// File serial number that is unique within its file system.
491#[derive(Clone, Copy, Debug, PartialEq, Eq, Prim)]
492pub struct Inode(u64);
493
494pub type Size = u32;
495pub type Pointer = u32;
496
497/// A region of memory for scatter/gather reads.
498#[repr(C)]
499#[derive(Clone, Copy, Debug, PartialEq, Eq)]
500pub struct IoVec {
501 pub buf: Pointer,
502 pub len: Size,
503}
504
505/// Number of hard links to an inode.
506pub type LinkCount = u32;
507
508bitflags! {
509 #[derive(Default)]
510 pub struct LookupFlags: u32 {
511 /// Follow symlinks.
512 const SYMLINK_FOLLOW = 1 << 0;
513 }
514}
515
516/// Information about a preopened resource.
517#[derive(Clone, Copy, Debug, PartialEq, Eq)]
518pub struct Prestat {
519 pub resource_type: PreopenType,
520}
521
522#[repr(C)]
523#[derive(Clone, Copy, Debug, PartialEq, Eq)]
524pub enum PreopenType {
525 Dir { name_len: Size },
526}
527
528bitflags! {
529 #[derive(Default)]
530 pub struct Rights: u64 {
531 const FD_DATASYNC = 1 << 0;
532 const FD_READ = 1 << 1;
533 const FD_SEEK = 1 << 2;
534 const FD_FDSTAT_SET_FLAGS = 1 << 3;
535 const FD_SYNC = 1 << 4;
536 const FD_TELL = 1 << 5;
537 const FD_WRITE = 1 << 6;
538 const FD_ADVISE = 1 << 7;
539 const FD_ALLOCATE = 1 << 8;
540 const PATH_CREATE_DIRECTORY = 1 << 9;
541 const PATH_CREATE_FILE = 1 << 10;
542 const PATH_LINK_SOURCE = 1 << 11;
543 const PATH_LINK_TARGET = 1 << 12;
544 const PATH_OPEN = 1 << 13;
545 const FD_READDIR = 1 << 14;
546 const PATH_READLINK = 1 << 15;
547 const PATH_RENAME_SOURCE = 1 << 16;
548 const PATH_RENAME_TARGET = 1 << 17;
549 const PATH_FILESTAT_GET = 1 << 18;
550 const PATH_FILESTAT_SET_SIZE = 1 << 19;
551 const PATH_FILESTAT_SET_TIMES = 1 << 20;
552 const FD_FILESTAT_GET = 1 << 21;
553 const FD_FILESTAT_SET_SIZE = 1 << 22;
554 const FD_FILESTAT_SET_TIMES = 1 << 23;
555 const PATH_SYMLINK = 1 << 24;
556 const PATH_REMOVE_DIRECTORY = 1 << 25;
557 const PATH_UNLINK_FILE = 1 << 26;
558 const POLL_FD_READWRITE = 1 << 27;
559 }
560}
561
562/// Signal condition.
563#[repr(u8)]
564#[derive(Clone, Copy, PartialEq, Prim)]
565pub enum Signal {
566 Reserved,
567 Abort,
568 Alarm,
569 Bus,
570 Child,
571 Cont,
572 FP,
573 Hup,
574 Ill,
575 Int,
576 Kill,
577 Pipe,
578 Quit,
579 Seg,
580 Stop,
581 Sys,
582 Term,
583 Trap,
584 TStp,
585 TTIn,
586 TTOut,
587 Urg,
588 Usr1,
589 Usr2,
590 VTAlrm,
591 XCpu,
592 XFSz,
593}
594
595/// Timestamp in nanoseconds.
596#[derive(Prim, Clone, Copy, Debug, PartialEq, Eq)]
597pub struct Timestamp(u64);
598
599impl Timestamp {
600 pub fn from_nanos(nanos: u64) -> Self {
601 Timestamp(nanos)
602 }
603
604 pub fn from_sec(sec: u64) -> Self {
605 Self::from_nanos(sec * 1_000_000_000)
606 }
607
608 pub fn as_nanos(&self) -> u64 {
609 self.0
610 }
611}
612
613bitflags! {
614 pub struct SetTimeFlags: u16 {
615 const ATIME = 1 << 0;
616 const ATIME_NOW = 1 << 1;
617 const MTIME = 1 << 2;
618 const MTIME_NOW = 1 << 3;
619 }
620}
621
622pub type UserData = u64;
623
624/// The position relative to which to set the offset of the file descriptor.
625#[repr(u8)]
626#[derive(Clone, Copy, Debug, PartialEq, Prim)]
627pub enum Whence {
628 Current,
629 End,
630 Start,
631}