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}