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}