cloudabi/
cloudabi.rs

1// Copyright (c) 2016-2017 Nuxi (https://nuxi.nl/) and contributors.
2//
3// Redistribution and use in source and binary forms, with or without
4// modification, are permitted provided that the following conditions
5// are met:
6// 1. Redistributions of source code must retain the above copyright
7//    notice, this list of conditions and the following disclaimer.
8// 2. Redistributions in binary form must reproduce the above copyright
9//    notice, this list of conditions and the following disclaimer in the
10//    documentation and/or other materials provided with the distribution.
11//
12// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22// SUCH DAMAGE.
23//
24// This file is automatically generated. Do not edit.
25//
26// Source: https://github.com/NuxiNL/cloudabi
27
28// Appease Rust's tidy.
29// ignore-license
30// ignore-tidy-linelength
31
32//! **PLEASE NOTE: This entire crate including this
33//! documentation is automatically generated from
34//! [`cloudabi.txt`](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt)**
35//!
36//! # Nuxi CloudABI
37//!
38//! CloudABI is what you get if you take POSIX, add capability-based
39//! security, and remove everything that's incompatible with that. The
40//! result is a minimal ABI consisting of only 49 syscalls.
41//!
42//! CloudABI doesn't have its own kernel, but instead is implemented in existing
43//! kernels: FreeBSD has CloudABI support for x86-64 and arm64, and [a patch-set
44//! for NetBSD](https://github.com/NuxiNL/netbsd) and [a patch-set for
45//! Linux](https://github.com/NuxiNL/linux) are available as well. This means that
46//! CloudABI binaries can be executed on different operating systems, without any
47//! modification.
48//!
49//! ## Capability-Based Security
50//!
51//! Capability-based security means that processes can only perform
52//! actions that have no global impact. Processes cannot open files by
53//! their absolute path, cannot open network connections, and cannot
54//! observe global system state such as the process table.
55//!
56//! The capabilities of a process are fully determined by its set of open
57//! file descriptors (fds). For example, files can only be opened if the
58//! process already has a file descriptor to a directory the file is in.
59//!
60//! Unlike in POSIX, where processes are normally started with file
61//! descriptors 0, 1, and 2 reserved for standard input, output, and
62//! error, CloudABI does not reserve any file descriptor numbers for
63//! specific purposes.
64//!
65//! In CloudABI, a process depends on its parent process to launch it with
66//! the right set of resources, since the process will not be able to open
67//! any new resources. For example, a simple static web server would need
68//! to be started with a file descriptor to a [TCP
69//! listener](https://github.com/NuxiNL/flower), and a file descriptor to
70//! the directory for which to serve files. The web server will then be
71//! unable to do anything other than reading files in that directory, and
72//! process incoming network connections.
73//!
74//! So, unknown CloudABI binaries can safely be executed without the need
75//! for containers, virtual machines, or other sandboxing technologies.
76//!
77//! Watch [Ed Schouten's Talk at
78//! 32C3](https://www.youtube.com/watch?v=3N29vrPoDv8) for more
79//! information about what capability-based security for UNIX means.
80//!
81//! ## Cloudlibc
82//!
83//! [Cloudlibc](https://github.com/NuxiNL/cloudlibc) is an implementation
84//! of the C standard library, without all CloudABI-incompatible
85//! functions. For example, Cloudlibc does not have `printf`, but does
86//! have `fprintf`. It does not have `open`, but does have `openat`.
87//!
88//! ## CloudABI-Ports
89//!
90//! [CloudABI-Ports](https://github.com/NuxiNL/cloudabi-ports) is a
91//! collection of ports of commonly used libraries and applications to
92//! CloudABI. It contains software such as `zlib`, `libpng`, `boost`,
93//! `memcached`, and much more. The software is patched to not depend on
94//! any global state, such as files in `/etc` or `/dev`, using `open()`,
95//! etc.
96//!
97//! ## Using CloudABI
98//!
99//! Instructions for using CloudABI (including kernel modules/patches,
100//! toolchain, and ports) are available for several operating systems:
101//!
102//! - [FreeBSD](https://cloudabi.org/run/freebsd/)
103//! - [Linux](https://cloudabi.org/run/linux/)
104//! - [macOS](https://cloudabi.org/run/macos/)
105//!
106//! ## Specification of the ABI
107//!
108//! The entire ABI is specified in a file called
109//! [`cloudabi.txt`](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt),
110//! from which all
111//! [headers](https://github.com/NuxiNL/cloudabi/tree/master/headers)
112//! and documentation (including the one you're reading now) is generated.
113
114#![no_std]
115#![allow(non_camel_case_types)]
116
117#[cfg(feature = "bitflags")]
118use bitflags::bitflags;
119
120// Minimal implementation of bitflags! in case we can't depend on the bitflags
121// crate. Only implements `bits()` and a `from_bits_unchecked()`.
122#[cfg(not(feature = "bitflags"))]
123macro_rules! bitflags {
124  (
125    $(#[$attr:meta])*
126    pub struct $name:ident: $type:ty {
127      $($(#[$const_attr:meta])* const $const:ident = $val:expr;)*
128    }
129  ) => {
130    $(#[$attr])*
131    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
132    pub struct $name { bits: $type }
133    impl $name {
134      $($(#[$const_attr])* pub const $const: $name = $name{ bits: $val };)*
135      pub const fn bits(&self) -> $type { self.bits }
136      pub const unsafe fn from_bits_unchecked(bits: $type) -> Self { $name{ bits } }
137    }
138  }
139}
140
141/// File or memory access pattern advisory information.
142#[repr(u8)]
143#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
144#[non_exhaustive]
145pub enum advice {
146  /// The application expects that it will not access the
147  /// specified data in the near future.
148  DONTNEED   = 1,
149  /// The application expects to access the specified data
150  /// once and then not reuse it thereafter.
151  NOREUSE    = 2,
152  /// The application has no advice to give on its behavior
153  /// with respect to the specified data.
154  NORMAL     = 3,
155  /// The application expects to access the specified data
156  /// in a random order.
157  RANDOM     = 4,
158  /// The application expects to access the specified data
159  /// sequentially from lower offsets to higher offsets.
160  SEQUENTIAL = 5,
161  /// The application expects to access the specified data
162  /// in the near future.
163  WILLNEED   = 6,
164}
165
166/// Enumeration describing the kind of value stored in [`auxv`](struct.auxv.html).
167#[repr(u32)]
168#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
169#[non_exhaustive]
170pub enum auxtype {
171  /// Base address of the binary argument data provided to
172  /// [`proc_exec()`](fn.proc_exec.html).
173  ARGDATA      = 256,
174  /// Length of the binary argument data provided to
175  /// [`proc_exec()`](fn.proc_exec.html).
176  ARGDATALEN   = 257,
177  /// Base address at which the executable is placed in
178  /// memory.
179  BASE         =   7,
180  /// Base address of a buffer of random data that may be
181  /// used for non-cryptographic purposes, for example as a
182  /// canary for stack smashing protection.
183  CANARY       = 258,
184  /// Length of a buffer of random data that may be used
185  /// for non-cryptographic purposes, for example as a
186  /// canary for stack smashing protection.
187  CANARYLEN    = 259,
188  /// Number of CPUs that the system this process is running
189  /// on has.
190  NCPUS        = 260,
191  /// Terminator of the auxiliary vector.
192  NULL         =   0,
193  /// Smallest memory object size for which individual
194  /// memory protection controls can be configured.
195  PAGESZ       =   6,
196  /// Address of the first ELF program header of the
197  /// executable.
198  PHDR         =   3,
199  /// Number of ELF program headers of the executable.
200  PHNUM        =   4,
201  /// Identifier of the process.
202  ///
203  /// This environment does not provide any simple numerical
204  /// process identifiers, for the reason that these are not
205  /// useful in distributed contexts. Instead, processes are
206  /// identified by a UUID.
207  ///
208  /// This record should point to sixteen bytes of binary
209  /// data, containing a version 4 UUID (fully random).
210  PID          = 263,
211  /// Address of the ELF header of the vDSO.
212  ///
213  /// The vDSO is a shared library that is mapped in the
214  /// address space of the process. It provides entry points
215  /// for every system call supported by the environment,
216  /// all having a corresponding symbol that is prefixed
217  /// with `cloudabi_sys_`. System calls should be invoked
218  /// through these entry points.
219  ///
220  /// The first advantage of letting processes call into a
221  /// vDSO to perform system calls instead of raising
222  /// hardware traps is that it allows for easy emulation of
223  /// executables on top of existing operating systems. The
224  /// second advantage is that in cases where an operating
225  /// system provides native support for CloudABI executables,
226  /// it may still implement partial userspace
227  /// implementations of these system calls to improve
228  /// performance (e.g., [`clock_time_get()`](fn.clock_time_get.html)). It also provides
229  /// a more dynamic way of adding, removing or replacing
230  /// system calls.
231  SYSINFO_EHDR = 262,
232  /// Thread ID of the initial thread of the process.
233  TID          = 261,
234}
235
236/// Identifiers for clocks.
237#[repr(u32)]
238#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
239#[non_exhaustive]
240pub enum clockid {
241  /// The system-wide monotonic clock, which is defined as a
242  /// clock measuring real time, whose value cannot be
243  /// adjusted and which cannot have negative clock jumps.
244  ///
245  /// The epoch of this clock is undefined. The absolute
246  /// time value of this clock therefore has no meaning.
247  MONOTONIC          = 1,
248  /// The CPU-time clock associated with the current
249  /// process.
250  PROCESS_CPUTIME_ID = 2,
251  /// The system-wide clock measuring real time. Time value
252  /// zero corresponds with 1970-01-01T00:00:00Z.
253  REALTIME           = 3,
254  /// The CPU-time clock associated with the current thread.
255  THREAD_CPUTIME_ID  = 4,
256}
257
258/// A userspace condition variable.
259#[repr(C)]
260#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
261pub struct condvar(pub u32);
262/// The condition variable is in its initial state. There
263/// are no threads waiting to be woken up. If the
264/// condition variable has any other value, the kernel
265/// must be called to wake up any sleeping threads.
266pub const CONDVAR_HAS_NO_WAITERS: condvar = condvar(0);
267
268/// Identifier for a device containing a file system. Can be used
269/// in combination with [`inode`](struct.inode.html) to uniquely identify a file on the
270/// local system.
271#[repr(C)]
272#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
273pub struct device(pub u64);
274
275/// A reference to the offset of a directory entry.
276#[repr(C)]
277#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
278pub struct dircookie(pub u64);
279/// Permanent reference to the first directory entry
280/// within a directory.
281pub const DIRCOOKIE_START: dircookie = dircookie(0);
282
283/// Error codes returned by system calls.
284///
285/// Not all of these error codes are returned by the system calls
286/// provided by this environment, but are either used in userspace
287/// exclusively or merely provided for alignment with POSIX.
288#[repr(u16)]
289#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
290#[non_exhaustive]
291pub enum errno {
292  /// No error occurred. System call completed successfully.
293  SUCCESS        =  0,
294  /// Argument list too long.
295  TOOBIG         =  1,
296  /// Permission denied.
297  ACCES          =  2,
298  /// Address in use.
299  ADDRINUSE      =  3,
300  /// Address not available.
301  ADDRNOTAVAIL   =  4,
302  /// Address family not supported.
303  AFNOSUPPORT    =  5,
304  /// Resource unavailable, or operation would block.
305  AGAIN          =  6,
306  /// Connection already in progress.
307  ALREADY        =  7,
308  /// Bad file descriptor.
309  BADF           =  8,
310  /// Bad message.
311  BADMSG         =  9,
312  /// Device or resource busy.
313  BUSY           = 10,
314  /// Operation canceled.
315  CANCELED       = 11,
316  /// No child processes.
317  CHILD          = 12,
318  /// Connection aborted.
319  CONNABORTED    = 13,
320  /// Connection refused.
321  CONNREFUSED    = 14,
322  /// Connection reset.
323  CONNRESET      = 15,
324  /// Resource deadlock would occur.
325  DEADLK         = 16,
326  /// Destination address required.
327  DESTADDRREQ    = 17,
328  /// Mathematics argument out of domain of function.
329  DOM            = 18,
330  /// Reserved.
331  DQUOT          = 19,
332  /// File exists.
333  EXIST          = 20,
334  /// Bad address.
335  FAULT          = 21,
336  /// File too large.
337  FBIG           = 22,
338  /// Host is unreachable.
339  HOSTUNREACH    = 23,
340  /// Identifier removed.
341  IDRM           = 24,
342  /// Illegal byte sequence.
343  ILSEQ          = 25,
344  /// Operation in progress.
345  INPROGRESS     = 26,
346  /// Interrupted function.
347  INTR           = 27,
348  /// Invalid argument.
349  INVAL          = 28,
350  /// I/O error.
351  IO             = 29,
352  /// Socket is connected.
353  ISCONN         = 30,
354  /// Is a directory.
355  ISDIR          = 31,
356  /// Too many levels of symbolic links.
357  LOOP           = 32,
358  /// File descriptor value too large.
359  MFILE          = 33,
360  /// Too many links.
361  MLINK          = 34,
362  /// Message too large.
363  MSGSIZE        = 35,
364  /// Reserved.
365  MULTIHOP       = 36,
366  /// Filename too long.
367  NAMETOOLONG    = 37,
368  /// Network is down.
369  NETDOWN        = 38,
370  /// Connection aborted by network.
371  NETRESET       = 39,
372  /// Network unreachable.
373  NETUNREACH     = 40,
374  /// Too many files open in system.
375  NFILE          = 41,
376  /// No buffer space available.
377  NOBUFS         = 42,
378  /// No such device.
379  NODEV          = 43,
380  /// No such file or directory.
381  NOENT          = 44,
382  /// Executable file format error.
383  NOEXEC         = 45,
384  /// No locks available.
385  NOLCK          = 46,
386  /// Reserved.
387  NOLINK         = 47,
388  /// Not enough space.
389  NOMEM          = 48,
390  /// No message of the desired type.
391  NOMSG          = 49,
392  /// Protocol not available.
393  NOPROTOOPT     = 50,
394  /// No space left on device.
395  NOSPC          = 51,
396  /// Function not supported.
397  NOSYS          = 52,
398  /// The socket is not connected.
399  NOTCONN        = 53,
400  /// Not a directory or a symbolic link to a directory.
401  NOTDIR         = 54,
402  /// Directory not empty.
403  NOTEMPTY       = 55,
404  /// State not recoverable.
405  NOTRECOVERABLE = 56,
406  /// Not a socket.
407  NOTSOCK        = 57,
408  /// Not supported, or operation not supported on socket.
409  NOTSUP         = 58,
410  /// Inappropriate I/O control operation.
411  NOTTY          = 59,
412  /// No such device or address.
413  NXIO           = 60,
414  /// Value too large to be stored in data type.
415  OVERFLOW       = 61,
416  /// Previous owner died.
417  OWNERDEAD      = 62,
418  /// Operation not permitted.
419  PERM           = 63,
420  /// Broken pipe.
421  PIPE           = 64,
422  /// Protocol error.
423  PROTO          = 65,
424  /// Protocol not supported.
425  PROTONOSUPPORT = 66,
426  /// Protocol wrong type for socket.
427  PROTOTYPE      = 67,
428  /// Result too large.
429  RANGE          = 68,
430  /// Read-only file system.
431  ROFS           = 69,
432  /// Invalid seek.
433  SPIPE          = 70,
434  /// No such process.
435  SRCH           = 71,
436  /// Reserved.
437  STALE          = 72,
438  /// Connection timed out.
439  TIMEDOUT       = 73,
440  /// Text file busy.
441  TXTBSY         = 74,
442  /// Cross-device link.
443  XDEV           = 75,
444  /// Extension: Capabilities insufficient.
445  NOTCAPABLE     = 76,
446}
447
448bitflags! {
449  /// The state of the file descriptor subscribed to with
450  /// [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
451  #[repr(C)]
452  pub struct eventrwflags: u16 {
453    /// The peer of this socket has closed or disconnected.
454    const HANGUP = 0x0001;
455  }
456}
457
458/// Type of a subscription to an event or its occurrence.
459#[repr(u8)]
460#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
461#[non_exhaustive]
462pub enum eventtype {
463  /// The time value of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id)
464  /// has reached timestamp [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout).
465  CLOCK          = 1,
466  /// Condition variable [`subscription.union.condvar.condvar`](struct.subscription_condvar.html#structfield.condvar) has
467  /// been woken up and [`subscription.union.condvar.lock`](struct.subscription_condvar.html#structfield.lock) has been
468  /// acquired for writing.
469  CONDVAR        = 2,
470  /// File descriptor [`subscription.union.fd_readwrite.fd`](struct.subscription_fd_readwrite.html#structfield.fd) has
471  /// data available for reading. This event always triggers
472  /// for regular files.
473  FD_READ        = 3,
474  /// File descriptor [`subscription.union.fd_readwrite.fd`](struct.subscription_fd_readwrite.html#structfield.fd) has
475  /// capacity available for writing. This event always
476  /// triggers for regular files.
477  FD_WRITE       = 4,
478  /// Lock [`subscription.union.lock.lock`](struct.subscription_lock.html#structfield.lock) has been acquired for
479  /// reading.
480  LOCK_RDLOCK    = 5,
481  /// Lock [`subscription.union.lock.lock`](struct.subscription_lock.html#structfield.lock) has been acquired for
482  /// writing.
483  LOCK_WRLOCK    = 6,
484  /// The process associated with process descriptor
485  /// [`subscription.union.proc_terminate.fd`](struct.subscription_proc_terminate.html#structfield.fd) has terminated.
486  PROC_TERMINATE = 7,
487}
488
489/// Exit code generated by a process when exiting.
490pub type exitcode = u32;
491
492/// A file descriptor number.
493///
494/// Unlike on POSIX-compliant systems, none of the file descriptor
495/// numbers are reserved for a purpose (e.g., stdin, stdout,
496/// stderr). Operating systems are not required to allocate new
497/// file descriptors in ascending order.
498#[repr(C)]
499#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
500pub struct fd(pub u32);
501/// Returned to the child process by [`proc_fork()`](fn.proc_fork.html).
502pub const PROCESS_CHILD: fd = fd(0xffffffff);
503/// Passed to [`mem_map()`](fn.mem_map.html) when creating a mapping to
504/// anonymous memory.
505pub const MAP_ANON_FD  : fd = fd(0xffffffff);
506
507bitflags! {
508  /// File descriptor flags.
509  #[repr(C)]
510  pub struct fdflags: u16 {
511    /// Append mode: Data written to the file is always
512    /// appended to the file's end.
513    const APPEND   = 0x0001;
514    /// Write according to synchronized I/O data integrity
515    /// completion. Only the data stored in the file is
516    /// synchronized.
517    const DSYNC    = 0x0002;
518    /// Non-blocking mode.
519    const NONBLOCK = 0x0004;
520    /// Synchronized read I/O operations.
521    const RSYNC    = 0x0008;
522    /// Write according to synchronized I/O file integrity
523    /// completion. In addition to synchronizing the data
524    /// stored in the file, the system may also synchronously
525    /// update the file's metadata.
526    const SYNC     = 0x0010;
527  }
528}
529
530bitflags! {
531  /// Which file descriptor attributes to adjust.
532  #[repr(C)]
533  pub struct fdsflags: u16 {
534    /// Adjust the file descriptor flags stored in
535    /// [`fdstat.fs_flags`](struct.fdstat.html#structfield.fs_flags).
536    const FLAGS  = 0x0001;
537    /// Restrict the rights of the file descriptor to the
538    /// rights stored in [`fdstat.fs_rights_base`](struct.fdstat.html#structfield.fs_rights_base) and
539    /// [`fdstat.fs_rights_inheriting`](struct.fdstat.html#structfield.fs_rights_inheriting).
540    const RIGHTS = 0x0002;
541  }
542}
543
544/// Relative offset within a file.
545pub type filedelta = i64;
546
547/// Non-negative file size or length of a region within a file.
548pub type filesize = u64;
549
550/// The type of a file descriptor or file.
551#[repr(u8)]
552#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
553#[non_exhaustive]
554pub enum filetype {
555  /// The type of the file descriptor or file is unknown or
556  /// is different from any of the other types specified.
557  UNKNOWN          =   0,
558  /// The file descriptor or file refers to a block device
559  /// inode.
560  BLOCK_DEVICE     =  16,
561  /// The file descriptor or file refers to a character
562  /// device inode.
563  CHARACTER_DEVICE =  17,
564  /// The file descriptor or file refers to a directory
565  /// inode.
566  DIRECTORY        =  32,
567  /// The file descriptor refers to a process handle.
568  PROCESS          =  80,
569  /// The file descriptor or file refers to a regular file
570  /// inode.
571  REGULAR_FILE     =  96,
572  /// The file descriptor refers to a shared memory object.
573  SHARED_MEMORY    = 112,
574  /// The file descriptor or file refers to a datagram
575  /// socket.
576  SOCKET_DGRAM     = 128,
577  /// The file descriptor or file refers to a byte-stream
578  /// socket.
579  SOCKET_STREAM    = 130,
580  /// The file refers to a symbolic link inode.
581  SYMBOLIC_LINK    = 144,
582}
583
584bitflags! {
585  /// Which file attributes to adjust.
586  #[repr(C)]
587  pub struct fsflags: u16 {
588    /// Adjust the last data access timestamp to the value
589    /// stored in [`filestat.st_atim`](struct.filestat.html#structfield.st_atim).
590    const ATIM     = 0x0001;
591    /// Adjust the last data access timestamp to the time
592    /// of clock [`REALTIME`](enum.clockid.html#variant.REALTIME).
593    const ATIM_NOW = 0x0002;
594    /// Adjust the last data modification timestamp to the
595    /// value stored in [`filestat.st_mtim`](struct.filestat.html#structfield.st_mtim).
596    const MTIM     = 0x0004;
597    /// Adjust the last data modification timestamp to the
598    /// time of clock [`REALTIME`](enum.clockid.html#variant.REALTIME).
599    const MTIM_NOW = 0x0008;
600    /// Truncate or extend the file to the size stored in
601    /// [`filestat.st_size`](struct.filestat.html#structfield.st_size).
602    const SIZE     = 0x0010;
603  }
604}
605
606/// File serial number that is unique within its file system.
607#[repr(C)]
608#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
609pub struct inode(pub u64);
610
611/// Number of hard links to an inode.
612pub type linkcount = u32;
613
614/// A userspace read-recursive readers-writer lock, similar to a
615/// Linux futex or a FreeBSD umtx.
616#[repr(C)]
617#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
618pub struct lock(pub u32);
619/// Value indicating that the lock is in its initial
620/// unlocked state.
621pub const LOCK_UNLOCKED      : lock = lock(0x00000000);
622/// Bitmask indicating that the lock is write-locked. If
623/// set, the lower 30 bits of the lock contain the
624/// identifier of the thread that owns the write lock.
625/// Otherwise, the lower 30 bits of the lock contain the
626/// number of acquired read locks.
627pub const LOCK_WRLOCKED      : lock = lock(0x40000000);
628/// Bitmask indicating that the lock is either read locked
629/// or write locked, and that one or more threads have
630/// their execution suspended, waiting to acquire the
631/// lock. The last owner of the lock must call the
632/// kernel to unlock.
633///
634/// When the lock is acquired for reading and this bit is
635/// set, it means that one or more threads are attempting
636/// to acquire this lock for writing. In that case, other
637/// threads should only acquire additional read locks if
638/// suspending execution would cause a deadlock. It is
639/// preferred to suspend execution, as this prevents
640/// starvation of writers.
641pub const LOCK_KERNEL_MANAGED: lock = lock(0x80000000);
642/// Value indicating that the lock is in an incorrect
643/// state. A lock cannot be in its initial unlocked state,
644/// while also managed by the kernel.
645pub const LOCK_BOGUS         : lock = lock(0x80000000);
646
647bitflags! {
648  /// Flags determining the method of how paths are resolved.
649  #[repr(C)]
650  pub struct lookupflags: u32 {
651    /// As long as the resolved path corresponds to a symbolic
652    /// link, it is expanded.
653    const SYMLINK_FOLLOW = 0x00000001;
654  }
655}
656
657bitflags! {
658  /// Memory mapping flags.
659  #[repr(C)]
660  pub struct mflags: u8 {
661    /// Instead of mapping the contents of the file provided,
662    /// create a mapping to anonymous memory. The file
663    /// descriptor argument must be set to [`MAP_ANON_FD`](constant.MAP_ANON_FD.html),
664    /// and the offset must be set to zero.
665    const ANON    = 0x01;
666    /// Require that the mapping is performed at the base
667    /// address provided.
668    const FIXED   = 0x02;
669    /// Changes are private.
670    const PRIVATE = 0x04;
671    /// Changes are shared.
672    const SHARED  = 0x08;
673  }
674}
675
676bitflags! {
677  /// Memory page protection options.
678  ///
679  /// This implementation enforces the `W^X` property: Pages cannot be
680  /// mapped for execution while also mapped for writing.
681  #[repr(C)]
682  pub struct mprot: u8 {
683    /// Page can be executed.
684    const EXEC  = 0x01;
685    /// Page can be written.
686    const WRITE = 0x02;
687    /// Page can be read.
688    const READ  = 0x04;
689  }
690}
691
692bitflags! {
693  /// Methods of synchronizing memory with physical storage.
694  #[repr(C)]
695  pub struct msflags: u8 {
696    /// Perform asynchronous writes.
697    const ASYNC      = 0x01;
698    /// Invalidate cached data.
699    const INVALIDATE = 0x02;
700    /// Perform synchronous writes.
701    const SYNC       = 0x04;
702  }
703}
704
705/// Specifies the number of threads sleeping on a condition
706/// variable that should be woken up.
707pub type nthreads = u32;
708
709bitflags! {
710  /// Open flags used by [`file_open()`](fn.file_open.html).
711  #[repr(C)]
712  pub struct oflags: u16 {
713    /// Create file if it does not exist.
714    const CREAT     = 0x0001;
715    /// Fail if not a directory.
716    const DIRECTORY = 0x0002;
717    /// Fail if file already exists.
718    const EXCL      = 0x0004;
719    /// Truncate file to size 0.
720    const TRUNC     = 0x0008;
721  }
722}
723
724bitflags! {
725  /// Flags provided to [`sock_recv()`](fn.sock_recv.html).
726  #[repr(C)]
727  pub struct riflags: u16 {
728    /// Returns the message without removing it from the
729    /// socket's receive queue.
730    const PEEK    = 0x0004;
731    /// On byte-stream sockets, block until the full amount
732    /// of data can be returned.
733    const WAITALL = 0x0010;
734  }
735}
736
737bitflags! {
738  /// File descriptor rights, determining which actions may be
739  /// performed.
740  #[repr(C)]
741  pub struct rights: u64 {
742    /// The right to invoke [`fd_datasync()`](fn.fd_datasync.html).
743    ///
744    /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
745    /// invoke [`file_open()`](fn.file_open.html) with [`DSYNC`](struct.fdflags.html#associatedconstant.DSYNC).
746    const FD_DATASYNC           = 0x0000000000000001;
747    /// The right to invoke [`fd_read()`](fn.fd_read.html) and [`sock_recv()`](fn.sock_recv.html).
748    ///
749    /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, includes the right to
750    /// invoke [`mem_map()`](fn.mem_map.html) with memory protection option
751    /// [`READ`](struct.mprot.html#associatedconstant.READ).
752    ///
753    /// If [`FD_SEEK`](struct.rights.html#associatedconstant.FD_SEEK) is set, includes the right to invoke
754    /// [`fd_pread()`](fn.fd_pread.html).
755    const FD_READ               = 0x0000000000000002;
756    /// The right to invoke [`fd_seek()`](fn.fd_seek.html). This flag implies
757    /// [`FD_TELL`](struct.rights.html#associatedconstant.FD_TELL).
758    const FD_SEEK               = 0x0000000000000004;
759    /// The right to invoke [`fd_stat_put()`](fn.fd_stat_put.html) with
760    /// [`FLAGS`](struct.fdsflags.html#associatedconstant.FLAGS).
761    const FD_STAT_PUT_FLAGS     = 0x0000000000000008;
762    /// The right to invoke [`fd_sync()`](fn.fd_sync.html).
763    ///
764    /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
765    /// invoke [`file_open()`](fn.file_open.html) with [`RSYNC`](struct.fdflags.html#associatedconstant.RSYNC) and
766    /// [`DSYNC`](struct.fdflags.html#associatedconstant.DSYNC).
767    const FD_SYNC               = 0x0000000000000010;
768    /// The right to invoke [`fd_seek()`](fn.fd_seek.html) in such a way that the
769    /// file offset remains unaltered (i.e., [`CUR`](enum.whence.html#variant.CUR) with
770    /// offset zero).
771    const FD_TELL               = 0x0000000000000020;
772    /// The right to invoke [`fd_write()`](fn.fd_write.html) and [`sock_send()`](fn.sock_send.html).
773    ///
774    /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, includes the right to
775    /// invoke [`mem_map()`](fn.mem_map.html) with memory protection option
776    /// [`WRITE`](struct.mprot.html#associatedconstant.WRITE).
777    ///
778    /// If [`FD_SEEK`](struct.rights.html#associatedconstant.FD_SEEK) is set, includes the right to
779    /// invoke [`fd_pwrite()`](fn.fd_pwrite.html).
780    const FD_WRITE              = 0x0000000000000040;
781    /// The right to invoke [`file_advise()`](fn.file_advise.html).
782    const FILE_ADVISE           = 0x0000000000000080;
783    /// The right to invoke [`file_allocate()`](fn.file_allocate.html).
784    const FILE_ALLOCATE         = 0x0000000000000100;
785    /// The right to invoke [`file_create()`](fn.file_create.html) with
786    /// [`DIRECTORY`](enum.filetype.html#variant.DIRECTORY).
787    const FILE_CREATE_DIRECTORY = 0x0000000000000200;
788    /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, the right to invoke
789    /// [`file_open()`](fn.file_open.html) with [`CREAT`](struct.oflags.html#associatedconstant.CREAT).
790    const FILE_CREATE_FILE      = 0x0000000000000400;
791    /// The right to invoke [`file_link()`](fn.file_link.html) with the file
792    /// descriptor as the source directory.
793    const FILE_LINK_SOURCE      = 0x0000000000001000;
794    /// The right to invoke [`file_link()`](fn.file_link.html) with the file
795    /// descriptor as the target directory.
796    const FILE_LINK_TARGET      = 0x0000000000002000;
797    /// The right to invoke [`file_open()`](fn.file_open.html).
798    const FILE_OPEN             = 0x0000000000004000;
799    /// The right to invoke [`file_readdir()`](fn.file_readdir.html).
800    const FILE_READDIR          = 0x0000000000008000;
801    /// The right to invoke [`file_readlink()`](fn.file_readlink.html).
802    const FILE_READLINK         = 0x0000000000010000;
803    /// The right to invoke [`file_rename()`](fn.file_rename.html) with the file
804    /// descriptor as the source directory.
805    const FILE_RENAME_SOURCE    = 0x0000000000020000;
806    /// The right to invoke [`file_rename()`](fn.file_rename.html) with the file
807    /// descriptor as the target directory.
808    const FILE_RENAME_TARGET    = 0x0000000000040000;
809    /// The right to invoke [`file_stat_fget()`](fn.file_stat_fget.html).
810    const FILE_STAT_FGET        = 0x0000000000080000;
811    /// The right to invoke [`file_stat_fput()`](fn.file_stat_fput.html) with
812    /// [`SIZE`](struct.fsflags.html#associatedconstant.SIZE).
813    ///
814    /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
815    /// invoke [`file_open()`](fn.file_open.html) with [`TRUNC`](struct.oflags.html#associatedconstant.TRUNC).
816    const FILE_STAT_FPUT_SIZE   = 0x0000000000100000;
817    /// The right to invoke [`file_stat_fput()`](fn.file_stat_fput.html) with
818    /// [`ATIM`](struct.fsflags.html#associatedconstant.ATIM), [`ATIM_NOW`](struct.fsflags.html#associatedconstant.ATIM_NOW), [`MTIM`](struct.fsflags.html#associatedconstant.MTIM),
819    /// and [`MTIM_NOW`](struct.fsflags.html#associatedconstant.MTIM_NOW).
820    const FILE_STAT_FPUT_TIMES  = 0x0000000000200000;
821    /// The right to invoke [`file_stat_get()`](fn.file_stat_get.html).
822    const FILE_STAT_GET         = 0x0000000000400000;
823    /// The right to invoke [`file_stat_put()`](fn.file_stat_put.html) with
824    /// [`ATIM`](struct.fsflags.html#associatedconstant.ATIM), [`ATIM_NOW`](struct.fsflags.html#associatedconstant.ATIM_NOW), [`MTIM`](struct.fsflags.html#associatedconstant.MTIM),
825    /// and [`MTIM_NOW`](struct.fsflags.html#associatedconstant.MTIM_NOW).
826    const FILE_STAT_PUT_TIMES   = 0x0000000000800000;
827    /// The right to invoke [`file_symlink()`](fn.file_symlink.html).
828    const FILE_SYMLINK          = 0x0000000001000000;
829    /// The right to invoke [`file_unlink()`](fn.file_unlink.html).
830    const FILE_UNLINK           = 0x0000000002000000;
831    /// The right to invoke [`mem_map()`](fn.mem_map.html) with [`mprot`](struct.mprot.html) set to
832    /// zero.
833    const MEM_MAP               = 0x0000000004000000;
834    /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, the right to invoke
835    /// [`mem_map()`](fn.mem_map.html) with [`EXEC`](struct.mprot.html#associatedconstant.EXEC).
836    const MEM_MAP_EXEC          = 0x0000000008000000;
837    /// If [`FD_READ`](struct.rights.html#associatedconstant.FD_READ) is set, includes the right to
838    /// invoke [`poll()`](fn.poll.html) to subscribe to [`FD_READ`](enum.eventtype.html#variant.FD_READ).
839    ///
840    /// If [`FD_WRITE`](struct.rights.html#associatedconstant.FD_WRITE) is set, includes the right to
841    /// invoke [`poll()`](fn.poll.html) to subscribe to [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
842    const POLL_FD_READWRITE     = 0x0000000010000000;
843    /// The right to invoke [`poll()`](fn.poll.html) to subscribe to
844    /// [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
845    const POLL_PROC_TERMINATE   = 0x0000000040000000;
846    /// The right to invoke [`proc_exec()`](fn.proc_exec.html).
847    const PROC_EXEC             = 0x0000000100000000;
848    /// The right to invoke [`sock_shutdown()`](fn.sock_shutdown.html).
849    const SOCK_SHUTDOWN         = 0x0000008000000000;
850  }
851}
852
853bitflags! {
854  /// Flags returned by [`sock_recv()`](fn.sock_recv.html).
855  #[repr(C)]
856  pub struct roflags: u16 {
857    /// Returned by [`sock_recv()`](fn.sock_recv.html): List of file descriptors
858    /// has been truncated.
859    const FDS_TRUNCATED  = 0x0001;
860    /// Returned by [`sock_recv()`](fn.sock_recv.html): Message data has been
861    /// truncated.
862    const DATA_TRUNCATED = 0x0008;
863  }
864}
865
866/// Indicates whether an object is stored in private or shared
867/// memory.
868#[repr(u8)]
869#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
870#[non_exhaustive]
871pub enum scope {
872  /// The object is stored in private memory.
873  PRIVATE = 4,
874  /// The object is stored in shared memory.
875  SHARED  = 8,
876}
877
878bitflags! {
879  /// Which channels on a socket need to be shut down.
880  #[repr(C)]
881  pub struct sdflags: u8 {
882    /// Disables further receive operations.
883    const RD = 0x01;
884    /// Disables further send operations.
885    const WR = 0x02;
886  }
887}
888
889bitflags! {
890  /// Flags provided to [`sock_send()`](fn.sock_send.html). As there are currently no flags
891  /// defined, it must be set to zero.
892  #[repr(C)]
893  pub struct siflags: u16 {
894    const DEFAULT = 0;
895  }
896}
897
898/// Signal condition.
899#[repr(u8)]
900#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
901#[non_exhaustive]
902pub enum signal {
903  /// Process abort signal.
904  ///
905  /// Action: Terminates the process.
906  ABRT   =  1,
907  /// Alarm clock.
908  ///
909  /// Action: Terminates the process.
910  ALRM   =  2,
911  /// Access to an undefined portion of a memory object.
912  ///
913  /// Action: Terminates the process.
914  BUS    =  3,
915  /// Child process terminated, stopped, or continued.
916  ///
917  /// Action: Ignored.
918  CHLD   =  4,
919  /// Continue executing, if stopped.
920  ///
921  /// Action: Continues executing, if stopped.
922  CONT   =  5,
923  /// Erroneous arithmetic operation.
924  ///
925  /// Action: Terminates the process.
926  FPE    =  6,
927  /// Hangup.
928  ///
929  /// Action: Terminates the process.
930  HUP    =  7,
931  /// Illegal instruction.
932  ///
933  /// Action: Terminates the process.
934  ILL    =  8,
935  /// Terminate interrupt signal.
936  ///
937  /// Action: Terminates the process.
938  INT    =  9,
939  /// Kill.
940  ///
941  /// Action: Terminates the process.
942  KILL   = 10,
943  /// Write on a pipe with no one to read it.
944  ///
945  /// Action: Ignored.
946  PIPE   = 11,
947  /// Terminal quit signal.
948  ///
949  /// Action: Terminates the process.
950  QUIT   = 12,
951  /// Invalid memory reference.
952  ///
953  /// Action: Terminates the process.
954  SEGV   = 13,
955  /// Stop executing.
956  ///
957  /// Action: Stops executing.
958  STOP   = 14,
959  /// Bad system call.
960  ///
961  /// Action: Terminates the process.
962  SYS    = 15,
963  /// Termination signal.
964  ///
965  /// Action: Terminates the process.
966  TERM   = 16,
967  /// Trace/breakpoint trap.
968  ///
969  /// Action: Terminates the process.
970  TRAP   = 17,
971  /// Terminal stop signal.
972  ///
973  /// Action: Stops executing.
974  TSTP   = 18,
975  /// Background process attempting read.
976  ///
977  /// Action: Stops executing.
978  TTIN   = 19,
979  /// Background process attempting write.
980  ///
981  /// Action: Stops executing.
982  TTOU   = 20,
983  /// High bandwidth data is available at a socket.
984  ///
985  /// Action: Ignored.
986  URG    = 21,
987  /// User-defined signal 1.
988  ///
989  /// Action: Terminates the process.
990  USR1   = 22,
991  /// User-defined signal 2.
992  ///
993  /// Action: Terminates the process.
994  USR2   = 23,
995  /// Virtual timer expired.
996  ///
997  /// Action: Terminates the process.
998  VTALRM = 24,
999  /// CPU time limit exceeded.
1000  ///
1001  /// Action: Terminates the process.
1002  XCPU   = 25,
1003  /// File size limit exceeded.
1004  ///
1005  /// Action: Terminates the process.
1006  XFSZ   = 26,
1007}
1008
1009bitflags! {
1010  /// Flags determining how the timestamp provided in
1011  /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) should be interpreted.
1012  #[repr(C)]
1013  pub struct subclockflags: u16 {
1014    /// If set, treat the timestamp provided in
1015    /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) as an absolute timestamp
1016    /// of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id).
1017    ///
1018    /// If clear, treat the timestamp provided in
1019    /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) relative to the current
1020    /// time value of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id).
1021    const ABSTIME = 0x0001;
1022  }
1023}
1024
1025bitflags! {
1026  /// Flags influencing the method of polling for read or writing on
1027  /// a file descriptor.
1028  #[repr(C)]
1029  pub struct subrwflags: u16 {
1030    /// Deprecated. Must be set by callers and ignored by
1031    /// implementations.
1032    const POLL = 0x0001;
1033  }
1034}
1035
1036/// Unique system-local identifier of a thread. This identifier is
1037/// only valid during the lifetime of the thread.
1038///
1039/// Threads must be aware of their thread identifier, as it is
1040/// written it into locks when acquiring them for writing. It is
1041/// not advised to use these identifiers for any other purpose.
1042///
1043/// As the thread identifier is also stored in [`lock`](struct.lock.html) when
1044/// [`LOCK_WRLOCKED`](constant.LOCK_WRLOCKED.html) is set, the top two bits of the thread
1045/// must always be set to zero.
1046#[repr(C)]
1047#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1048pub struct tid(pub u32);
1049
1050/// Timestamp in nanoseconds.
1051pub type timestamp = u64;
1052
1053bitflags! {
1054  /// Specifies whether files are unlinked or directories are
1055  /// removed.
1056  #[repr(C)]
1057  pub struct ulflags: u8 {
1058    /// If set, removes a directory. Otherwise, unlinks any
1059    /// non-directory file.
1060    const REMOVEDIR = 0x01;
1061  }
1062}
1063
1064/// User-provided value that can be attached to objects that is
1065/// retained when extracted from the kernel.
1066pub type userdata = u64;
1067
1068/// Relative to which position the offset of the file descriptor
1069/// should be set.
1070#[repr(u8)]
1071#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1072#[non_exhaustive]
1073pub enum whence {
1074  /// Seek relative to current position.
1075  CUR = 1,
1076  /// Seek relative to end-of-file.
1077  END = 2,
1078  /// Seek relative to start-of-file.
1079  SET = 3,
1080}
1081
1082/// Auxiliary vector entry.
1083///
1084/// The auxiliary vector is a list of key-value pairs that is
1085/// provided to the process on startup. Unlike structures, it is
1086/// extensible, as it is possible to add new records later on.
1087/// The auxiliary vector is always terminated by an entry having
1088/// type [`NULL`](enum.auxtype.html#variant.NULL).
1089///
1090/// The auxiliary vector is part of the x86-64 ABI, but is used by
1091/// this environment on all architectures.
1092#[repr(C)]
1093#[derive(Copy, Clone)]
1094pub struct auxv {
1095  /// The type of the auxiliary vector entry.
1096  pub a_type: auxtype,
1097  pub union: auxv_union
1098}
1099/// A union inside `auxv`.
1100#[repr(C)]
1101#[derive(Copy, Clone)]
1102pub union auxv_union {
1103  /// Used when [`a_type`](struct.auxv.html#structfield.a_type) is [`ARGDATALEN`](enum.auxtype.html#variant.ARGDATALEN), [`CANARYLEN`](enum.auxtype.html#variant.CANARYLEN), [`NCPUS`](enum.auxtype.html#variant.NCPUS), [`PAGESZ`](enum.auxtype.html#variant.PAGESZ), [`PHNUM`](enum.auxtype.html#variant.PHNUM), or [`TID`](enum.auxtype.html#variant.TID).
1104  /// A numerical value.
1105  pub a_val: usize,
1106  /// Used when [`a_type`](struct.auxv.html#structfield.a_type) is [`ARGDATA`](enum.auxtype.html#variant.ARGDATA), [`BASE`](enum.auxtype.html#variant.BASE), [`CANARY`](enum.auxtype.html#variant.CANARY), [`PHDR`](enum.auxtype.html#variant.PHDR), [`PID`](enum.auxtype.html#variant.PID), or [`SYSINFO_EHDR`](enum.auxtype.html#variant.SYSINFO_EHDR).
1107  /// A pointer value.
1108  pub a_ptr: *mut (),
1109}
1110#[test]
1111#[cfg(target_pointer_width = "32")]
1112fn auxv_layout_test_32() {
1113  assert_eq!(core::mem::size_of::<auxv>(), 8);
1114  assert_eq!(core::mem::align_of::<auxv>(), 4);
1115  let mut obj = auxv {
1116    a_type: auxtype::ARGDATA,
1117    union: auxv_union {
1118      a_val: 0,
1119    },
1120  };
1121  let base = &obj as *const _ as usize;
1122  assert_eq!(&obj.a_type as *const _ as usize - base, 0);
1123  obj.union.a_val = 0;
1124  unsafe {
1125    assert_eq!(&obj.union.a_val as *const _ as usize - base, 4);
1126  }
1127  obj.union.a_ptr = 0 as *mut ();
1128  unsafe {
1129    assert_eq!(&obj.union.a_ptr as *const _ as usize - base, 4);
1130  }
1131}
1132#[test]
1133#[cfg(target_pointer_width = "64")]
1134fn auxv_layout_test_64() {
1135  assert_eq!(core::mem::size_of::<auxv>(), 16);
1136  assert_eq!(core::mem::align_of::<auxv>(), 8);
1137  let mut obj = auxv {
1138    a_type: auxtype::ARGDATA,
1139    union: auxv_union {
1140      a_val: 0,
1141    },
1142  };
1143  let base = &obj as *const _ as usize;
1144  assert_eq!(&obj.a_type as *const _ as usize - base, 0);
1145  obj.union.a_val = 0;
1146  unsafe {
1147    assert_eq!(&obj.union.a_val as *const _ as usize - base, 8);
1148  }
1149  obj.union.a_ptr = 0 as *mut ();
1150  unsafe {
1151    assert_eq!(&obj.union.a_ptr as *const _ as usize - base, 8);
1152  }
1153}
1154
1155/// A region of memory for scatter/gather writes.
1156#[repr(C)]
1157#[derive(Copy, Clone)]
1158pub struct ciovec {
1159  /// The address and length of the buffer to be written.
1160  pub buf: (*const (), usize),
1161}
1162#[test]
1163#[cfg(target_pointer_width = "32")]
1164fn ciovec_layout_test_32() {
1165  assert_eq!(core::mem::size_of::<ciovec>(), 8);
1166  assert_eq!(core::mem::align_of::<ciovec>(), 4);
1167  let obj = ciovec {
1168    buf: (0 as *const _, 0),
1169  };
1170  let base = &obj as *const _ as usize;
1171  assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
1172  assert_eq!(&obj.buf.1 as *const _ as usize - base, 4);
1173}
1174#[test]
1175#[cfg(target_pointer_width = "64")]
1176fn ciovec_layout_test_64() {
1177  assert_eq!(core::mem::size_of::<ciovec>(), 16);
1178  assert_eq!(core::mem::align_of::<ciovec>(), 8);
1179  let obj = ciovec {
1180    buf: (0 as *const _, 0),
1181  };
1182  let base = &obj as *const _ as usize;
1183  assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
1184  assert_eq!(&obj.buf.1 as *const _ as usize - base, 8);
1185}
1186
1187/// A directory entry.
1188#[repr(C)]
1189#[derive(Copy, Clone)]
1190pub struct dirent {
1191  /// The offset of the next directory entry stored in this
1192  /// directory.
1193  pub d_next: dircookie,
1194  /// The serial number of the file referred to by this
1195  /// directory entry.
1196  pub d_ino: inode,
1197  /// The length of the name of the directory entry.
1198  pub d_namlen: u32,
1199  /// The type of the file referred to by this directory
1200  /// entry.
1201  pub d_type: filetype,
1202}
1203#[test]
1204fn dirent_layout_test() {
1205  assert_eq!(core::mem::size_of::<dirent>(), 24);
1206  assert_eq!(core::mem::align_of::<dirent>(), 8);
1207  let obj = dirent {
1208    d_next: dircookie(0),
1209    d_ino: inode(0),
1210    d_namlen: 0,
1211    d_type: filetype::UNKNOWN,
1212  };
1213  let base = &obj as *const _ as usize;
1214  assert_eq!(&obj.d_next as *const _ as usize - base, 0);
1215  assert_eq!(&obj.d_ino as *const _ as usize - base, 8);
1216  assert_eq!(&obj.d_namlen as *const _ as usize - base, 16);
1217  assert_eq!(&obj.d_type as *const _ as usize - base, 20);
1218}
1219
1220/// An event that occurred.
1221#[repr(C)]
1222#[derive(Copy, Clone)]
1223pub struct event {
1224  /// User-provided value that got attached to
1225  /// [`subscription.userdata`](struct.subscription.html#structfield.userdata).
1226  pub userdata: userdata,
1227  /// If non-zero, an error that occurred while processing
1228  /// the subscription request.
1229  pub error: errno,
1230  /// The type of the event that occurred.
1231  pub r#type: eventtype,
1232  pub union: event_union
1233}
1234/// A union inside `event`.
1235#[repr(C)]
1236#[derive(Copy, Clone)]
1237pub union event_union {
1238  /// Used when [`type`](struct.event.html#structfield.type) is [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
1239  pub fd_readwrite: event_fd_readwrite,
1240  /// Used when [`type`](struct.event.html#structfield.type) is [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
1241  pub proc_terminate: event_proc_terminate,
1242}
1243#[repr(C)]
1244#[derive(Copy, Clone)]
1245pub struct event_fd_readwrite {
1246  /// The number of bytes available
1247  /// for reading or writing.
1248  pub nbytes: filesize,
1249  /// Obsolete.
1250  pub unused: [u8; 4],
1251  /// The state of the file
1252  /// descriptor.
1253  pub flags: eventrwflags,
1254}
1255#[repr(C)]
1256#[derive(Copy, Clone)]
1257pub struct event_proc_terminate {
1258  /// Obsolete.
1259  pub unused: [u8; 4],
1260  /// If zero, the process has
1261  /// exited.
1262  /// Otherwise, the signal
1263  /// condition causing it to
1264  /// terminated.
1265  pub signal: signal,
1266  /// If exited, the exit code of
1267  /// the process.
1268  pub exitcode: exitcode,
1269}
1270#[test]
1271fn event_layout_test() {
1272  assert_eq!(core::mem::size_of::<event>(), 32);
1273  assert_eq!(core::mem::align_of::<event>(), 8);
1274  let mut obj = event {
1275    userdata: 0,
1276    error: errno::SUCCESS,
1277    r#type: eventtype::CLOCK,
1278    union: event_union {
1279      fd_readwrite: event_fd_readwrite {
1280        nbytes: 0,
1281        unused: [0; 4],
1282        flags: eventrwflags::HANGUP,
1283      },
1284    },
1285  };
1286  let base = &obj as *const _ as usize;
1287  assert_eq!(&obj.userdata as *const _ as usize - base, 0);
1288  assert_eq!(&obj.error as *const _ as usize - base, 8);
1289  assert_eq!(&obj.r#type as *const _ as usize - base, 10);
1290  obj.union.fd_readwrite = event_fd_readwrite {
1291    nbytes: 0,
1292    unused: [0; 4],
1293    flags: eventrwflags::HANGUP,
1294  };
1295  unsafe {
1296    assert_eq!(&obj.union.fd_readwrite.nbytes as *const _ as usize - base, 16);
1297    assert_eq!(&obj.union.fd_readwrite.unused as *const _ as usize - base, 24);
1298    assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 28);
1299  }
1300  obj.union.proc_terminate = event_proc_terminate {
1301    unused: [0; 4],
1302    signal: signal::ABRT,
1303    exitcode: 0,
1304  };
1305  unsafe {
1306    assert_eq!(&obj.union.proc_terminate.unused as *const _ as usize - base, 16);
1307    assert_eq!(&obj.union.proc_terminate.signal as *const _ as usize - base, 20);
1308    assert_eq!(&obj.union.proc_terminate.exitcode as *const _ as usize - base, 24);
1309  }
1310}
1311
1312/// File descriptor attributes.
1313#[repr(C)]
1314#[derive(Copy, Clone)]
1315pub struct fdstat {
1316  /// File type.
1317  pub fs_filetype: filetype,
1318  /// File descriptor flags.
1319  pub fs_flags: fdflags,
1320  /// Rights that apply to this file descriptor.
1321  pub fs_rights_base: rights,
1322  /// Maximum set of rights that can be installed on new
1323  /// file descriptors that are created through this file
1324  /// descriptor, e.g., through [`file_open()`](fn.file_open.html).
1325  pub fs_rights_inheriting: rights,
1326}
1327#[test]
1328fn fdstat_layout_test() {
1329  assert_eq!(core::mem::size_of::<fdstat>(), 24);
1330  assert_eq!(core::mem::align_of::<fdstat>(), 8);
1331  let obj = fdstat {
1332    fs_filetype: filetype::UNKNOWN,
1333    fs_flags: fdflags::APPEND,
1334    fs_rights_base: rights::FD_DATASYNC,
1335    fs_rights_inheriting: rights::FD_DATASYNC,
1336  };
1337  let base = &obj as *const _ as usize;
1338  assert_eq!(&obj.fs_filetype as *const _ as usize - base, 0);
1339  assert_eq!(&obj.fs_flags as *const _ as usize - base, 2);
1340  assert_eq!(&obj.fs_rights_base as *const _ as usize - base, 8);
1341  assert_eq!(&obj.fs_rights_inheriting as *const _ as usize - base, 16);
1342}
1343
1344/// File attributes.
1345#[repr(C)]
1346#[derive(Copy, Clone)]
1347pub struct filestat {
1348  /// Device ID of device containing the file.
1349  pub st_dev: device,
1350  /// File serial number.
1351  pub st_ino: inode,
1352  /// File type.
1353  pub st_filetype: filetype,
1354  /// Number of hard links to the file.
1355  pub st_nlink: linkcount,
1356  /// For regular files, the file size in bytes. For
1357  /// symbolic links, the length in bytes of the pathname
1358  /// contained in the symbolic link.
1359  pub st_size: filesize,
1360  /// Last data access timestamp.
1361  pub st_atim: timestamp,
1362  /// Last data modification timestamp.
1363  pub st_mtim: timestamp,
1364  /// Last file status change timestamp.
1365  pub st_ctim: timestamp,
1366}
1367#[test]
1368fn filestat_layout_test() {
1369  assert_eq!(core::mem::size_of::<filestat>(), 56);
1370  assert_eq!(core::mem::align_of::<filestat>(), 8);
1371  let obj = filestat {
1372    st_dev: device(0),
1373    st_ino: inode(0),
1374    st_filetype: filetype::UNKNOWN,
1375    st_nlink: 0,
1376    st_size: 0,
1377    st_atim: 0,
1378    st_mtim: 0,
1379    st_ctim: 0,
1380  };
1381  let base = &obj as *const _ as usize;
1382  assert_eq!(&obj.st_dev as *const _ as usize - base, 0);
1383  assert_eq!(&obj.st_ino as *const _ as usize - base, 8);
1384  assert_eq!(&obj.st_filetype as *const _ as usize - base, 16);
1385  assert_eq!(&obj.st_nlink as *const _ as usize - base, 20);
1386  assert_eq!(&obj.st_size as *const _ as usize - base, 24);
1387  assert_eq!(&obj.st_atim as *const _ as usize - base, 32);
1388  assert_eq!(&obj.st_mtim as *const _ as usize - base, 40);
1389  assert_eq!(&obj.st_ctim as *const _ as usize - base, 48);
1390}
1391
1392/// A region of memory for scatter/gather reads.
1393#[repr(C)]
1394#[derive(Copy, Clone)]
1395pub struct iovec {
1396  /// The address and length of the buffer to be filled.
1397  pub buf: (*mut (), usize),
1398}
1399#[test]
1400#[cfg(target_pointer_width = "32")]
1401fn iovec_layout_test_32() {
1402  assert_eq!(core::mem::size_of::<iovec>(), 8);
1403  assert_eq!(core::mem::align_of::<iovec>(), 4);
1404  let obj = iovec {
1405    buf: (0 as *mut _, 0),
1406  };
1407  let base = &obj as *const _ as usize;
1408  assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
1409  assert_eq!(&obj.buf.1 as *const _ as usize - base, 4);
1410}
1411#[test]
1412#[cfg(target_pointer_width = "64")]
1413fn iovec_layout_test_64() {
1414  assert_eq!(core::mem::size_of::<iovec>(), 16);
1415  assert_eq!(core::mem::align_of::<iovec>(), 8);
1416  let obj = iovec {
1417    buf: (0 as *mut _, 0),
1418  };
1419  let base = &obj as *const _ as usize;
1420  assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
1421  assert_eq!(&obj.buf.1 as *const _ as usize - base, 8);
1422}
1423
1424/// Path lookup properties.
1425#[repr(C)]
1426#[derive(Copy, Clone)]
1427pub struct lookup {
1428  /// The working directory at which the resolution of the
1429  /// path starts.
1430  pub fd: fd,
1431  /// Flags determining the method of how the path is
1432  /// resolved.
1433  pub flags: lookupflags,
1434}
1435#[test]
1436fn lookup_layout_test() {
1437  assert_eq!(core::mem::size_of::<lookup>(), 8);
1438  assert_eq!(core::mem::align_of::<lookup>(), 4);
1439  let obj = lookup {
1440    fd: fd(0),
1441    flags: lookupflags::SYMLINK_FOLLOW,
1442  };
1443  let base = &obj as *const _ as usize;
1444  assert_eq!(&obj.fd as *const _ as usize - base, 0);
1445  assert_eq!(&obj.flags as *const _ as usize - base, 4);
1446}
1447
1448/// Entry point for a process (`_start`).
1449///
1450/// **auxv**:
1451/// The auxiliary vector. See [`auxv`](struct.auxv.html).
1452pub type processentry = unsafe extern "C" fn(
1453  auxv: *const auxv,
1454) -> ();
1455
1456/// Arguments of [`sock_recv()`](fn.sock_recv.html).
1457#[repr(C)]
1458#[derive(Copy, Clone)]
1459pub struct recv_in {
1460  /// List of scatter/gather vectors where message data
1461  /// should be stored.
1462  pub ri_data: (*const iovec, usize),
1463  /// Buffer where numbers of incoming file descriptors
1464  /// should be stored.
1465  pub ri_fds: (*mut fd, usize),
1466  /// Message flags.
1467  pub ri_flags: riflags,
1468}
1469#[test]
1470#[cfg(target_pointer_width = "32")]
1471fn recv_in_layout_test_32() {
1472  assert_eq!(core::mem::size_of::<recv_in>(), 20);
1473  assert_eq!(core::mem::align_of::<recv_in>(), 4);
1474  let obj = recv_in {
1475    ri_data: (0 as *const _, 0),
1476    ri_fds: (0 as *mut _, 0),
1477    ri_flags: riflags::PEEK,
1478  };
1479  let base = &obj as *const _ as usize;
1480  assert_eq!(&obj.ri_data.0 as *const _ as usize - base, 0);
1481  assert_eq!(&obj.ri_data.1 as *const _ as usize - base, 4);
1482  assert_eq!(&obj.ri_fds.0 as *const _ as usize - base, 8);
1483  assert_eq!(&obj.ri_fds.1 as *const _ as usize - base, 12);
1484  assert_eq!(&obj.ri_flags as *const _ as usize - base, 16);
1485}
1486#[test]
1487#[cfg(target_pointer_width = "64")]
1488fn recv_in_layout_test_64() {
1489  assert_eq!(core::mem::size_of::<recv_in>(), 40);
1490  assert_eq!(core::mem::align_of::<recv_in>(), 8);
1491  let obj = recv_in {
1492    ri_data: (0 as *const _, 0),
1493    ri_fds: (0 as *mut _, 0),
1494    ri_flags: riflags::PEEK,
1495  };
1496  let base = &obj as *const _ as usize;
1497  assert_eq!(&obj.ri_data.0 as *const _ as usize - base, 0);
1498  assert_eq!(&obj.ri_data.1 as *const _ as usize - base, 8);
1499  assert_eq!(&obj.ri_fds.0 as *const _ as usize - base, 16);
1500  assert_eq!(&obj.ri_fds.1 as *const _ as usize - base, 24);
1501  assert_eq!(&obj.ri_flags as *const _ as usize - base, 32);
1502}
1503
1504/// Results of [`sock_recv()`](fn.sock_recv.html).
1505#[repr(C)]
1506#[derive(Copy, Clone)]
1507pub struct recv_out {
1508  /// Number of bytes stored in [`recv_in.ri_data`](struct.recv_in.html#structfield.ri_data).
1509  pub ro_datalen: usize,
1510  /// Number of file descriptors stored in [`recv_in.ri_fds`](struct.recv_in.html#structfield.ri_fds).
1511  pub ro_fdslen: usize,
1512  /// Fields that were used by previous implementations.
1513  pub ro_unused: [u8; 40],
1514  /// Message flags.
1515  pub ro_flags: roflags,
1516}
1517#[test]
1518#[cfg(target_pointer_width = "32")]
1519fn recv_out_layout_test_32() {
1520  assert_eq!(core::mem::size_of::<recv_out>(), 52);
1521  assert_eq!(core::mem::align_of::<recv_out>(), 4);
1522  let obj = recv_out {
1523    ro_datalen: 0,
1524    ro_fdslen: 0,
1525    ro_unused: [0; 40],
1526    ro_flags: roflags::FDS_TRUNCATED,
1527  };
1528  let base = &obj as *const _ as usize;
1529  assert_eq!(&obj.ro_datalen as *const _ as usize - base, 0);
1530  assert_eq!(&obj.ro_fdslen as *const _ as usize - base, 4);
1531  assert_eq!(&obj.ro_unused as *const _ as usize - base, 8);
1532  assert_eq!(&obj.ro_flags as *const _ as usize - base, 48);
1533}
1534#[test]
1535#[cfg(target_pointer_width = "64")]
1536fn recv_out_layout_test_64() {
1537  assert_eq!(core::mem::size_of::<recv_out>(), 64);
1538  assert_eq!(core::mem::align_of::<recv_out>(), 8);
1539  let obj = recv_out {
1540    ro_datalen: 0,
1541    ro_fdslen: 0,
1542    ro_unused: [0; 40],
1543    ro_flags: roflags::FDS_TRUNCATED,
1544  };
1545  let base = &obj as *const _ as usize;
1546  assert_eq!(&obj.ro_datalen as *const _ as usize - base, 0);
1547  assert_eq!(&obj.ro_fdslen as *const _ as usize - base, 8);
1548  assert_eq!(&obj.ro_unused as *const _ as usize - base, 16);
1549  assert_eq!(&obj.ro_flags as *const _ as usize - base, 56);
1550}
1551
1552/// Arguments of [`sock_send()`](fn.sock_send.html).
1553#[repr(C)]
1554#[derive(Copy, Clone)]
1555pub struct send_in {
1556  /// List of scatter/gather vectors where message data
1557  /// should be retrieved.
1558  pub si_data: (*const ciovec, usize),
1559  /// File descriptors that need to be attached to the
1560  /// message.
1561  pub si_fds: (*const fd, usize),
1562  /// Message flags.
1563  pub si_flags: siflags,
1564}
1565#[test]
1566#[cfg(target_pointer_width = "32")]
1567fn send_in_layout_test_32() {
1568  assert_eq!(core::mem::size_of::<send_in>(), 20);
1569  assert_eq!(core::mem::align_of::<send_in>(), 4);
1570  let obj = send_in {
1571    si_data: (0 as *const _, 0),
1572    si_fds: (0 as *const _, 0),
1573    si_flags: siflags::DEFAULT,
1574  };
1575  let base = &obj as *const _ as usize;
1576  assert_eq!(&obj.si_data.0 as *const _ as usize - base, 0);
1577  assert_eq!(&obj.si_data.1 as *const _ as usize - base, 4);
1578  assert_eq!(&obj.si_fds.0 as *const _ as usize - base, 8);
1579  assert_eq!(&obj.si_fds.1 as *const _ as usize - base, 12);
1580  assert_eq!(&obj.si_flags as *const _ as usize - base, 16);
1581}
1582#[test]
1583#[cfg(target_pointer_width = "64")]
1584fn send_in_layout_test_64() {
1585  assert_eq!(core::mem::size_of::<send_in>(), 40);
1586  assert_eq!(core::mem::align_of::<send_in>(), 8);
1587  let obj = send_in {
1588    si_data: (0 as *const _, 0),
1589    si_fds: (0 as *const _, 0),
1590    si_flags: siflags::DEFAULT,
1591  };
1592  let base = &obj as *const _ as usize;
1593  assert_eq!(&obj.si_data.0 as *const _ as usize - base, 0);
1594  assert_eq!(&obj.si_data.1 as *const _ as usize - base, 8);
1595  assert_eq!(&obj.si_fds.0 as *const _ as usize - base, 16);
1596  assert_eq!(&obj.si_fds.1 as *const _ as usize - base, 24);
1597  assert_eq!(&obj.si_flags as *const _ as usize - base, 32);
1598}
1599
1600/// Results of [`sock_send()`](fn.sock_send.html).
1601#[repr(C)]
1602#[derive(Copy, Clone)]
1603pub struct send_out {
1604  /// Number of bytes transmitted.
1605  pub so_datalen: usize,
1606}
1607#[test]
1608#[cfg(target_pointer_width = "32")]
1609fn send_out_layout_test_32() {
1610  assert_eq!(core::mem::size_of::<send_out>(), 4);
1611  assert_eq!(core::mem::align_of::<send_out>(), 4);
1612  let obj = send_out {
1613    so_datalen: 0,
1614  };
1615  let base = &obj as *const _ as usize;
1616  assert_eq!(&obj.so_datalen as *const _ as usize - base, 0);
1617}
1618#[test]
1619#[cfg(target_pointer_width = "64")]
1620fn send_out_layout_test_64() {
1621  assert_eq!(core::mem::size_of::<send_out>(), 8);
1622  assert_eq!(core::mem::align_of::<send_out>(), 8);
1623  let obj = send_out {
1624    so_datalen: 0,
1625  };
1626  let base = &obj as *const _ as usize;
1627  assert_eq!(&obj.so_datalen as *const _ as usize - base, 0);
1628}
1629
1630/// Subscription to an event.
1631#[repr(C)]
1632#[derive(Copy, Clone)]
1633pub struct subscription {
1634  /// User-provided value that is attached to the
1635  /// subscription in the kernel and returned through
1636  /// [`event.userdata`](struct.event.html#structfield.userdata).
1637  pub userdata: userdata,
1638  /// Used by previous implementations. Ignored.
1639  pub unused: u16,
1640  /// The type of the event to which to subscribe.
1641  ///
1642  /// Currently, [`CONDVAR`](enum.eventtype.html#variant.CONDVAR),
1643  /// [`LOCK_RDLOCK`](enum.eventtype.html#variant.LOCK_RDLOCK), and [`LOCK_WRLOCK`](enum.eventtype.html#variant.LOCK_WRLOCK)
1644  /// must be provided as the first subscription and may
1645  /// only be followed by up to one other subscription,
1646  /// having type [`CLOCK`](enum.eventtype.html#variant.CLOCK).
1647  pub r#type: eventtype,
1648  pub union: subscription_union
1649}
1650/// A union inside `subscription`.
1651#[repr(C)]
1652#[derive(Copy, Clone)]
1653pub union subscription_union {
1654  /// Used when [`type`](struct.subscription.html#structfield.type) is [`CLOCK`](enum.eventtype.html#variant.CLOCK).
1655  pub clock: subscription_clock,
1656  /// Used when [`type`](struct.subscription.html#structfield.type) is [`CONDVAR`](enum.eventtype.html#variant.CONDVAR).
1657  pub condvar: subscription_condvar,
1658  /// Used when [`type`](struct.subscription.html#structfield.type) is [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
1659  pub fd_readwrite: subscription_fd_readwrite,
1660  /// Used when [`type`](struct.subscription.html#structfield.type) is [`LOCK_RDLOCK`](enum.eventtype.html#variant.LOCK_RDLOCK) or [`LOCK_WRLOCK`](enum.eventtype.html#variant.LOCK_WRLOCK).
1661  pub lock: subscription_lock,
1662  /// Used when [`type`](struct.subscription.html#structfield.type) is [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
1663  pub proc_terminate: subscription_proc_terminate,
1664}
1665#[repr(C)]
1666#[derive(Copy, Clone)]
1667pub struct subscription_clock {
1668  /// The user-defined unique
1669  /// identifier of the clock.
1670  pub identifier: userdata,
1671  /// The clock against which the
1672  /// timestamp should be compared.
1673  pub clock_id: clockid,
1674  /// The absolute or relative
1675  /// timestamp.
1676  pub timeout: timestamp,
1677  /// The amount of time that the
1678  /// kernel may wait additionally
1679  /// to coalesce with other events.
1680  pub precision: timestamp,
1681  /// Flags specifying whether the
1682  /// timeout is absolute or
1683  /// relative.
1684  pub flags: subclockflags,
1685}
1686#[repr(C)]
1687#[derive(Copy, Clone)]
1688pub struct subscription_condvar {
1689  /// The condition variable on
1690  /// which to wait to be woken up.
1691  pub condvar: *mut condvar,
1692  /// The lock that will be
1693  /// released while waiting.
1694  ///
1695  /// The lock will be reacquired
1696  /// for writing when the condition
1697  /// variable triggers.
1698  pub lock: *mut lock,
1699  /// Whether the condition variable
1700  /// is stored in private or shared
1701  /// memory.
1702  pub condvar_scope: scope,
1703  /// Whether the lock is stored in
1704  /// private or shared memory.
1705  pub lock_scope: scope,
1706}
1707#[repr(C)]
1708#[derive(Copy, Clone)]
1709pub struct subscription_fd_readwrite {
1710  /// The file descriptor on which
1711  /// to wait for it to become ready
1712  /// for reading or writing.
1713  pub fd: fd,
1714  /// Under which conditions to
1715  /// trigger.
1716  pub flags: subrwflags,
1717}
1718#[repr(C)]
1719#[derive(Copy, Clone)]
1720pub struct subscription_lock {
1721  /// The lock that will be acquired
1722  /// for reading or writing.
1723  pub lock: *mut lock,
1724  /// Whether the lock is stored in
1725  /// private or shared memory.
1726  pub lock_scope: scope,
1727}
1728#[repr(C)]
1729#[derive(Copy, Clone)]
1730pub struct subscription_proc_terminate {
1731  /// The process descriptor on
1732  /// which to wait for process
1733  /// termination.
1734  pub fd: fd,
1735}
1736#[test]
1737#[cfg(target_pointer_width = "32")]
1738fn subscription_layout_test_32() {
1739  assert_eq!(core::mem::size_of::<subscription>(), 56);
1740  assert_eq!(core::mem::align_of::<subscription>(), 8);
1741  let mut obj = subscription {
1742    userdata: 0,
1743    unused: 0,
1744    r#type: eventtype::CLOCK,
1745    union: subscription_union {
1746      clock: subscription_clock {
1747        identifier: 0,
1748        clock_id: clockid::MONOTONIC,
1749        timeout: 0,
1750        precision: 0,
1751        flags: subclockflags::ABSTIME,
1752      },
1753    },
1754  };
1755  let base = &obj as *const _ as usize;
1756  assert_eq!(&obj.userdata as *const _ as usize - base, 0);
1757  assert_eq!(&obj.unused as *const _ as usize - base, 8);
1758  assert_eq!(&obj.r#type as *const _ as usize - base, 10);
1759  obj.union.clock = subscription_clock {
1760    identifier: 0,
1761    clock_id: clockid::MONOTONIC,
1762    timeout: 0,
1763    precision: 0,
1764    flags: subclockflags::ABSTIME,
1765  };
1766  unsafe {
1767    assert_eq!(&obj.union.clock.identifier as *const _ as usize - base, 16);
1768    assert_eq!(&obj.union.clock.clock_id as *const _ as usize - base, 24);
1769    assert_eq!(&obj.union.clock.timeout as *const _ as usize - base, 32);
1770    assert_eq!(&obj.union.clock.precision as *const _ as usize - base, 40);
1771    assert_eq!(&obj.union.clock.flags as *const _ as usize - base, 48);
1772  }
1773  obj.union.condvar = subscription_condvar {
1774    condvar: 0 as *mut condvar,
1775    lock: 0 as *mut lock,
1776    condvar_scope: scope::PRIVATE,
1777    lock_scope: scope::PRIVATE,
1778  };
1779  unsafe {
1780    assert_eq!(&obj.union.condvar.condvar as *const _ as usize - base, 16);
1781    assert_eq!(&obj.union.condvar.lock as *const _ as usize - base, 20);
1782    assert_eq!(&obj.union.condvar.condvar_scope as *const _ as usize - base, 24);
1783    assert_eq!(&obj.union.condvar.lock_scope as *const _ as usize - base, 25);
1784  }
1785  obj.union.fd_readwrite = subscription_fd_readwrite {
1786    fd: fd(0),
1787    flags: subrwflags::POLL,
1788  };
1789  unsafe {
1790    assert_eq!(&obj.union.fd_readwrite.fd as *const _ as usize - base, 16);
1791    assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 20);
1792  }
1793  obj.union.lock = subscription_lock {
1794    lock: 0 as *mut lock,
1795    lock_scope: scope::PRIVATE,
1796  };
1797  unsafe {
1798    assert_eq!(&obj.union.lock.lock as *const _ as usize - base, 16);
1799    assert_eq!(&obj.union.lock.lock_scope as *const _ as usize - base, 20);
1800  }
1801  obj.union.proc_terminate = subscription_proc_terminate {
1802    fd: fd(0),
1803  };
1804  unsafe {
1805    assert_eq!(&obj.union.proc_terminate.fd as *const _ as usize - base, 16);
1806  }
1807}
1808#[test]
1809#[cfg(target_pointer_width = "64")]
1810fn subscription_layout_test_64() {
1811  assert_eq!(core::mem::size_of::<subscription>(), 56);
1812  assert_eq!(core::mem::align_of::<subscription>(), 8);
1813  let mut obj = subscription {
1814    userdata: 0,
1815    unused: 0,
1816    r#type: eventtype::CLOCK,
1817    union: subscription_union {
1818      clock: subscription_clock {
1819        identifier: 0,
1820        clock_id: clockid::MONOTONIC,
1821        timeout: 0,
1822        precision: 0,
1823        flags: subclockflags::ABSTIME,
1824      },
1825    },
1826  };
1827  let base = &obj as *const _ as usize;
1828  assert_eq!(&obj.userdata as *const _ as usize - base, 0);
1829  assert_eq!(&obj.unused as *const _ as usize - base, 8);
1830  assert_eq!(&obj.r#type as *const _ as usize - base, 10);
1831  obj.union.clock = subscription_clock {
1832    identifier: 0,
1833    clock_id: clockid::MONOTONIC,
1834    timeout: 0,
1835    precision: 0,
1836    flags: subclockflags::ABSTIME,
1837  };
1838  unsafe {
1839    assert_eq!(&obj.union.clock.identifier as *const _ as usize - base, 16);
1840    assert_eq!(&obj.union.clock.clock_id as *const _ as usize - base, 24);
1841    assert_eq!(&obj.union.clock.timeout as *const _ as usize - base, 32);
1842    assert_eq!(&obj.union.clock.precision as *const _ as usize - base, 40);
1843    assert_eq!(&obj.union.clock.flags as *const _ as usize - base, 48);
1844  }
1845  obj.union.condvar = subscription_condvar {
1846    condvar: 0 as *mut condvar,
1847    lock: 0 as *mut lock,
1848    condvar_scope: scope::PRIVATE,
1849    lock_scope: scope::PRIVATE,
1850  };
1851  unsafe {
1852    assert_eq!(&obj.union.condvar.condvar as *const _ as usize - base, 16);
1853    assert_eq!(&obj.union.condvar.lock as *const _ as usize - base, 24);
1854    assert_eq!(&obj.union.condvar.condvar_scope as *const _ as usize - base, 32);
1855    assert_eq!(&obj.union.condvar.lock_scope as *const _ as usize - base, 33);
1856  }
1857  obj.union.fd_readwrite = subscription_fd_readwrite {
1858    fd: fd(0),
1859    flags: subrwflags::POLL,
1860  };
1861  unsafe {
1862    assert_eq!(&obj.union.fd_readwrite.fd as *const _ as usize - base, 16);
1863    assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 20);
1864  }
1865  obj.union.lock = subscription_lock {
1866    lock: 0 as *mut lock,
1867    lock_scope: scope::PRIVATE,
1868  };
1869  unsafe {
1870    assert_eq!(&obj.union.lock.lock as *const _ as usize - base, 16);
1871    assert_eq!(&obj.union.lock.lock_scope as *const _ as usize - base, 24);
1872  }
1873  obj.union.proc_terminate = subscription_proc_terminate {
1874    fd: fd(0),
1875  };
1876  unsafe {
1877    assert_eq!(&obj.union.proc_terminate.fd as *const _ as usize - base, 16);
1878  }
1879}
1880
1881/// The Thread Control Block (TCB).
1882///
1883/// After a thread begins execution (at program startup or when
1884/// created through [`thread_create()`](fn.thread_create.html)), the CPU's registers
1885/// controlling Thread-Local Storage (TLS) will already be
1886/// initialized. They will point to an area only containing the
1887/// TCB.
1888///
1889/// If the thread needs space for storing thread-specific
1890/// variables, the thread may allocate a larger area and adjust
1891/// the CPU's registers to point to that area instead. However, it
1892/// does need to make sure that the TCB is copied over to the new
1893/// TLS area.
1894///
1895/// The purpose of the TCB is that it allows light-weight
1896/// emulators to store information related to individual threads.
1897/// For example, it may be used to store a copy of the CPU
1898/// registers prior emulation, so that TLS for the host system
1899/// can be restored if needed.
1900#[repr(C)]
1901#[derive(Copy, Clone)]
1902pub struct tcb {
1903  /// Pointer that may be freely assigned by the system. Its
1904  /// value cannot be interpreted by the application.
1905  pub parent: *mut (),
1906}
1907#[test]
1908#[cfg(target_pointer_width = "32")]
1909fn tcb_layout_test_32() {
1910  assert_eq!(core::mem::size_of::<tcb>(), 4);
1911  assert_eq!(core::mem::align_of::<tcb>(), 4);
1912  let obj = tcb {
1913    parent: 0 as *mut (),
1914  };
1915  let base = &obj as *const _ as usize;
1916  assert_eq!(&obj.parent as *const _ as usize - base, 0);
1917}
1918#[test]
1919#[cfg(target_pointer_width = "64")]
1920fn tcb_layout_test_64() {
1921  assert_eq!(core::mem::size_of::<tcb>(), 8);
1922  assert_eq!(core::mem::align_of::<tcb>(), 8);
1923  let obj = tcb {
1924    parent: 0 as *mut (),
1925  };
1926  let base = &obj as *const _ as usize;
1927  assert_eq!(&obj.parent as *const _ as usize - base, 0);
1928}
1929
1930/// Entry point for additionally created threads.
1931///
1932/// **tid**:
1933/// Thread ID of the current thread.
1934///
1935/// **aux**:
1936/// Copy of the value stored in
1937/// [`threadattr.argument`](struct.threadattr.html#structfield.argument).
1938pub type threadentry = unsafe extern "C" fn(
1939  tid: tid,
1940  aux: *mut (),
1941) -> ();
1942
1943/// Attributes for thread creation.
1944#[repr(C)]
1945#[derive(Copy, Clone)]
1946pub struct threadattr {
1947  /// Initial program counter value.
1948  pub entry_point: threadentry,
1949  /// Region allocated to serve as stack space.
1950  pub stack: (*mut (), usize),
1951  /// Argument to be forwarded to the entry point function.
1952  pub argument: *mut (),
1953}
1954#[test]
1955#[cfg(target_pointer_width = "32")]
1956fn threadattr_layout_test_32() {
1957  assert_eq!(core::mem::size_of::<threadattr>(), 16);
1958  assert_eq!(core::mem::align_of::<threadattr>(), 4);
1959  let obj = threadattr {
1960    entry_point: { extern "C" fn f(_: tid, _: *mut ()) -> () {} f },
1961    stack: (0 as *mut _, 0),
1962    argument: 0 as *mut (),
1963  };
1964  let base = &obj as *const _ as usize;
1965  assert_eq!(&obj.entry_point as *const _ as usize - base, 0);
1966  assert_eq!(&obj.stack.0 as *const _ as usize - base, 4);
1967  assert_eq!(&obj.stack.1 as *const _ as usize - base, 8);
1968  assert_eq!(&obj.argument as *const _ as usize - base, 12);
1969}
1970#[test]
1971#[cfg(target_pointer_width = "64")]
1972fn threadattr_layout_test_64() {
1973  assert_eq!(core::mem::size_of::<threadattr>(), 32);
1974  assert_eq!(core::mem::align_of::<threadattr>(), 8);
1975  let obj = threadattr {
1976    entry_point: { extern "C" fn f(_: tid, _: *mut ()) -> () {} f },
1977    stack: (0 as *mut _, 0),
1978    argument: 0 as *mut (),
1979  };
1980  let base = &obj as *const _ as usize;
1981  assert_eq!(&obj.entry_point as *const _ as usize - base, 0);
1982  assert_eq!(&obj.stack.0 as *const _ as usize - base, 8);
1983  assert_eq!(&obj.stack.1 as *const _ as usize - base, 16);
1984  assert_eq!(&obj.argument as *const _ as usize - base, 24);
1985}
1986
1987/// The table with pointers to all syscall implementations.
1988#[allow(improper_ctypes)]
1989extern "C" {
1990  fn cloudabi_sys_clock_res_get(_: clockid, _: *mut timestamp) -> errno;
1991  fn cloudabi_sys_clock_time_get(_: clockid, _: timestamp, _: *mut timestamp) -> errno;
1992  fn cloudabi_sys_condvar_signal(_: *mut condvar, _: scope, _: nthreads) -> errno;
1993  fn cloudabi_sys_fd_close(_: fd) -> errno;
1994  fn cloudabi_sys_fd_create1(_: filetype, _: *mut fd) -> errno;
1995  fn cloudabi_sys_fd_create2(_: filetype, _: *mut fd, _: *mut fd) -> errno;
1996  fn cloudabi_sys_fd_datasync(_: fd) -> errno;
1997  fn cloudabi_sys_fd_dup(_: fd, _: *mut fd) -> errno;
1998  fn cloudabi_sys_fd_pread(_: fd, _: *const iovec, _: usize, _: filesize, _: *mut usize) -> errno;
1999  fn cloudabi_sys_fd_pwrite(_: fd, _: *const ciovec, _: usize, _: filesize, _: *mut usize) -> errno;
2000  fn cloudabi_sys_fd_read(_: fd, _: *const iovec, _: usize, _: *mut usize) -> errno;
2001  fn cloudabi_sys_fd_replace(_: fd, _: fd) -> errno;
2002  fn cloudabi_sys_fd_seek(_: fd, _: filedelta, _: whence, _: *mut filesize) -> errno;
2003  fn cloudabi_sys_fd_stat_get(_: fd, _: *mut fdstat) -> errno;
2004  fn cloudabi_sys_fd_stat_put(_: fd, _: *const fdstat, _: fdsflags) -> errno;
2005  fn cloudabi_sys_fd_sync(_: fd) -> errno;
2006  fn cloudabi_sys_fd_write(_: fd, _: *const ciovec, _: usize, _: *mut usize) -> errno;
2007  fn cloudabi_sys_file_advise(_: fd, _: filesize, _: filesize, _: advice) -> errno;
2008  fn cloudabi_sys_file_allocate(_: fd, _: filesize, _: filesize) -> errno;
2009  fn cloudabi_sys_file_create(_: fd, _: *const u8, _: usize, _: filetype) -> errno;
2010  fn cloudabi_sys_file_link(_: lookup, _: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
2011  fn cloudabi_sys_file_open(_: lookup, _: *const u8, _: usize, _: oflags, _: *const fdstat, _: *mut fd) -> errno;
2012  fn cloudabi_sys_file_readdir(_: fd, _: *mut (), _: usize, _: dircookie, _: *mut usize) -> errno;
2013  fn cloudabi_sys_file_readlink(_: fd, _: *const u8, _: usize, _: *mut u8, _: usize, _: *mut usize) -> errno;
2014  fn cloudabi_sys_file_rename(_: fd, _: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
2015  fn cloudabi_sys_file_stat_fget(_: fd, _: *mut filestat) -> errno;
2016  fn cloudabi_sys_file_stat_fput(_: fd, _: *const filestat, _: fsflags) -> errno;
2017  fn cloudabi_sys_file_stat_get(_: lookup, _: *const u8, _: usize, _: *mut filestat) -> errno;
2018  fn cloudabi_sys_file_stat_put(_: lookup, _: *const u8, _: usize, _: *const filestat, _: fsflags) -> errno;
2019  fn cloudabi_sys_file_symlink(_: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
2020  fn cloudabi_sys_file_unlink(_: fd, _: *const u8, _: usize, _: ulflags) -> errno;
2021  fn cloudabi_sys_lock_unlock(_: *mut lock, _: scope) -> errno;
2022  fn cloudabi_sys_mem_advise(_: *mut (), _: usize, _: advice) -> errno;
2023  fn cloudabi_sys_mem_map(_: *mut (), _: usize, _: mprot, _: mflags, _: fd, _: filesize, _: *mut *mut ()) -> errno;
2024  fn cloudabi_sys_mem_protect(_: *mut (), _: usize, _: mprot) -> errno;
2025  fn cloudabi_sys_mem_sync(_: *mut (), _: usize, _: msflags) -> errno;
2026  fn cloudabi_sys_mem_unmap(_: *mut (), _: usize) -> errno;
2027  fn cloudabi_sys_poll(_: *const subscription, _: *mut event, _: usize, _: *mut usize) -> errno;
2028  fn cloudabi_sys_proc_exec(_: fd, _: *const (), _: usize, _: *const fd, _: usize) -> errno;
2029  fn cloudabi_sys_proc_exit(_: exitcode) -> !;
2030  fn cloudabi_sys_proc_fork(_: *mut fd, _: *mut tid) -> errno;
2031  fn cloudabi_sys_proc_raise(_: signal) -> errno;
2032  fn cloudabi_sys_random_get(_: *mut (), _: usize) -> errno;
2033  fn cloudabi_sys_sock_recv(_: fd, _: *const recv_in, _: *mut recv_out) -> errno;
2034  fn cloudabi_sys_sock_send(_: fd, _: *const send_in, _: *mut send_out) -> errno;
2035  fn cloudabi_sys_sock_shutdown(_: fd, _: sdflags) -> errno;
2036  fn cloudabi_sys_thread_create(_: *mut threadattr, _: *mut tid) -> errno;
2037  fn cloudabi_sys_thread_exit(_: *mut lock, _: scope) -> !;
2038  fn cloudabi_sys_thread_yield() -> errno;
2039}
2040
2041/// Obtains the resolution of a clock.
2042///
2043/// ## Parameters
2044///
2045/// **clock_id**:
2046/// The clock for which the resolution needs to be
2047/// returned.
2048///
2049/// **resolution**:
2050/// The resolution of the clock.
2051#[inline]
2052pub unsafe fn clock_res_get(clock_id_: clockid, resolution_: *mut timestamp) -> errno {
2053  cloudabi_sys_clock_res_get(clock_id_, resolution_)
2054}
2055
2056/// Obtains the time value of a clock.
2057///
2058/// ## Parameters
2059///
2060/// **clock_id**:
2061/// The clock for which the time needs to be
2062/// returned.
2063///
2064/// **precision**:
2065/// The maximum lag (exclusive) that the returned
2066/// time value may have, compared to its actual
2067/// value.
2068///
2069/// **time**:
2070/// The time value of the clock.
2071#[inline]
2072pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: *mut timestamp) -> errno {
2073  cloudabi_sys_clock_time_get(clock_id_, precision_, time_)
2074}
2075
2076/// Wakes up threads waiting on a userspace condition variable.
2077///
2078/// If an invocation of this system call causes all waiting
2079/// threads to be woken up, the value of the condition variable
2080/// is set to [`CONDVAR_HAS_NO_WAITERS`](constant.CONDVAR_HAS_NO_WAITERS.html). As long as the condition
2081/// variable is set to this value, it is not needed to invoke this
2082/// system call.
2083///
2084/// ## Parameters
2085///
2086/// **condvar**:
2087/// The userspace condition variable that has
2088/// waiting threads.
2089///
2090/// **scope**:
2091/// Whether the condition variable is stored in
2092/// private or shared memory.
2093///
2094/// **nwaiters**:
2095/// The number of threads that need to be woken
2096/// up. If it exceeds the number of waiting
2097/// threads, all threads are woken up.
2098#[inline]
2099pub unsafe fn condvar_signal(condvar_: *mut condvar, scope_: scope, nwaiters_: nthreads) -> errno {
2100  cloudabi_sys_condvar_signal(condvar_, scope_, nwaiters_)
2101}
2102
2103/// Closes a file descriptor.
2104///
2105/// ## Parameters
2106///
2107/// **fd**:
2108/// The file descriptor that needs to be closed.
2109#[inline]
2110pub unsafe fn fd_close(fd_: fd) -> errno {
2111  cloudabi_sys_fd_close(fd_)
2112}
2113
2114/// Creates a file descriptor.
2115///
2116/// ## Parameters
2117///
2118/// **type**:
2119/// Possible values:
2120///
2121///   - [`SHARED_MEMORY`](enum.filetype.html#variant.SHARED_MEMORY):
2122///     Creates an anonymous shared memory
2123///     object.
2124///
2125/// **fd**:
2126/// The file descriptor that has been created.
2127#[inline]
2128pub unsafe fn fd_create1(type_: filetype, fd_: *mut fd) -> errno {
2129  cloudabi_sys_fd_create1(type_, fd_)
2130}
2131
2132/// Creates a pair of file descriptors.
2133///
2134/// ## Parameters
2135///
2136/// **type**:
2137/// Possible values:
2138///
2139///   - [`SOCKET_DGRAM`](enum.filetype.html#variant.SOCKET_DGRAM):
2140///     Creates a UNIX datagram socket pair.
2141///   - [`SOCKET_STREAM`](enum.filetype.html#variant.SOCKET_STREAM):
2142///     Creates a UNIX byte-stream socket
2143///     pair.
2144///
2145/// **fd1**:
2146/// The first file descriptor of the pair.
2147///
2148/// **fd2**:
2149/// The second file descriptor of the pair.
2150#[inline]
2151pub unsafe fn fd_create2(type_: filetype, fd1_: *mut fd, fd2_: *mut fd) -> errno {
2152  cloudabi_sys_fd_create2(type_, fd1_, fd2_)
2153}
2154
2155/// Synchronizes the data of a file to disk.
2156///
2157/// ## Parameters
2158///
2159/// **fd**:
2160/// The file descriptor of the file whose data
2161/// needs to be synchronized to disk.
2162#[inline]
2163pub unsafe fn fd_datasync(fd_: fd) -> errno {
2164  cloudabi_sys_fd_datasync(fd_)
2165}
2166
2167/// Duplicates a file descriptor.
2168///
2169/// ## Parameters
2170///
2171/// **from**:
2172/// The file descriptor that needs to be
2173/// duplicated.
2174///
2175/// **fd**:
2176/// The new file descriptor.
2177#[inline]
2178pub unsafe fn fd_dup(from_: fd, fd_: *mut fd) -> errno {
2179  cloudabi_sys_fd_dup(from_, fd_)
2180}
2181
2182/// Reads from a file descriptor, without using and updating the
2183/// file descriptor's offset.
2184///
2185/// ## Parameters
2186///
2187/// **fd**:
2188/// The file descriptor from which data should be
2189/// read.
2190///
2191/// **iovs**:
2192/// List of scatter/gather vectors where data
2193/// should be stored.
2194///
2195/// **offset**:
2196/// The offset within the file at which reading
2197/// should start.
2198///
2199/// **nread**:
2200/// The number of bytes read.
2201#[inline]
2202pub unsafe fn fd_pread(fd_: fd, iovs_: &[iovec], offset_: filesize, nread_: *mut usize) -> errno {
2203  cloudabi_sys_fd_pread(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nread_)
2204}
2205
2206/// Writes to a file descriptor, without using and updating the
2207/// file descriptor's offset.
2208///
2209/// ## Parameters
2210///
2211/// **fd**:
2212/// The file descriptor to which data should be
2213/// written.
2214///
2215/// **iovs**:
2216/// List of scatter/gather vectors where data
2217/// should be retrieved.
2218///
2219/// **offset**:
2220/// The offset within the file at which writing
2221/// should start.
2222///
2223/// **nwritten**:
2224/// The number of bytes written.
2225#[inline]
2226pub unsafe fn fd_pwrite(fd_: fd, iovs_: &[ciovec], offset_: filesize, nwritten_: *mut usize) -> errno {
2227  cloudabi_sys_fd_pwrite(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nwritten_)
2228}
2229
2230/// Reads from a file descriptor.
2231///
2232/// ## Parameters
2233///
2234/// **fd**:
2235/// The file descriptor from which data should be
2236/// read.
2237///
2238/// **iovs**:
2239/// List of scatter/gather vectors where data
2240/// should be stored.
2241///
2242/// **nread**:
2243/// The number of bytes read.
2244#[inline]
2245pub unsafe fn fd_read(fd_: fd, iovs_: &[iovec], nread_: *mut usize) -> errno {
2246  cloudabi_sys_fd_read(fd_, iovs_.as_ptr(), iovs_.len(), nread_)
2247}
2248
2249/// Atomically replaces a file descriptor by a copy of another
2250/// file descriptor.
2251///
2252/// Due to the strong focus on thread safety, this environment
2253/// does not provide a mechanism to duplicate a file descriptor to
2254/// an arbitrary number, like dup2(). This would be prone to race
2255/// conditions, as an actual file descriptor with the same number
2256/// could be allocated by a different thread at the same time.
2257///
2258/// This system call provides a way to atomically replace file
2259/// descriptors, which would disappear if dup2() were to be
2260/// removed entirely.
2261///
2262/// ## Parameters
2263///
2264/// **from**:
2265/// The file descriptor that needs to be copied.
2266///
2267/// **to**:
2268/// The file descriptor that needs to be
2269/// overwritten.
2270#[inline]
2271pub unsafe fn fd_replace(from_: fd, to_: fd) -> errno {
2272  cloudabi_sys_fd_replace(from_, to_)
2273}
2274
2275/// Moves the offset of the file descriptor.
2276///
2277/// ## Parameters
2278///
2279/// **fd**:
2280/// The file descriptor whose offset has to be
2281/// moved.
2282///
2283/// **offset**:
2284/// The number of bytes to move.
2285///
2286/// **whence**:
2287/// Relative to which position the move should
2288/// take place.
2289///
2290/// **newoffset**:
2291/// The new offset of the file descriptor,
2292/// relative to the start of the file.
2293#[inline]
2294pub unsafe fn fd_seek(fd_: fd, offset_: filedelta, whence_: whence, newoffset_: *mut filesize) -> errno {
2295  cloudabi_sys_fd_seek(fd_, offset_, whence_, newoffset_)
2296}
2297
2298/// Gets attributes of a file descriptor.
2299///
2300/// ## Parameters
2301///
2302/// **fd**:
2303/// The file descriptor whose attributes have to
2304/// be obtained.
2305///
2306/// **buf**:
2307/// The buffer where the file descriptor's
2308/// attributes are stored.
2309#[inline]
2310pub unsafe fn fd_stat_get(fd_: fd, buf_: *mut fdstat) -> errno {
2311  cloudabi_sys_fd_stat_get(fd_, buf_)
2312}
2313
2314/// Adjusts attributes of a file descriptor.
2315///
2316/// ## Parameters
2317///
2318/// **fd**:
2319/// The file descriptor whose attributes have to
2320/// be adjusted.
2321///
2322/// **buf**:
2323/// The desired values of the file descriptor
2324/// attributes that are adjusted.
2325///
2326/// **flags**:
2327/// A bitmask indicating which attributes have to
2328/// be adjusted.
2329#[inline]
2330pub unsafe fn fd_stat_put(fd_: fd, buf_: *const fdstat, flags_: fdsflags) -> errno {
2331  cloudabi_sys_fd_stat_put(fd_, buf_, flags_)
2332}
2333
2334/// Synchronizes the data and metadata of a file to disk.
2335///
2336/// ## Parameters
2337///
2338/// **fd**:
2339/// The file descriptor of the file whose data
2340/// and metadata needs to be synchronized to disk.
2341#[inline]
2342pub unsafe fn fd_sync(fd_: fd) -> errno {
2343  cloudabi_sys_fd_sync(fd_)
2344}
2345
2346/// Writes to a file descriptor.
2347///
2348/// ## Parameters
2349///
2350/// **fd**:
2351/// The file descriptor to which data should be
2352/// written.
2353///
2354/// **iovs**:
2355/// List of scatter/gather vectors where data
2356/// should be retrieved.
2357///
2358/// **nwritten**:
2359/// The number of bytes written.
2360#[inline]
2361pub unsafe fn fd_write(fd_: fd, iovs_: &[ciovec], nwritten_: *mut usize) -> errno {
2362  cloudabi_sys_fd_write(fd_, iovs_.as_ptr(), iovs_.len(), nwritten_)
2363}
2364
2365/// Provides file advisory information on a file descriptor.
2366///
2367/// ## Parameters
2368///
2369/// **fd**:
2370/// The file descriptor for which to provide file
2371/// advisory information.
2372///
2373/// **offset**:
2374/// The offset within the file to which the
2375/// advisory applies.
2376///
2377/// **len**:
2378/// The length of the region to which the advisory
2379/// applies.
2380///
2381/// **advice**:
2382/// The advice.
2383#[inline]
2384pub unsafe fn file_advise(fd_: fd, offset_: filesize, len_: filesize, advice_: advice) -> errno {
2385  cloudabi_sys_file_advise(fd_, offset_, len_, advice_)
2386}
2387
2388/// Forces the allocation of space in a file.
2389///
2390/// ## Parameters
2391///
2392/// **fd**:
2393/// The file in which the space should be
2394/// allocated.
2395///
2396/// **offset**:
2397/// The offset at which the allocation should
2398/// start.
2399///
2400/// **len**:
2401/// The length of the area that is allocated.
2402#[inline]
2403pub unsafe fn file_allocate(fd_: fd, offset_: filesize, len_: filesize) -> errno {
2404  cloudabi_sys_file_allocate(fd_, offset_, len_)
2405}
2406
2407/// Creates a file of a specified type.
2408///
2409/// ## Parameters
2410///
2411/// **fd**:
2412/// The working directory at which the resolution
2413/// of the file to be created starts.
2414///
2415/// **path**:
2416/// The path at which the file should be created.
2417///
2418/// **type**:
2419/// Possible values:
2420///
2421///   - [`DIRECTORY`](enum.filetype.html#variant.DIRECTORY):
2422///     Creates a directory.
2423#[inline]
2424pub unsafe fn file_create(fd_: fd, path_: &[u8], type_: filetype) -> errno {
2425  cloudabi_sys_file_create(fd_, path_.as_ptr(), path_.len(), type_)
2426}
2427
2428/// Creates a hard link.
2429///
2430/// ## Parameters
2431///
2432/// **fd1**:
2433/// The working directory at which the resolution
2434/// of the source path starts.
2435///
2436/// **path1**:
2437/// The source path of the file that should be
2438/// hard linked.
2439///
2440/// **fd2**:
2441/// The working directory at which the resolution
2442/// of the destination path starts.
2443///
2444/// **path2**:
2445/// The destination path at which the hard link
2446/// should be created.
2447#[inline]
2448pub unsafe fn file_link(fd1_: lookup, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> errno {
2449  cloudabi_sys_file_link(fd1_, path1_.as_ptr(), path1_.len(), fd2_, path2_.as_ptr(), path2_.len())
2450}
2451
2452/// Opens a file.
2453///
2454/// ## Parameters
2455///
2456/// **dirfd**:
2457/// The working directory at which the resolution
2458/// of the file to be opened starts.
2459///
2460/// **path**:
2461/// The path of the file that should be opened.
2462///
2463/// **oflags**:
2464/// The method at which the file should be opened.
2465///
2466/// **fds**:
2467/// [`fdstat.fs_rights_base`](struct.fdstat.html#structfield.fs_rights_base) and
2468/// [`fdstat.fs_rights_inheriting`](struct.fdstat.html#structfield.fs_rights_inheriting) specify the
2469/// initial rights of the newly created file
2470/// descriptor. The operating system is allowed to
2471/// return a file descriptor with fewer rights
2472/// than specified, if and only if those rights do
2473/// not apply to the type of file being opened.
2474///
2475/// [`fdstat.fs_flags`](struct.fdstat.html#structfield.fs_flags) specifies the initial flags
2476/// of the file descriptor.
2477///
2478/// [`fdstat.fs_filetype`](struct.fdstat.html#structfield.fs_filetype) is ignored.
2479///
2480/// **fd**:
2481/// The file descriptor of the file that has been
2482/// opened.
2483#[inline]
2484pub unsafe fn file_open(dirfd_: lookup, path_: &[u8], oflags_: oflags, fds_: *const fdstat, fd_: *mut fd) -> errno {
2485  cloudabi_sys_file_open(dirfd_, path_.as_ptr(), path_.len(), oflags_, fds_, fd_)
2486}
2487
2488/// Reads directory entries from a directory.
2489///
2490/// When successful, the contents of the output buffer consist of
2491/// a sequence of directory entries. Each directory entry consists
2492/// of a [`dirent`](struct.dirent.html) object, followed by [`dirent.d_namlen`](struct.dirent.html#structfield.d_namlen) bytes
2493/// holding the name of the directory entry.
2494///
2495/// This system call fills the output buffer as much as possible,
2496/// potentially truncating the last directory entry. This allows
2497/// the caller to grow its read buffer size in case it's too small
2498/// to fit a single large directory entry, or skip the oversized
2499/// directory entry.
2500///
2501/// ## Parameters
2502///
2503/// **fd**:
2504/// The directory from which to read the directory
2505/// entries.
2506///
2507/// **buf**:
2508/// The buffer where directory entries are stored.
2509///
2510/// **cookie**:
2511/// The location within the directory to start
2512/// reading.
2513///
2514/// **bufused**:
2515/// The number of bytes stored in the read buffer.
2516/// If less than the size of the read buffer, the
2517/// end of the directory has been reached.
2518#[inline]
2519pub unsafe fn file_readdir(fd_: fd, buf_: &mut [u8], cookie_: dircookie, bufused_: *mut usize) -> errno {
2520  cloudabi_sys_file_readdir(fd_, buf_.as_mut_ptr() as *mut (), buf_.len(), cookie_, bufused_)
2521}
2522
2523/// Reads the contents of a symbolic link.
2524///
2525/// ## Parameters
2526///
2527/// **fd**:
2528/// The working directory at which the resolution
2529/// of the path of the symbolic starts.
2530///
2531/// **path**:
2532/// The path of the symbolic link whose contents
2533/// should be read.
2534///
2535/// **buf**:
2536/// The buffer where the contents of the symbolic
2537/// link should be stored.
2538///
2539/// **bufused**:
2540/// The number of bytes placed in the buffer.
2541#[inline]
2542pub unsafe fn file_readlink(fd_: fd, path_: &[u8], buf_: &mut [u8], bufused_: *mut usize) -> errno {
2543  cloudabi_sys_file_readlink(fd_, path_.as_ptr(), path_.len(), buf_.as_mut_ptr(), buf_.len(), bufused_)
2544}
2545
2546/// Renames a file.
2547///
2548/// ## Parameters
2549///
2550/// **fd1**:
2551/// The working directory at which the resolution
2552/// of the source path starts.
2553///
2554/// **path1**:
2555/// The source path of the file that should be
2556/// renamed.
2557///
2558/// **fd2**:
2559/// The working directory at which the resolution
2560/// of the destination path starts.
2561///
2562/// **path2**:
2563/// The destination path to which the file should
2564/// be renamed.
2565#[inline]
2566pub unsafe fn file_rename(fd1_: fd, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> errno {
2567  cloudabi_sys_file_rename(fd1_, path1_.as_ptr(), path1_.len(), fd2_, path2_.as_ptr(), path2_.len())
2568}
2569
2570/// Gets attributes of a file by file descriptor.
2571///
2572/// ## Parameters
2573///
2574/// **fd**:
2575/// The file descriptor whose attributes have to
2576/// be obtained.
2577///
2578/// **buf**:
2579/// The buffer where the file's attributes are
2580/// stored.
2581#[inline]
2582pub unsafe fn file_stat_fget(fd_: fd, buf_: *mut filestat) -> errno {
2583  cloudabi_sys_file_stat_fget(fd_, buf_)
2584}
2585
2586/// Adjusts attributes of a file by file descriptor.
2587///
2588/// ## Parameters
2589///
2590/// **fd**:
2591/// The file descriptor whose attributes have to
2592/// be adjusted.
2593///
2594/// **buf**:
2595/// The desired values of the file attributes that
2596/// are adjusted.
2597///
2598/// **flags**:
2599/// A bitmask indicating which attributes have to
2600/// be adjusted.
2601#[inline]
2602pub unsafe fn file_stat_fput(fd_: fd, buf_: *const filestat, flags_: fsflags) -> errno {
2603  cloudabi_sys_file_stat_fput(fd_, buf_, flags_)
2604}
2605
2606/// Gets attributes of a file by path.
2607///
2608/// ## Parameters
2609///
2610/// **fd**:
2611/// The working directory at which the resolution
2612/// of the path whose attributes have to be
2613/// obtained starts.
2614///
2615/// **path**:
2616/// The path of the file whose attributes have to
2617/// be obtained.
2618///
2619/// **buf**:
2620/// The buffer where the file's attributes are
2621/// stored.
2622#[inline]
2623pub unsafe fn file_stat_get(fd_: lookup, path_: &[u8], buf_: *mut filestat) -> errno {
2624  cloudabi_sys_file_stat_get(fd_, path_.as_ptr(), path_.len(), buf_)
2625}
2626
2627/// Adjusts attributes of a file by path.
2628///
2629/// ## Parameters
2630///
2631/// **fd**:
2632/// The working directory at which the resolution
2633/// of the path whose attributes have to be
2634/// adjusted starts.
2635///
2636/// **path**:
2637/// The path of the file whose attributes have to
2638/// be adjusted.
2639///
2640/// **buf**:
2641/// The desired values of the file attributes that
2642/// are adjusted.
2643///
2644/// **flags**:
2645/// A bitmask indicating which attributes have to
2646/// be adjusted.
2647#[inline]
2648pub unsafe fn file_stat_put(fd_: lookup, path_: &[u8], buf_: *const filestat, flags_: fsflags) -> errno {
2649  cloudabi_sys_file_stat_put(fd_, path_.as_ptr(), path_.len(), buf_, flags_)
2650}
2651
2652/// Creates a symbolic link.
2653///
2654/// ## Parameters
2655///
2656/// **path1**:
2657/// The contents of the symbolic link.
2658///
2659/// **fd**:
2660/// The working directory at which the resolution
2661/// of the destination path starts.
2662///
2663/// **path2**:
2664/// The destination path at which the symbolic
2665/// link should be created.
2666#[inline]
2667pub unsafe fn file_symlink(path1_: &[u8], fd_: fd, path2_: &[u8]) -> errno {
2668  cloudabi_sys_file_symlink(path1_.as_ptr(), path1_.len(), fd_, path2_.as_ptr(), path2_.len())
2669}
2670
2671/// Unlinks a file, or removes a directory.
2672///
2673/// ## Parameters
2674///
2675/// **fd**:
2676/// The working directory at which the resolution
2677/// of the path starts.
2678///
2679/// **path**:
2680/// The path that needs to be unlinked or removed.
2681///
2682/// **flags**:
2683/// Possible values:
2684///
2685///   - [`REMOVEDIR`](struct.ulflags.html#associatedconstant.REMOVEDIR):
2686///     If set, attempt to remove a directory.
2687///     Otherwise, unlink a file.
2688#[inline]
2689pub unsafe fn file_unlink(fd_: fd, path_: &[u8], flags_: ulflags) -> errno {
2690  cloudabi_sys_file_unlink(fd_, path_.as_ptr(), path_.len(), flags_)
2691}
2692
2693/// Unlocks a write-locked userspace lock.
2694///
2695/// If a userspace lock is unlocked while having its
2696/// [`LOCK_KERNEL_MANAGED`](constant.LOCK_KERNEL_MANAGED.html) flag set, the lock cannot be unlocked in
2697/// userspace directly. This system call needs to be performed
2698/// instead, so that any waiting threads can be woken up.
2699///
2700/// To prevent spurious invocations of this system call, the lock
2701/// must be locked for writing. This prevents other threads from
2702/// acquiring additional read locks while the system call is in
2703/// progress. If the lock is acquired for reading, it must first
2704/// be upgraded to a write lock.
2705///
2706/// ## Parameters
2707///
2708/// **lock**:
2709/// The userspace lock that is locked for writing
2710/// by the calling thread.
2711///
2712/// **scope**:
2713/// Whether the lock is stored in private or
2714/// shared memory.
2715#[inline]
2716pub unsafe fn lock_unlock(lock_: *mut lock, scope_: scope) -> errno {
2717  cloudabi_sys_lock_unlock(lock_, scope_)
2718}
2719
2720/// Provides memory advisory information on a region of memory.
2721///
2722/// ## Parameters
2723///
2724/// **mapping**:
2725/// The pages for which to provide memory advisory
2726/// information.
2727///
2728/// **advice**:
2729/// The advice.
2730#[inline]
2731pub unsafe fn mem_advise(mapping_: &mut [u8], advice_: advice) -> errno {
2732  cloudabi_sys_mem_advise(mapping_.as_mut_ptr() as *mut (), mapping_.len(), advice_)
2733}
2734
2735/// Creates a memory mapping, making the contents of a file
2736/// accessible through memory.
2737///
2738/// ## Parameters
2739///
2740/// **addr**:
2741/// If [`FIXED`](struct.mflags.html#associatedconstant.FIXED) is set, specifies to which
2742/// address the file region is mapped. Otherwise,
2743/// the mapping is performed at an unused
2744/// location.
2745///
2746/// **len**:
2747/// The length of the memory mapping to be
2748/// created.
2749///
2750/// **prot**:
2751/// Initial memory protection options for the
2752/// memory mapping.
2753///
2754/// **flags**:
2755/// Memory mapping flags.
2756///
2757/// **fd**:
2758/// If [`ANON`](struct.mflags.html#associatedconstant.ANON) is set, this argument must be
2759/// [`MAP_ANON_FD`](constant.MAP_ANON_FD.html). Otherwise, this argument
2760/// specifies the file whose contents need to be
2761/// mapped.
2762///
2763/// **off**:
2764/// If [`ANON`](struct.mflags.html#associatedconstant.ANON) is set, this argument must be
2765/// zero. Otherwise, this argument specifies the
2766/// offset within the file at which the mapping
2767/// starts.
2768///
2769/// **mem**:
2770/// The starting address of the memory mapping.
2771#[inline]
2772pub unsafe fn mem_map(addr_: *mut (), len_: usize, prot_: mprot, flags_: mflags, fd_: fd, off_: filesize, mem_: *mut *mut ()) -> errno {
2773  cloudabi_sys_mem_map(addr_, len_, prot_, flags_, fd_, off_, mem_)
2774}
2775
2776/// Change the protection of a memory mapping.
2777///
2778/// ## Parameters
2779///
2780/// **mapping**:
2781/// The pages that need their protection changed.
2782///
2783/// **prot**:
2784/// New protection options.
2785#[inline]
2786pub unsafe fn mem_protect(mapping_: &mut [u8], prot_: mprot) -> errno {
2787  cloudabi_sys_mem_protect(mapping_.as_mut_ptr() as *mut (), mapping_.len(), prot_)
2788}
2789
2790/// Synchronize a region of memory with its physical storage.
2791///
2792/// ## Parameters
2793///
2794/// **mapping**:
2795/// The pages that need to be synchronized.
2796///
2797/// **flags**:
2798/// The method of synchronization.
2799#[inline]
2800pub unsafe fn mem_sync(mapping_: &mut [u8], flags_: msflags) -> errno {
2801  cloudabi_sys_mem_sync(mapping_.as_mut_ptr() as *mut (), mapping_.len(), flags_)
2802}
2803
2804/// Unmaps a region of memory.
2805///
2806/// ## Parameters
2807///
2808/// **mapping**:
2809/// The pages that needs to be unmapped.
2810#[inline]
2811pub unsafe fn mem_unmap(mapping_: &mut [u8]) -> errno {
2812  cloudabi_sys_mem_unmap(mapping_.as_mut_ptr() as *mut (), mapping_.len())
2813}
2814
2815/// Concurrently polls for the occurrence of a set of events.
2816///
2817/// ## Parameters
2818///
2819/// **in**:
2820/// The events to which to subscribe.
2821///
2822/// **out**:
2823/// The events that have occurred.
2824///
2825/// **nsubscriptions**:
2826/// Both the number of subscriptions and events.
2827///
2828/// **nevents**:
2829/// The number of events stored.
2830#[inline]
2831pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: *mut usize) -> errno {
2832  cloudabi_sys_poll(in_, out_, nsubscriptions_, nevents_)
2833}
2834
2835/// Replaces the process by a new executable.
2836///
2837/// Process execution in CloudABI differs from POSIX in two ways:
2838/// handling of arguments and inheritance of file descriptors.
2839///
2840/// CloudABI does not use string command line arguments. Instead,
2841/// a buffer with binary data is copied into the address space of
2842/// the new executable. The kernel does not enforce any specific
2843/// structure to this data, although CloudABI's C library uses it
2844/// to store a tree structure that is semantically identical to
2845/// YAML.
2846///
2847/// Due to the strong focus on thread safety, file descriptors
2848/// aren't inherited through close-on-exec flags. An explicit
2849/// list of file descriptors that need to be retained needs to be
2850/// provided. After execution, file descriptors are placed in the
2851/// order in which they are stored in the array. This not only
2852/// makes the execution process deterministic. It also prevents
2853/// potential information disclosures about the layout of the
2854/// original process.
2855///
2856/// ## Parameters
2857///
2858/// **fd**:
2859/// A file descriptor of the new executable.
2860///
2861/// **data**:
2862/// Binary argument data that is passed on to the
2863/// new executable.
2864///
2865/// **fds**:
2866/// The layout of the file descriptor table after
2867/// execution.
2868#[inline]
2869pub unsafe fn proc_exec(fd_: fd, data_: &[u8], fds_: &[fd]) -> errno {
2870  cloudabi_sys_proc_exec(fd_, data_.as_ptr() as *const (), data_.len(), fds_.as_ptr(), fds_.len())
2871}
2872
2873/// Terminates the process normally.
2874///
2875/// ## Parameters
2876///
2877/// **rval**:
2878/// The exit code returned by the process. The
2879/// exit code can be obtained by other processes
2880/// through [`event.union.proc_terminate.exitcode`](struct.event_proc_terminate.html#structfield.exitcode).
2881#[inline]
2882pub unsafe fn proc_exit(rval_: exitcode) -> ! {
2883  cloudabi_sys_proc_exit(rval_)
2884}
2885
2886/// Forks the process of the calling thread.
2887///
2888/// After forking, a new process shall be created, having only a
2889/// copy of the calling thread. The parent process will obtain a
2890/// process descriptor. When closed, the child process is
2891/// automatically signaled with [`KILL`](enum.signal.html#variant.KILL).
2892///
2893/// ## Parameters
2894///
2895/// **fd**:
2896/// In the parent process: the file descriptor
2897/// number of the process descriptor.
2898///
2899/// In the child process: [`PROCESS_CHILD`](constant.PROCESS_CHILD.html).
2900///
2901/// **tid**:
2902/// In the parent process: undefined.
2903///
2904/// In the child process: the thread ID of the
2905/// initial thread of the child process.
2906#[inline]
2907pub unsafe fn proc_fork(fd_: *mut fd, tid_: *mut tid) -> errno {
2908  cloudabi_sys_proc_fork(fd_, tid_)
2909}
2910
2911/// Sends a signal to the process of the calling thread.
2912///
2913/// ## Parameters
2914///
2915/// **sig**:
2916/// The signal condition that should be triggered.
2917/// If the signal causes the process to terminate,
2918/// its condition can be obtained by other
2919/// processes through
2920/// [`event.union.proc_terminate.signal`](struct.event_proc_terminate.html#structfield.signal).
2921#[inline]
2922pub unsafe fn proc_raise(sig_: signal) -> errno {
2923  cloudabi_sys_proc_raise(sig_)
2924}
2925
2926/// Obtains random data from the kernel random number generator.
2927///
2928/// As this interface is not guaranteed to be fast, it is advised
2929/// that the random data obtained through this system call is used
2930/// as the seed for a userspace pseudo-random number generator.
2931///
2932/// ## Parameters
2933///
2934/// **buf**:
2935/// The buffer that needs to be filled with random
2936/// data.
2937#[inline]
2938pub unsafe fn random_get(buf_: &mut [u8]) -> errno {
2939  cloudabi_sys_random_get(buf_.as_mut_ptr() as *mut (), buf_.len())
2940}
2941
2942/// Receives a message on a socket.
2943///
2944/// ## Parameters
2945///
2946/// **sock**:
2947/// The socket on which a message should be
2948/// received.
2949///
2950/// **in**:
2951/// Input parameters.
2952///
2953/// **out**:
2954/// Output parameters.
2955#[inline]
2956pub unsafe fn sock_recv(sock_: fd, in_: *const recv_in, out_: *mut recv_out) -> errno {
2957  cloudabi_sys_sock_recv(sock_, in_, out_)
2958}
2959
2960/// Sends a message on a socket.
2961///
2962/// ## Parameters
2963///
2964/// **sock**:
2965/// The socket on which a message should be sent.
2966///
2967/// **in**:
2968/// Input parameters.
2969///
2970/// **out**:
2971/// Output parameters.
2972#[inline]
2973pub unsafe fn sock_send(sock_: fd, in_: *const send_in, out_: *mut send_out) -> errno {
2974  cloudabi_sys_sock_send(sock_, in_, out_)
2975}
2976
2977/// Shuts down socket send and receive channels.
2978///
2979/// ## Parameters
2980///
2981/// **sock**:
2982/// The socket that needs its channels shut down.
2983///
2984/// **how**:
2985/// Which channels on the socket need to be shut
2986/// down.
2987#[inline]
2988pub unsafe fn sock_shutdown(sock_: fd, how_: sdflags) -> errno {
2989  cloudabi_sys_sock_shutdown(sock_, how_)
2990}
2991
2992/// Creates a new thread within the current process.
2993///
2994/// ## Parameters
2995///
2996/// **attr**:
2997/// The desired attributes of the new thread.
2998///
2999/// **tid**:
3000/// The thread ID of the new thread.
3001#[inline]
3002pub unsafe fn thread_create(attr_: *mut threadattr, tid_: *mut tid) -> errno {
3003  cloudabi_sys_thread_create(attr_, tid_)
3004}
3005
3006/// Terminates the calling thread.
3007///
3008/// This system call can also unlock a single userspace lock
3009/// after termination, which can be used to implement thread
3010/// joining.
3011///
3012/// ## Parameters
3013///
3014/// **lock**:
3015/// Userspace lock that is locked for writing by
3016/// the calling thread.
3017///
3018/// **scope**:
3019/// Whether the lock is stored in private or
3020/// shared memory.
3021#[inline]
3022pub unsafe fn thread_exit(lock_: *mut lock, scope_: scope) -> ! {
3023  cloudabi_sys_thread_exit(lock_, scope_)
3024}
3025
3026/// Temporarily yields execution of the calling thread.
3027#[inline]
3028pub unsafe fn thread_yield() -> errno {
3029  cloudabi_sys_thread_yield()
3030}