зеркало из https://github.com/mozilla/gecko-dev.git
2848 строки
94 KiB
Rust
2848 строки
94 KiB
Rust
// Copyright (c) 2016-2017 Nuxi (https://nuxi.nl/) and contributors.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions
|
|
// are met:
|
|
// 1. Redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
// 2. Redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
// SUCH DAMAGE.
|
|
//
|
|
// This file is automatically generated. Do not edit.
|
|
//
|
|
// Source: https://github.com/NuxiNL/cloudabi
|
|
|
|
// Appease Rust's tidy.
|
|
// ignore-license
|
|
// ignore-tidy-linelength
|
|
|
|
//! **PLEASE NOTE: This entire crate including this
|
|
//! documentation is automatically generated from
|
|
//! [`cloudabi.txt`](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt)**
|
|
//!
|
|
//! # Nuxi CloudABI
|
|
//!
|
|
//! CloudABI is what you get if you take POSIX, add capability-based
|
|
//! security, and remove everything that's incompatible with that. The
|
|
//! result is a minimal ABI consisting of only 49 syscalls.
|
|
//!
|
|
//! CloudABI doesn't have its own kernel, but instead is implemented in existing
|
|
//! kernels: FreeBSD has CloudABI support for x86-64 and arm64, and [a patch-set
|
|
//! for NetBSD](https://github.com/NuxiNL/netbsd) and [a patch-set for
|
|
//! Linux](https://github.com/NuxiNL/linux) are available as well. This means that
|
|
//! CloudABI binaries can be executed on different operating systems, without any
|
|
//! modification.
|
|
//!
|
|
//! ## Capability-Based Security
|
|
//!
|
|
//! Capability-based security means that processes can only perform
|
|
//! actions that have no global impact. Processes cannot open files by
|
|
//! their absolute path, cannot open network connections, and cannot
|
|
//! observe global system state such as the process table.
|
|
//!
|
|
//! The capabilities of a process are fully determined by its set of open
|
|
//! file descriptors (fds). For example, files can only be opened if the
|
|
//! process already has a file descriptor to a directory the file is in.
|
|
//!
|
|
//! Unlike in POSIX, where processes are normally started with file
|
|
//! descriptors 0, 1, and 2 reserved for standard input, output, and
|
|
//! error, CloudABI does not reserve any file descriptor numbers for
|
|
//! specific purposes.
|
|
//!
|
|
//! In CloudABI, a process depends on its parent process to launch it with
|
|
//! the right set of resources, since the process will not be able to open
|
|
//! any new resources. For example, a simple static web server would need
|
|
//! to be started with a file descriptor to a [TCP
|
|
//! listener](https://github.com/NuxiNL/flower), and a file descriptor to
|
|
//! the directory for which to serve files. The web server will then be
|
|
//! unable to do anything other than reading files in that directory, and
|
|
//! process incoming network connections.
|
|
//!
|
|
//! So, unknown CloudABI binaries can safely be executed without the need
|
|
//! for containers, virtual machines, or other sandboxing technologies.
|
|
//!
|
|
//! Watch [Ed Schouten's Talk at
|
|
//! 32C3](https://www.youtube.com/watch?v=3N29vrPoDv8) for more
|
|
//! information about what capability-based security for UNIX means.
|
|
//!
|
|
//! ## Cloudlibc
|
|
//!
|
|
//! [Cloudlibc](https://github.com/NuxiNL/cloudlibc) is an implementation
|
|
//! of the C standard library, without all CloudABI-incompatible
|
|
//! functions. For example, Cloudlibc does not have `printf`, but does
|
|
//! have `fprintf`. It does not have `open`, but does have `openat`.
|
|
//!
|
|
//! ## CloudABI-Ports
|
|
//!
|
|
//! [CloudABI-Ports](https://github.com/NuxiNL/cloudabi-ports) is a
|
|
//! collection of ports of commonly used libraries and applications to
|
|
//! CloudABI. It contains software such as `zlib`, `libpng`, `boost`,
|
|
//! `memcached`, and much more. The software is patched to not depend on
|
|
//! any global state, such as files in `/etc` or `/dev`, using `open()`,
|
|
//! etc.
|
|
//!
|
|
//! ## Using CloudABI
|
|
//!
|
|
//! Instructions for using CloudABI (including kernel modules/patches,
|
|
//! toolchain, and ports) are available for several operating systems:
|
|
//!
|
|
//! - [Arch Linux](https://nuxi.nl/cloudabi/archlinux/)
|
|
//! - [Debian, Ubuntu, and other Debian derivatives](https://nuxi.nl/cloudabi/debian/)
|
|
//! - [FreeBSD, PC-BSD and DragonFly BSD](https://nuxi.nl/cloudabi/freebsd/)
|
|
//! - [Mac OS X](https://nuxi.nl/cloudabi/mac/)
|
|
//! - [NetBSD](https://nuxi.nl/cloudabi/netbsd/)
|
|
//!
|
|
//! ## Specification of the ABI
|
|
//!
|
|
//! The entire ABI is specified in a a file called
|
|
//! [`cloudabi.txt`](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt),
|
|
//! from which all
|
|
//! [headers](https://github.com/NuxiNL/cloudabi/tree/master/headers)
|
|
//! and documentation (including the one you're reading now) is generated.
|
|
|
|
#![no_std]
|
|
#![allow(non_camel_case_types)]
|
|
|
|
include!("bitflags.rs");
|
|
|
|
/// File or memory access pattern advisory information.
|
|
#[repr(u8)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub enum advice {
|
|
/// The application expects that it will not access the
|
|
/// specified data in the near future.
|
|
DONTNEED = 1,
|
|
/// The application expects to access the specified data
|
|
/// once and then not reuse it thereafter.
|
|
NOREUSE = 2,
|
|
/// The application has no advice to give on its behavior
|
|
/// with respect to the specified data.
|
|
NORMAL = 3,
|
|
/// The application expects to access the specified data
|
|
/// in a random order.
|
|
RANDOM = 4,
|
|
/// The application expects to access the specified data
|
|
/// sequentially from lower offsets to higher offsets.
|
|
SEQUENTIAL = 5,
|
|
/// The application expects to access the specified data
|
|
/// in the near future.
|
|
WILLNEED = 6,
|
|
#[doc(hidden)] _NonExhaustive = -1 as isize as u8,
|
|
}
|
|
|
|
/// Enumeration describing the kind of value stored in [`auxv`](struct.auxv.html).
|
|
#[repr(u32)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub enum auxtype {
|
|
/// Base address of the binary argument data provided to
|
|
/// [`proc_exec()`](fn.proc_exec.html).
|
|
ARGDATA = 256,
|
|
/// Length of the binary argument data provided to
|
|
/// [`proc_exec()`](fn.proc_exec.html).
|
|
ARGDATALEN = 257,
|
|
/// Base address at which the executable is placed in
|
|
/// memory.
|
|
BASE = 7,
|
|
/// Base address of a buffer of random data that may be
|
|
/// used for non-cryptographic purposes, for example as a
|
|
/// canary for stack smashing protection.
|
|
CANARY = 258,
|
|
/// Length of a buffer of random data that may be used
|
|
/// for non-cryptographic purposes, for example as a
|
|
/// canary for stack smashing protection.
|
|
CANARYLEN = 259,
|
|
/// Number of CPUs that the system this process is running
|
|
/// on has.
|
|
NCPUS = 260,
|
|
/// Terminator of the auxiliary vector.
|
|
NULL = 0,
|
|
/// Smallest memory object size for which individual
|
|
/// memory protection controls can be configured.
|
|
PAGESZ = 6,
|
|
/// Address of the first ELF program header of the
|
|
/// executable.
|
|
PHDR = 3,
|
|
/// Number of ELF program headers of the executable.
|
|
PHNUM = 4,
|
|
/// Identifier of the process.
|
|
///
|
|
/// This environment does not provide any simple numerical
|
|
/// process identifiers, for the reason that these are not
|
|
/// useful in distributed contexts. Instead, processes are
|
|
/// identified by a UUID.
|
|
///
|
|
/// This record should point to sixteen bytes of binary
|
|
/// data, containing a version 4 UUID (fully random).
|
|
PID = 263,
|
|
/// Address of the ELF header of the vDSO.
|
|
///
|
|
/// The vDSO is a shared library that is mapped in the
|
|
/// address space of the process. It provides entry points
|
|
/// for every system call supported by the environment,
|
|
/// all having a corresponding symbol that is prefixed
|
|
/// with `cloudabi_sys_`. System calls should be invoked
|
|
/// through these entry points.
|
|
///
|
|
/// The first advantage of letting processes call into a
|
|
/// vDSO to perform system calls instead of raising
|
|
/// hardware traps is that it allows for easy emulation of
|
|
/// executables on top of existing operating systems. The
|
|
/// second advantage is that in cases where an operating
|
|
/// system provides native support for CloudABI executables,
|
|
/// it may still implement partial userspace
|
|
/// implementations of these system calls to improve
|
|
/// performance (e.g., [`clock_time_get()`](fn.clock_time_get.html)). It also provides
|
|
/// a more dynamic way of adding, removing or replacing
|
|
/// system calls.
|
|
SYSINFO_EHDR = 262,
|
|
/// Thread ID of the initial thread of the process.
|
|
TID = 261,
|
|
#[doc(hidden)] _NonExhaustive = -1 as isize as u32,
|
|
}
|
|
|
|
/// Identifiers for clocks.
|
|
#[repr(u32)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub enum clockid {
|
|
/// The system-wide monotonic clock, which is defined as a
|
|
/// clock measuring real time, whose value cannot be
|
|
/// adjusted and which cannot have negative clock jumps.
|
|
///
|
|
/// The epoch of this clock is undefined. The absolute
|
|
/// time value of this clock therefore has no meaning.
|
|
MONOTONIC = 1,
|
|
/// The CPU-time clock associated with the current
|
|
/// process.
|
|
PROCESS_CPUTIME_ID = 2,
|
|
/// The system-wide clock measuring real time. Time value
|
|
/// zero corresponds with 1970-01-01T00:00:00Z.
|
|
REALTIME = 3,
|
|
/// The CPU-time clock associated with the current thread.
|
|
THREAD_CPUTIME_ID = 4,
|
|
#[doc(hidden)] _NonExhaustive = -1 as isize as u32,
|
|
}
|
|
|
|
/// A userspace condition variable.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub struct condvar(pub u32);
|
|
/// The condition variable is in its initial state. There
|
|
/// are no threads waiting to be woken up. If the
|
|
/// condition variable has any other value, the kernel
|
|
/// must be called to wake up any sleeping threads.
|
|
pub const CONDVAR_HAS_NO_WAITERS: condvar = condvar(0);
|
|
|
|
/// Identifier for a device containing a file system. Can be used
|
|
/// in combination with [`inode`](struct.inode.html) to uniquely identify a file on the
|
|
/// local system.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub struct device(pub u64);
|
|
|
|
/// A reference to the offset of a directory entry.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub struct dircookie(pub u64);
|
|
/// Permanent reference to the first directory entry
|
|
/// within a directory.
|
|
pub const DIRCOOKIE_START: dircookie = dircookie(0);
|
|
|
|
/// Error codes returned by system calls.
|
|
///
|
|
/// Not all of these error codes are returned by the system calls
|
|
/// provided by this environment, but are either used in userspace
|
|
/// exclusively or merely provided for alignment with POSIX.
|
|
#[repr(u16)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub enum errno {
|
|
/// No error occurred. System call completed successfully.
|
|
SUCCESS = 0,
|
|
/// Argument list too long.
|
|
TOOBIG = 1,
|
|
/// Permission denied.
|
|
ACCES = 2,
|
|
/// Address in use.
|
|
ADDRINUSE = 3,
|
|
/// Address not available.
|
|
ADDRNOTAVAIL = 4,
|
|
/// Address family not supported.
|
|
AFNOSUPPORT = 5,
|
|
/// Resource unavailable, or operation would block.
|
|
AGAIN = 6,
|
|
/// Connection already in progress.
|
|
ALREADY = 7,
|
|
/// Bad file descriptor.
|
|
BADF = 8,
|
|
/// Bad message.
|
|
BADMSG = 9,
|
|
/// Device or resource busy.
|
|
BUSY = 10,
|
|
/// Operation canceled.
|
|
CANCELED = 11,
|
|
/// No child processes.
|
|
CHILD = 12,
|
|
/// Connection aborted.
|
|
CONNABORTED = 13,
|
|
/// Connection refused.
|
|
CONNREFUSED = 14,
|
|
/// Connection reset.
|
|
CONNRESET = 15,
|
|
/// Resource deadlock would occur.
|
|
DEADLK = 16,
|
|
/// Destination address required.
|
|
DESTADDRREQ = 17,
|
|
/// Mathematics argument out of domain of function.
|
|
DOM = 18,
|
|
/// Reserved.
|
|
DQUOT = 19,
|
|
/// File exists.
|
|
EXIST = 20,
|
|
/// Bad address.
|
|
FAULT = 21,
|
|
/// File too large.
|
|
FBIG = 22,
|
|
/// Host is unreachable.
|
|
HOSTUNREACH = 23,
|
|
/// Identifier removed.
|
|
IDRM = 24,
|
|
/// Illegal byte sequence.
|
|
ILSEQ = 25,
|
|
/// Operation in progress.
|
|
INPROGRESS = 26,
|
|
/// Interrupted function.
|
|
INTR = 27,
|
|
/// Invalid argument.
|
|
INVAL = 28,
|
|
/// I/O error.
|
|
IO = 29,
|
|
/// Socket is connected.
|
|
ISCONN = 30,
|
|
/// Is a directory.
|
|
ISDIR = 31,
|
|
/// Too many levels of symbolic links.
|
|
LOOP = 32,
|
|
/// File descriptor value too large.
|
|
MFILE = 33,
|
|
/// Too many links.
|
|
MLINK = 34,
|
|
/// Message too large.
|
|
MSGSIZE = 35,
|
|
/// Reserved.
|
|
MULTIHOP = 36,
|
|
/// Filename too long.
|
|
NAMETOOLONG = 37,
|
|
/// Network is down.
|
|
NETDOWN = 38,
|
|
/// Connection aborted by network.
|
|
NETRESET = 39,
|
|
/// Network unreachable.
|
|
NETUNREACH = 40,
|
|
/// Too many files open in system.
|
|
NFILE = 41,
|
|
/// No buffer space available.
|
|
NOBUFS = 42,
|
|
/// No such device.
|
|
NODEV = 43,
|
|
/// No such file or directory.
|
|
NOENT = 44,
|
|
/// Executable file format error.
|
|
NOEXEC = 45,
|
|
/// No locks available.
|
|
NOLCK = 46,
|
|
/// Reserved.
|
|
NOLINK = 47,
|
|
/// Not enough space.
|
|
NOMEM = 48,
|
|
/// No message of the desired type.
|
|
NOMSG = 49,
|
|
/// Protocol not available.
|
|
NOPROTOOPT = 50,
|
|
/// No space left on device.
|
|
NOSPC = 51,
|
|
/// Function not supported.
|
|
NOSYS = 52,
|
|
/// The socket is not connected.
|
|
NOTCONN = 53,
|
|
/// Not a directory or a symbolic link to a directory.
|
|
NOTDIR = 54,
|
|
/// Directory not empty.
|
|
NOTEMPTY = 55,
|
|
/// State not recoverable.
|
|
NOTRECOVERABLE = 56,
|
|
/// Not a socket.
|
|
NOTSOCK = 57,
|
|
/// Not supported, or operation not supported on socket.
|
|
NOTSUP = 58,
|
|
/// Inappropriate I/O control operation.
|
|
NOTTY = 59,
|
|
/// No such device or address.
|
|
NXIO = 60,
|
|
/// Value too large to be stored in data type.
|
|
OVERFLOW = 61,
|
|
/// Previous owner died.
|
|
OWNERDEAD = 62,
|
|
/// Operation not permitted.
|
|
PERM = 63,
|
|
/// Broken pipe.
|
|
PIPE = 64,
|
|
/// Protocol error.
|
|
PROTO = 65,
|
|
/// Protocol not supported.
|
|
PROTONOSUPPORT = 66,
|
|
/// Protocol wrong type for socket.
|
|
PROTOTYPE = 67,
|
|
/// Result too large.
|
|
RANGE = 68,
|
|
/// Read-only file system.
|
|
ROFS = 69,
|
|
/// Invalid seek.
|
|
SPIPE = 70,
|
|
/// No such process.
|
|
SRCH = 71,
|
|
/// Reserved.
|
|
STALE = 72,
|
|
/// Connection timed out.
|
|
TIMEDOUT = 73,
|
|
/// Text file busy.
|
|
TXTBSY = 74,
|
|
/// Cross-device link.
|
|
XDEV = 75,
|
|
/// Extension: Capabilities insufficient.
|
|
NOTCAPABLE = 76,
|
|
#[doc(hidden)] _NonExhaustive = -1 as isize as u16,
|
|
}
|
|
|
|
bitflags! {
|
|
/// The state of the file descriptor subscribed to with
|
|
/// [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
|
|
#[repr(C)]
|
|
pub struct eventrwflags: u16 {
|
|
/// The peer of this socket has closed or disconnected.
|
|
const HANGUP = 0x0001;
|
|
}
|
|
}
|
|
|
|
/// Type of a subscription to an event or its occurrence.
|
|
#[repr(u8)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub enum eventtype {
|
|
/// The time value of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id)
|
|
/// has reached timestamp [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout).
|
|
CLOCK = 1,
|
|
/// Condition variable [`subscription.union.condvar.condvar`](struct.subscription_condvar.html#structfield.condvar) has
|
|
/// been woken up and [`subscription.union.condvar.lock`](struct.subscription_condvar.html#structfield.lock) has been
|
|
/// acquired for writing.
|
|
CONDVAR = 2,
|
|
/// File descriptor [`subscription.union.fd_readwrite.fd`](struct.subscription_fd_readwrite.html#structfield.fd) has
|
|
/// data available for reading. This event always triggers
|
|
/// for regular files.
|
|
FD_READ = 3,
|
|
/// File descriptor [`subscription.union.fd_readwrite.fd`](struct.subscription_fd_readwrite.html#structfield.fd) has
|
|
/// capacity available for writing. This event always
|
|
/// triggers for regular files.
|
|
FD_WRITE = 4,
|
|
/// Lock [`subscription.union.lock.lock`](struct.subscription_lock.html#structfield.lock) has been acquired for
|
|
/// reading.
|
|
LOCK_RDLOCK = 5,
|
|
/// Lock [`subscription.union.lock.lock`](struct.subscription_lock.html#structfield.lock) has been acquired for
|
|
/// writing.
|
|
LOCK_WRLOCK = 6,
|
|
/// The process associated with process descriptor
|
|
/// [`subscription.union.proc_terminate.fd`](struct.subscription_proc_terminate.html#structfield.fd) has terminated.
|
|
PROC_TERMINATE = 7,
|
|
#[doc(hidden)] _NonExhaustive = -1 as isize as u8,
|
|
}
|
|
|
|
/// Exit code generated by a process when exiting.
|
|
pub type exitcode = u32;
|
|
|
|
/// A file descriptor number.
|
|
///
|
|
/// Unlike on POSIX-compliant systems, none of the file descriptor
|
|
/// numbers are reserved for a purpose (e.g., stdin, stdout,
|
|
/// stderr). Operating systems are not required to allocate new
|
|
/// file descriptors in ascending order.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub struct fd(pub u32);
|
|
/// Returned to the child process by [`proc_fork()`](fn.proc_fork.html).
|
|
pub const PROCESS_CHILD: fd = fd(0xffffffff);
|
|
/// Passed to [`mem_map()`](fn.mem_map.html) when creating a mapping to
|
|
/// anonymous memory.
|
|
pub const MAP_ANON_FD : fd = fd(0xffffffff);
|
|
|
|
bitflags! {
|
|
/// File descriptor flags.
|
|
#[repr(C)]
|
|
pub struct fdflags: u16 {
|
|
/// Append mode: Data written to the file is always
|
|
/// appended to the file's end.
|
|
const APPEND = 0x0001;
|
|
/// Write according to synchronized I/O data integrity
|
|
/// completion. Only the data stored in the file is
|
|
/// synchronized.
|
|
const DSYNC = 0x0002;
|
|
/// Non-blocking mode.
|
|
const NONBLOCK = 0x0004;
|
|
/// Synchronized read I/O operations.
|
|
const RSYNC = 0x0008;
|
|
/// Write according to synchronized I/O file integrity
|
|
/// completion. In addition to synchronizing the data
|
|
/// stored in the file, the system may also synchronously
|
|
/// update the file's metadata.
|
|
const SYNC = 0x0010;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
/// Which file descriptor attributes to adjust.
|
|
#[repr(C)]
|
|
pub struct fdsflags: u16 {
|
|
/// Adjust the file descriptor flags stored in
|
|
/// [`fdstat.fs_flags`](struct.fdstat.html#structfield.fs_flags).
|
|
const FLAGS = 0x0001;
|
|
/// Restrict the rights of the file descriptor to the
|
|
/// rights stored in [`fdstat.fs_rights_base`](struct.fdstat.html#structfield.fs_rights_base) and
|
|
/// [`fdstat.fs_rights_inheriting`](struct.fdstat.html#structfield.fs_rights_inheriting).
|
|
const RIGHTS = 0x0002;
|
|
}
|
|
}
|
|
|
|
/// Relative offset within a file.
|
|
pub type filedelta = i64;
|
|
|
|
/// Non-negative file size or length of a region within a file.
|
|
pub type filesize = u64;
|
|
|
|
/// The type of a file descriptor or file.
|
|
#[repr(u8)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub enum filetype {
|
|
/// The type of the file descriptor or file is unknown or
|
|
/// is different from any of the other types specified.
|
|
UNKNOWN = 0,
|
|
/// The file descriptor or file refers to a block device
|
|
/// inode.
|
|
BLOCK_DEVICE = 16,
|
|
/// The file descriptor or file refers to a character
|
|
/// device inode.
|
|
CHARACTER_DEVICE = 17,
|
|
/// The file descriptor or file refers to a directory
|
|
/// inode.
|
|
DIRECTORY = 32,
|
|
/// The file descriptor refers to a process handle.
|
|
PROCESS = 80,
|
|
/// The file descriptor or file refers to a regular file
|
|
/// inode.
|
|
REGULAR_FILE = 96,
|
|
/// The file descriptor refers to a shared memory object.
|
|
SHARED_MEMORY = 112,
|
|
/// The file descriptor or file refers to a datagram
|
|
/// socket.
|
|
SOCKET_DGRAM = 128,
|
|
/// The file descriptor or file refers to a byte-stream
|
|
/// socket.
|
|
SOCKET_STREAM = 130,
|
|
/// The file refers to a symbolic link inode.
|
|
SYMBOLIC_LINK = 144,
|
|
#[doc(hidden)] _NonExhaustive = -1 as isize as u8,
|
|
}
|
|
|
|
bitflags! {
|
|
/// Which file attributes to adjust.
|
|
#[repr(C)]
|
|
pub struct fsflags: u16 {
|
|
/// Adjust the last data access timestamp to the value
|
|
/// stored in [`filestat.st_atim`](struct.filestat.html#structfield.st_atim).
|
|
const ATIM = 0x0001;
|
|
/// Adjust the last data access timestamp to the time
|
|
/// of clock [`REALTIME`](enum.clockid.html#variant.REALTIME).
|
|
const ATIM_NOW = 0x0002;
|
|
/// Adjust the last data modification timestamp to the
|
|
/// value stored in [`filestat.st_mtim`](struct.filestat.html#structfield.st_mtim).
|
|
const MTIM = 0x0004;
|
|
/// Adjust the last data modification timestamp to the
|
|
/// time of clock [`REALTIME`](enum.clockid.html#variant.REALTIME).
|
|
const MTIM_NOW = 0x0008;
|
|
/// Truncate or extend the file to the size stored in
|
|
/// [`filestat.st_size`](struct.filestat.html#structfield.st_size).
|
|
const SIZE = 0x0010;
|
|
}
|
|
}
|
|
|
|
/// File serial number that is unique within its file system.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub struct inode(pub u64);
|
|
|
|
/// Number of hard links to an inode.
|
|
pub type linkcount = u32;
|
|
|
|
/// A userspace read-recursive readers-writer lock, similar to a
|
|
/// Linux futex or a FreeBSD umtx.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub struct lock(pub u32);
|
|
/// Value indicating that the lock is in its initial
|
|
/// unlocked state.
|
|
pub const LOCK_UNLOCKED : lock = lock(0x00000000);
|
|
/// Bitmask indicating that the lock is write-locked. If
|
|
/// set, the lower 30 bits of the lock contain the
|
|
/// identifier of the thread that owns the write lock.
|
|
/// Otherwise, the lower 30 bits of the lock contain the
|
|
/// number of acquired read locks.
|
|
pub const LOCK_WRLOCKED : lock = lock(0x40000000);
|
|
/// Bitmask indicating that the lock is either read locked
|
|
/// or write locked, and that one or more threads have
|
|
/// their execution suspended, waiting to acquire the
|
|
/// lock. The last owner of the lock must call the
|
|
/// kernel to unlock.
|
|
///
|
|
/// When the lock is acquired for reading and this bit is
|
|
/// set, it means that one or more threads are attempting
|
|
/// to acquire this lock for writing. In that case, other
|
|
/// threads should only acquire additional read locks if
|
|
/// suspending execution would cause a deadlock. It is
|
|
/// preferred to suspend execution, as this prevents
|
|
/// starvation of writers.
|
|
pub const LOCK_KERNEL_MANAGED: lock = lock(0x80000000);
|
|
/// Value indicating that the lock is in an incorrect
|
|
/// state. A lock cannot be in its initial unlocked state,
|
|
/// while also managed by the kernel.
|
|
pub const LOCK_BOGUS : lock = lock(0x80000000);
|
|
|
|
bitflags! {
|
|
/// Flags determining the method of how paths are resolved.
|
|
#[repr(C)]
|
|
pub struct lookupflags: u32 {
|
|
/// As long as the resolved path corresponds to a symbolic
|
|
/// link, it is expanded.
|
|
const SYMLINK_FOLLOW = 0x00000001;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
/// Memory mapping flags.
|
|
#[repr(C)]
|
|
pub struct mflags: u8 {
|
|
/// Instead of mapping the contents of the file provided,
|
|
/// create a mapping to anonymous memory. The file
|
|
/// descriptor argument must be set to [`MAP_ANON_FD`](constant.MAP_ANON_FD.html),
|
|
/// and the offset must be set to zero.
|
|
const ANON = 0x01;
|
|
/// Require that the mapping is performed at the base
|
|
/// address provided.
|
|
const FIXED = 0x02;
|
|
/// Changes are private.
|
|
const PRIVATE = 0x04;
|
|
/// Changes are shared.
|
|
const SHARED = 0x08;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
/// Memory page protection options.
|
|
///
|
|
/// This implementation enforces the `W^X` property: Pages cannot be
|
|
/// mapped for execution while also mapped for writing.
|
|
#[repr(C)]
|
|
pub struct mprot: u8 {
|
|
/// Page can be executed.
|
|
const EXEC = 0x01;
|
|
/// Page can be written.
|
|
const WRITE = 0x02;
|
|
/// Page can be read.
|
|
const READ = 0x04;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
/// Methods of synchronizing memory with physical storage.
|
|
#[repr(C)]
|
|
pub struct msflags: u8 {
|
|
/// Perform asynchronous writes.
|
|
const ASYNC = 0x01;
|
|
/// Invalidate cached data.
|
|
const INVALIDATE = 0x02;
|
|
/// Perform synchronous writes.
|
|
const SYNC = 0x04;
|
|
}
|
|
}
|
|
|
|
/// Specifies the number of threads sleeping on a condition
|
|
/// variable that should be woken up.
|
|
pub type nthreads = u32;
|
|
|
|
bitflags! {
|
|
/// Open flags used by [`file_open()`](fn.file_open.html).
|
|
#[repr(C)]
|
|
pub struct oflags: u16 {
|
|
/// Create file if it does not exist.
|
|
const CREAT = 0x0001;
|
|
/// Fail if not a directory.
|
|
const DIRECTORY = 0x0002;
|
|
/// Fail if file already exists.
|
|
const EXCL = 0x0004;
|
|
/// Truncate file to size 0.
|
|
const TRUNC = 0x0008;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
/// Flags provided to [`sock_recv()`](fn.sock_recv.html).
|
|
#[repr(C)]
|
|
pub struct riflags: u16 {
|
|
/// Returns the message without removing it from the
|
|
/// socket's receive queue.
|
|
const PEEK = 0x0004;
|
|
/// On byte-stream sockets, block until the full amount
|
|
/// of data can be returned.
|
|
const WAITALL = 0x0010;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
/// File descriptor rights, determining which actions may be
|
|
/// performed.
|
|
#[repr(C)]
|
|
pub struct rights: u64 {
|
|
/// The right to invoke [`fd_datasync()`](fn.fd_datasync.html).
|
|
///
|
|
/// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
|
|
/// invoke [`file_open()`](fn.file_open.html) with [`DSYNC`](struct.fdflags.html#associatedconstant.DSYNC).
|
|
const FD_DATASYNC = 0x0000000000000001;
|
|
/// The right to invoke [`fd_read()`](fn.fd_read.html) and [`sock_recv()`](fn.sock_recv.html).
|
|
///
|
|
/// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, includes the right to
|
|
/// invoke [`mem_map()`](fn.mem_map.html) with memory protection option
|
|
/// [`READ`](struct.mprot.html#associatedconstant.READ).
|
|
///
|
|
/// If [`FD_SEEK`](struct.rights.html#associatedconstant.FD_SEEK) is set, includes the right to invoke
|
|
/// [`fd_pread()`](fn.fd_pread.html).
|
|
const FD_READ = 0x0000000000000002;
|
|
/// The right to invoke [`fd_seek()`](fn.fd_seek.html). This flag implies
|
|
/// [`FD_TELL`](struct.rights.html#associatedconstant.FD_TELL).
|
|
const FD_SEEK = 0x0000000000000004;
|
|
/// The right to invoke [`fd_stat_put()`](fn.fd_stat_put.html) with
|
|
/// [`FLAGS`](struct.fdsflags.html#associatedconstant.FLAGS).
|
|
const FD_STAT_PUT_FLAGS = 0x0000000000000008;
|
|
/// The right to invoke [`fd_sync()`](fn.fd_sync.html).
|
|
///
|
|
/// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
|
|
/// invoke [`file_open()`](fn.file_open.html) with [`RSYNC`](struct.fdflags.html#associatedconstant.RSYNC) and
|
|
/// [`DSYNC`](struct.fdflags.html#associatedconstant.DSYNC).
|
|
const FD_SYNC = 0x0000000000000010;
|
|
/// The right to invoke [`fd_seek()`](fn.fd_seek.html) in such a way that the
|
|
/// file offset remains unaltered (i.e., [`CUR`](enum.whence.html#variant.CUR) with
|
|
/// offset zero).
|
|
const FD_TELL = 0x0000000000000020;
|
|
/// The right to invoke [`fd_write()`](fn.fd_write.html) and [`sock_send()`](fn.sock_send.html).
|
|
///
|
|
/// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, includes the right to
|
|
/// invoke [`mem_map()`](fn.mem_map.html) with memory protection option
|
|
/// [`WRITE`](struct.mprot.html#associatedconstant.WRITE).
|
|
///
|
|
/// If [`FD_SEEK`](struct.rights.html#associatedconstant.FD_SEEK) is set, includes the right to
|
|
/// invoke [`fd_pwrite()`](fn.fd_pwrite.html).
|
|
const FD_WRITE = 0x0000000000000040;
|
|
/// The right to invoke [`file_advise()`](fn.file_advise.html).
|
|
const FILE_ADVISE = 0x0000000000000080;
|
|
/// The right to invoke [`file_allocate()`](fn.file_allocate.html).
|
|
const FILE_ALLOCATE = 0x0000000000000100;
|
|
/// The right to invoke [`file_create()`](fn.file_create.html) with
|
|
/// [`DIRECTORY`](enum.filetype.html#variant.DIRECTORY).
|
|
const FILE_CREATE_DIRECTORY = 0x0000000000000200;
|
|
/// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, the right to invoke
|
|
/// [`file_open()`](fn.file_open.html) with [`CREAT`](struct.oflags.html#associatedconstant.CREAT).
|
|
const FILE_CREATE_FILE = 0x0000000000000400;
|
|
/// The right to invoke [`file_link()`](fn.file_link.html) with the file
|
|
/// descriptor as the source directory.
|
|
const FILE_LINK_SOURCE = 0x0000000000001000;
|
|
/// The right to invoke [`file_link()`](fn.file_link.html) with the file
|
|
/// descriptor as the target directory.
|
|
const FILE_LINK_TARGET = 0x0000000000002000;
|
|
/// The right to invoke [`file_open()`](fn.file_open.html).
|
|
const FILE_OPEN = 0x0000000000004000;
|
|
/// The right to invoke [`file_readdir()`](fn.file_readdir.html).
|
|
const FILE_READDIR = 0x0000000000008000;
|
|
/// The right to invoke [`file_readlink()`](fn.file_readlink.html).
|
|
const FILE_READLINK = 0x0000000000010000;
|
|
/// The right to invoke [`file_rename()`](fn.file_rename.html) with the file
|
|
/// descriptor as the source directory.
|
|
const FILE_RENAME_SOURCE = 0x0000000000020000;
|
|
/// The right to invoke [`file_rename()`](fn.file_rename.html) with the file
|
|
/// descriptor as the target directory.
|
|
const FILE_RENAME_TARGET = 0x0000000000040000;
|
|
/// The right to invoke [`file_stat_fget()`](fn.file_stat_fget.html).
|
|
const FILE_STAT_FGET = 0x0000000000080000;
|
|
/// The right to invoke [`file_stat_fput()`](fn.file_stat_fput.html) with
|
|
/// [`SIZE`](struct.fsflags.html#associatedconstant.SIZE).
|
|
///
|
|
/// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
|
|
/// invoke [`file_open()`](fn.file_open.html) with [`TRUNC`](struct.oflags.html#associatedconstant.TRUNC).
|
|
const FILE_STAT_FPUT_SIZE = 0x0000000000100000;
|
|
/// The right to invoke [`file_stat_fput()`](fn.file_stat_fput.html) with
|
|
/// [`ATIM`](struct.fsflags.html#associatedconstant.ATIM), [`ATIM_NOW`](struct.fsflags.html#associatedconstant.ATIM_NOW), [`MTIM`](struct.fsflags.html#associatedconstant.MTIM),
|
|
/// and [`MTIM_NOW`](struct.fsflags.html#associatedconstant.MTIM_NOW).
|
|
const FILE_STAT_FPUT_TIMES = 0x0000000000200000;
|
|
/// The right to invoke [`file_stat_get()`](fn.file_stat_get.html).
|
|
const FILE_STAT_GET = 0x0000000000400000;
|
|
/// The right to invoke [`file_stat_put()`](fn.file_stat_put.html) with
|
|
/// [`ATIM`](struct.fsflags.html#associatedconstant.ATIM), [`ATIM_NOW`](struct.fsflags.html#associatedconstant.ATIM_NOW), [`MTIM`](struct.fsflags.html#associatedconstant.MTIM),
|
|
/// and [`MTIM_NOW`](struct.fsflags.html#associatedconstant.MTIM_NOW).
|
|
const FILE_STAT_PUT_TIMES = 0x0000000000800000;
|
|
/// The right to invoke [`file_symlink()`](fn.file_symlink.html).
|
|
const FILE_SYMLINK = 0x0000000001000000;
|
|
/// The right to invoke [`file_unlink()`](fn.file_unlink.html).
|
|
const FILE_UNLINK = 0x0000000002000000;
|
|
/// The right to invoke [`mem_map()`](fn.mem_map.html) with [`mprot`](struct.mprot.html) set to
|
|
/// zero.
|
|
const MEM_MAP = 0x0000000004000000;
|
|
/// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, the right to invoke
|
|
/// [`mem_map()`](fn.mem_map.html) with [`EXEC`](struct.mprot.html#associatedconstant.EXEC).
|
|
const MEM_MAP_EXEC = 0x0000000008000000;
|
|
/// If [`FD_READ`](struct.rights.html#associatedconstant.FD_READ) is set, includes the right to
|
|
/// invoke [`poll()`](fn.poll.html) to subscribe to [`FD_READ`](enum.eventtype.html#variant.FD_READ).
|
|
///
|
|
/// If [`FD_WRITE`](struct.rights.html#associatedconstant.FD_WRITE) is set, includes the right to
|
|
/// invoke [`poll()`](fn.poll.html) to subscribe to [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
|
|
const POLL_FD_READWRITE = 0x0000000010000000;
|
|
/// The right to invoke [`poll()`](fn.poll.html) to subscribe to
|
|
/// [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
|
|
const POLL_PROC_TERMINATE = 0x0000000040000000;
|
|
/// The right to invoke [`proc_exec()`](fn.proc_exec.html).
|
|
const PROC_EXEC = 0x0000000100000000;
|
|
/// The right to invoke [`sock_shutdown()`](fn.sock_shutdown.html).
|
|
const SOCK_SHUTDOWN = 0x0000008000000000;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
/// Flags returned by [`sock_recv()`](fn.sock_recv.html).
|
|
#[repr(C)]
|
|
pub struct roflags: u16 {
|
|
/// Returned by [`sock_recv()`](fn.sock_recv.html): List of file descriptors
|
|
/// has been truncated.
|
|
const FDS_TRUNCATED = 0x0001;
|
|
/// Returned by [`sock_recv()`](fn.sock_recv.html): Message data has been
|
|
/// truncated.
|
|
const DATA_TRUNCATED = 0x0008;
|
|
}
|
|
}
|
|
|
|
/// Indicates whether an object is stored in private or shared
|
|
/// memory.
|
|
#[repr(u8)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub enum scope {
|
|
/// The object is stored in private memory.
|
|
PRIVATE = 4,
|
|
/// The object is stored in shared memory.
|
|
SHARED = 8,
|
|
#[doc(hidden)] _NonExhaustive = -1 as isize as u8,
|
|
}
|
|
|
|
bitflags! {
|
|
/// Which channels on a socket need to be shut down.
|
|
#[repr(C)]
|
|
pub struct sdflags: u8 {
|
|
/// Disables further receive operations.
|
|
const RD = 0x01;
|
|
/// Disables further send operations.
|
|
const WR = 0x02;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
/// Flags provided to [`sock_send()`](fn.sock_send.html). As there are currently no flags
|
|
/// defined, it must be set to zero.
|
|
#[repr(C)]
|
|
pub struct siflags: u16 {
|
|
const DEFAULT = 0;
|
|
}
|
|
}
|
|
|
|
/// Signal condition.
|
|
#[repr(u8)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub enum signal {
|
|
/// Process abort signal.
|
|
///
|
|
/// Action: Terminates the process.
|
|
ABRT = 1,
|
|
/// Alarm clock.
|
|
///
|
|
/// Action: Terminates the process.
|
|
ALRM = 2,
|
|
/// Access to an undefined portion of a memory object.
|
|
///
|
|
/// Action: Terminates the process.
|
|
BUS = 3,
|
|
/// Child process terminated, stopped, or continued.
|
|
///
|
|
/// Action: Ignored.
|
|
CHLD = 4,
|
|
/// Continue executing, if stopped.
|
|
///
|
|
/// Action: Continues executing, if stopped.
|
|
CONT = 5,
|
|
/// Erroneous arithmetic operation.
|
|
///
|
|
/// Action: Terminates the process.
|
|
FPE = 6,
|
|
/// Hangup.
|
|
///
|
|
/// Action: Terminates the process.
|
|
HUP = 7,
|
|
/// Illegal instruction.
|
|
///
|
|
/// Action: Terminates the process.
|
|
ILL = 8,
|
|
/// Terminate interrupt signal.
|
|
///
|
|
/// Action: Terminates the process.
|
|
INT = 9,
|
|
/// Kill.
|
|
///
|
|
/// Action: Terminates the process.
|
|
KILL = 10,
|
|
/// Write on a pipe with no one to read it.
|
|
///
|
|
/// Action: Ignored.
|
|
PIPE = 11,
|
|
/// Terminal quit signal.
|
|
///
|
|
/// Action: Terminates the process.
|
|
QUIT = 12,
|
|
/// Invalid memory reference.
|
|
///
|
|
/// Action: Terminates the process.
|
|
SEGV = 13,
|
|
/// Stop executing.
|
|
///
|
|
/// Action: Stops executing.
|
|
STOP = 14,
|
|
/// Bad system call.
|
|
///
|
|
/// Action: Terminates the process.
|
|
SYS = 15,
|
|
/// Termination signal.
|
|
///
|
|
/// Action: Terminates the process.
|
|
TERM = 16,
|
|
/// Trace/breakpoint trap.
|
|
///
|
|
/// Action: Terminates the process.
|
|
TRAP = 17,
|
|
/// Terminal stop signal.
|
|
///
|
|
/// Action: Stops executing.
|
|
TSTP = 18,
|
|
/// Background process attempting read.
|
|
///
|
|
/// Action: Stops executing.
|
|
TTIN = 19,
|
|
/// Background process attempting write.
|
|
///
|
|
/// Action: Stops executing.
|
|
TTOU = 20,
|
|
/// High bandwidth data is available at a socket.
|
|
///
|
|
/// Action: Ignored.
|
|
URG = 21,
|
|
/// User-defined signal 1.
|
|
///
|
|
/// Action: Terminates the process.
|
|
USR1 = 22,
|
|
/// User-defined signal 2.
|
|
///
|
|
/// Action: Terminates the process.
|
|
USR2 = 23,
|
|
/// Virtual timer expired.
|
|
///
|
|
/// Action: Terminates the process.
|
|
VTALRM = 24,
|
|
/// CPU time limit exceeded.
|
|
///
|
|
/// Action: Terminates the process.
|
|
XCPU = 25,
|
|
/// File size limit exceeded.
|
|
///
|
|
/// Action: Terminates the process.
|
|
XFSZ = 26,
|
|
#[doc(hidden)] _NonExhaustive = -1 as isize as u8,
|
|
}
|
|
|
|
bitflags! {
|
|
/// Flags determining how the timestamp provided in
|
|
/// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) should be interpreted.
|
|
#[repr(C)]
|
|
pub struct subclockflags: u16 {
|
|
/// If set, treat the timestamp provided in
|
|
/// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) as an absolute timestamp
|
|
/// of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id).
|
|
///
|
|
/// If clear, treat the timestamp provided in
|
|
/// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) relative to the current
|
|
/// time value of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id).
|
|
const ABSTIME = 0x0001;
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
/// Flags influencing the method of polling for read or writing on
|
|
/// a file descriptor.
|
|
#[repr(C)]
|
|
pub struct subrwflags: u16 {
|
|
/// Deprecated. Must be set by callers and ignored by
|
|
/// implementations.
|
|
const POLL = 0x0001;
|
|
}
|
|
}
|
|
|
|
/// Unique system-local identifier of a thread. This identifier is
|
|
/// only valid during the lifetime of the thread.
|
|
///
|
|
/// Threads must be aware of their thread identifier, as it is
|
|
/// written it into locks when acquiring them for writing. It is
|
|
/// not advised to use these identifiers for any other purpose.
|
|
///
|
|
/// As the thread identifier is also stored in [`lock`](struct.lock.html) when
|
|
/// [`LOCK_WRLOCKED`](constant.LOCK_WRLOCKED.html) is set, the top two bits of the thread
|
|
/// must always be set to zero.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub struct tid(pub u32);
|
|
|
|
/// Timestamp in nanoseconds.
|
|
pub type timestamp = u64;
|
|
|
|
bitflags! {
|
|
/// Specifies whether files are unlinked or directories are
|
|
/// removed.
|
|
#[repr(C)]
|
|
pub struct ulflags: u8 {
|
|
/// If set, removes a directory. Otherwise, unlinks any
|
|
/// non-directory file.
|
|
const REMOVEDIR = 0x01;
|
|
}
|
|
}
|
|
|
|
/// User-provided value that can be attached to objects that is
|
|
/// retained when extracted from the kernel.
|
|
pub type userdata = u64;
|
|
|
|
/// Relative to which position the offset of the file descriptor
|
|
/// should be set.
|
|
#[repr(u8)]
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
|
pub enum whence {
|
|
/// Seek relative to current position.
|
|
CUR = 1,
|
|
/// Seek relative to end-of-file.
|
|
END = 2,
|
|
/// Seek relative to start-of-file.
|
|
SET = 3,
|
|
#[doc(hidden)] _NonExhaustive = -1 as isize as u8,
|
|
}
|
|
|
|
/// Auxiliary vector entry.
|
|
///
|
|
/// The auxiliary vector is a list of key-value pairs that is
|
|
/// provided to the process on startup. Unlike structures, it is
|
|
/// extensible, as it is possible to add new records later on.
|
|
/// The auxiliary vector is always terminated by an entry having
|
|
/// type [`NULL`](enum.auxtype.html#variant.NULL).
|
|
///
|
|
/// The auxiliary vector is part of the x86-64 ABI, but is used by
|
|
/// this environment on all architectures.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct auxv {
|
|
/// The type of the auxiliary vector entry.
|
|
pub a_type: auxtype,
|
|
pub union: auxv_union
|
|
}
|
|
/// A union inside `auxv`.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub union auxv_union {
|
|
/// Used when `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).
|
|
/// A numerical value.
|
|
pub a_val: usize,
|
|
/// Used when `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).
|
|
/// A pointer value.
|
|
pub a_ptr: *mut (),
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "32")]
|
|
fn auxv_layout_test_32() {
|
|
assert_eq!(::core::mem::size_of::<auxv>(), 8);
|
|
assert_eq!(::core::mem::align_of::<auxv>(), 4);
|
|
unsafe {
|
|
let obj: auxv = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.a_type as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.union.a_val as *const _ as usize - base, 4);
|
|
assert_eq!(&obj.union.a_ptr as *const _ as usize - base, 4);
|
|
}
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "64")]
|
|
fn auxv_layout_test_64() {
|
|
assert_eq!(::core::mem::size_of::<auxv>(), 16);
|
|
assert_eq!(::core::mem::align_of::<auxv>(), 8);
|
|
unsafe {
|
|
let obj: auxv = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.a_type as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.union.a_val as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.union.a_ptr as *const _ as usize - base, 8);
|
|
}
|
|
}
|
|
|
|
/// A region of memory for scatter/gather writes.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct ciovec {
|
|
/// The address and length of the buffer to be written.
|
|
pub buf: (*const (), usize),
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "32")]
|
|
fn ciovec_layout_test_32() {
|
|
assert_eq!(::core::mem::size_of::<ciovec>(), 8);
|
|
assert_eq!(::core::mem::align_of::<ciovec>(), 4);
|
|
unsafe {
|
|
let obj: ciovec = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.buf.1 as *const _ as usize - base, 4);
|
|
}
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "64")]
|
|
fn ciovec_layout_test_64() {
|
|
assert_eq!(::core::mem::size_of::<ciovec>(), 16);
|
|
assert_eq!(::core::mem::align_of::<ciovec>(), 8);
|
|
unsafe {
|
|
let obj: ciovec = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.buf.1 as *const _ as usize - base, 8);
|
|
}
|
|
}
|
|
|
|
/// A directory entry.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct dirent {
|
|
/// The offset of the next directory entry stored in this
|
|
/// directory.
|
|
pub d_next: dircookie,
|
|
/// The serial number of the file referred to by this
|
|
/// directory entry.
|
|
pub d_ino: inode,
|
|
/// The length of the name of the directory entry.
|
|
pub d_namlen: u32,
|
|
/// The type of the file referred to by this directory
|
|
/// entry.
|
|
pub d_type: filetype,
|
|
}
|
|
#[test]
|
|
fn dirent_layout_test() {
|
|
assert_eq!(::core::mem::size_of::<dirent>(), 24);
|
|
assert_eq!(::core::mem::align_of::<dirent>(), 8);
|
|
unsafe {
|
|
let obj: dirent = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.d_next as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.d_ino as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.d_namlen as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.d_type as *const _ as usize - base, 20);
|
|
}
|
|
}
|
|
|
|
/// An event that occurred.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct event {
|
|
/// User-provided value that got attached to
|
|
/// [`subscription.userdata`](struct.subscription.html#structfield.userdata).
|
|
pub userdata: userdata,
|
|
/// If non-zero, an error that occurred while processing
|
|
/// the subscription request.
|
|
pub error: errno,
|
|
/// The type of the event that occurred.
|
|
pub type_: eventtype,
|
|
pub union: event_union
|
|
}
|
|
/// A union inside `event`.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub union event_union {
|
|
/// Used when `type_` is [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
|
|
pub fd_readwrite: event_fd_readwrite,
|
|
/// Used when `type_` is [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
|
|
pub proc_terminate: event_proc_terminate,
|
|
}
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct event_fd_readwrite {
|
|
/// The number of bytes available
|
|
/// for reading or writing.
|
|
pub nbytes: filesize,
|
|
/// Obsolete.
|
|
pub unused: [u8; 4],
|
|
/// The state of the file
|
|
/// descriptor.
|
|
pub flags: eventrwflags,
|
|
}
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct event_proc_terminate {
|
|
/// Obsolete.
|
|
pub unused: [u8; 4],
|
|
/// If zero, the process has
|
|
/// exited.
|
|
/// Otherwise, the signal
|
|
/// condition causing it to
|
|
/// terminated.
|
|
pub signal: signal,
|
|
/// If exited, the exit code of
|
|
/// the process.
|
|
pub exitcode: exitcode,
|
|
}
|
|
#[test]
|
|
fn event_layout_test() {
|
|
assert_eq!(::core::mem::size_of::<event>(), 32);
|
|
assert_eq!(::core::mem::align_of::<event>(), 8);
|
|
unsafe {
|
|
let obj: event = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.userdata as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.error as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.type_ as *const _ as usize - base, 10);
|
|
assert_eq!(&obj.union.fd_readwrite.nbytes as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.union.fd_readwrite.unused as *const _ as usize - base, 24);
|
|
assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 28);
|
|
assert_eq!(&obj.union.proc_terminate.unused as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.union.proc_terminate.signal as *const _ as usize - base, 20);
|
|
assert_eq!(&obj.union.proc_terminate.exitcode as *const _ as usize - base, 24);
|
|
}
|
|
}
|
|
|
|
/// File descriptor attributes.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct fdstat {
|
|
/// File type.
|
|
pub fs_filetype: filetype,
|
|
/// File descriptor flags.
|
|
pub fs_flags: fdflags,
|
|
/// Rights that apply to this file descriptor.
|
|
pub fs_rights_base: rights,
|
|
/// Maximum set of rights that can be installed on new
|
|
/// file descriptors that are created through this file
|
|
/// descriptor, e.g., through [`file_open()`](fn.file_open.html).
|
|
pub fs_rights_inheriting: rights,
|
|
}
|
|
#[test]
|
|
fn fdstat_layout_test() {
|
|
assert_eq!(::core::mem::size_of::<fdstat>(), 24);
|
|
assert_eq!(::core::mem::align_of::<fdstat>(), 8);
|
|
unsafe {
|
|
let obj: fdstat = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.fs_filetype as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.fs_flags as *const _ as usize - base, 2);
|
|
assert_eq!(&obj.fs_rights_base as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.fs_rights_inheriting as *const _ as usize - base, 16);
|
|
}
|
|
}
|
|
|
|
/// File attributes.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct filestat {
|
|
/// Device ID of device containing the file.
|
|
pub st_dev: device,
|
|
/// File serial number.
|
|
pub st_ino: inode,
|
|
/// File type.
|
|
pub st_filetype: filetype,
|
|
/// Number of hard links to the file.
|
|
pub st_nlink: linkcount,
|
|
/// For regular files, the file size in bytes. For
|
|
/// symbolic links, the length in bytes of the pathname
|
|
/// contained in the symbolic link.
|
|
pub st_size: filesize,
|
|
/// Last data access timestamp.
|
|
pub st_atim: timestamp,
|
|
/// Last data modification timestamp.
|
|
pub st_mtim: timestamp,
|
|
/// Last file status change timestamp.
|
|
pub st_ctim: timestamp,
|
|
}
|
|
#[test]
|
|
fn filestat_layout_test() {
|
|
assert_eq!(::core::mem::size_of::<filestat>(), 56);
|
|
assert_eq!(::core::mem::align_of::<filestat>(), 8);
|
|
unsafe {
|
|
let obj: filestat = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.st_dev as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.st_ino as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.st_filetype as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.st_nlink as *const _ as usize - base, 20);
|
|
assert_eq!(&obj.st_size as *const _ as usize - base, 24);
|
|
assert_eq!(&obj.st_atim as *const _ as usize - base, 32);
|
|
assert_eq!(&obj.st_mtim as *const _ as usize - base, 40);
|
|
assert_eq!(&obj.st_ctim as *const _ as usize - base, 48);
|
|
}
|
|
}
|
|
|
|
/// A region of memory for scatter/gather reads.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct iovec {
|
|
/// The address and length of the buffer to be filled.
|
|
pub buf: (*mut (), usize),
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "32")]
|
|
fn iovec_layout_test_32() {
|
|
assert_eq!(::core::mem::size_of::<iovec>(), 8);
|
|
assert_eq!(::core::mem::align_of::<iovec>(), 4);
|
|
unsafe {
|
|
let obj: iovec = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.buf.1 as *const _ as usize - base, 4);
|
|
}
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "64")]
|
|
fn iovec_layout_test_64() {
|
|
assert_eq!(::core::mem::size_of::<iovec>(), 16);
|
|
assert_eq!(::core::mem::align_of::<iovec>(), 8);
|
|
unsafe {
|
|
let obj: iovec = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.buf.1 as *const _ as usize - base, 8);
|
|
}
|
|
}
|
|
|
|
/// Path lookup properties.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct lookup {
|
|
/// The working directory at which the resolution of the
|
|
/// path starts.
|
|
pub fd: fd,
|
|
/// Flags determining the method of how the path is
|
|
/// resolved.
|
|
pub flags: lookupflags,
|
|
}
|
|
#[test]
|
|
fn lookup_layout_test() {
|
|
assert_eq!(::core::mem::size_of::<lookup>(), 8);
|
|
assert_eq!(::core::mem::align_of::<lookup>(), 4);
|
|
unsafe {
|
|
let obj: lookup = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.fd as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.flags as *const _ as usize - base, 4);
|
|
}
|
|
}
|
|
|
|
/// Entry point for a process (`_start`).
|
|
///
|
|
/// **auxv**:
|
|
/// The auxiliary vector. See [`auxv`](struct.auxv.html).
|
|
pub type processentry = unsafe extern "C" fn(
|
|
auxv: *const auxv,
|
|
) -> ();
|
|
|
|
/// Arguments of [`sock_recv()`](fn.sock_recv.html).
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct recv_in {
|
|
/// List of scatter/gather vectors where message data
|
|
/// should be stored.
|
|
pub ri_data: (*const iovec, usize),
|
|
/// Buffer where numbers of incoming file descriptors
|
|
/// should be stored.
|
|
pub ri_fds: (*mut fd, usize),
|
|
/// Message flags.
|
|
pub ri_flags: riflags,
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "32")]
|
|
fn recv_in_layout_test_32() {
|
|
assert_eq!(::core::mem::size_of::<recv_in>(), 20);
|
|
assert_eq!(::core::mem::align_of::<recv_in>(), 4);
|
|
unsafe {
|
|
let obj: recv_in = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.ri_data.0 as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.ri_data.1 as *const _ as usize - base, 4);
|
|
assert_eq!(&obj.ri_fds.0 as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.ri_fds.1 as *const _ as usize - base, 12);
|
|
assert_eq!(&obj.ri_flags as *const _ as usize - base, 16);
|
|
}
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "64")]
|
|
fn recv_in_layout_test_64() {
|
|
assert_eq!(::core::mem::size_of::<recv_in>(), 40);
|
|
assert_eq!(::core::mem::align_of::<recv_in>(), 8);
|
|
unsafe {
|
|
let obj: recv_in = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.ri_data.0 as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.ri_data.1 as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.ri_fds.0 as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.ri_fds.1 as *const _ as usize - base, 24);
|
|
assert_eq!(&obj.ri_flags as *const _ as usize - base, 32);
|
|
}
|
|
}
|
|
|
|
/// Results of [`sock_recv()`](fn.sock_recv.html).
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct recv_out {
|
|
/// Number of bytes stored in [`recv_in.ri_data`](struct.recv_in.html#structfield.ri_data).
|
|
pub ro_datalen: usize,
|
|
/// Number of file descriptors stored in [`recv_in.ri_fds`](struct.recv_in.html#structfield.ri_fds).
|
|
pub ro_fdslen: usize,
|
|
/// Fields that were used by previous implementations.
|
|
pub ro_unused: [u8; 40],
|
|
/// Message flags.
|
|
pub ro_flags: roflags,
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "32")]
|
|
fn recv_out_layout_test_32() {
|
|
assert_eq!(::core::mem::size_of::<recv_out>(), 52);
|
|
assert_eq!(::core::mem::align_of::<recv_out>(), 4);
|
|
unsafe {
|
|
let obj: recv_out = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.ro_datalen as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.ro_fdslen as *const _ as usize - base, 4);
|
|
assert_eq!(&obj.ro_unused as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.ro_flags as *const _ as usize - base, 48);
|
|
}
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "64")]
|
|
fn recv_out_layout_test_64() {
|
|
assert_eq!(::core::mem::size_of::<recv_out>(), 64);
|
|
assert_eq!(::core::mem::align_of::<recv_out>(), 8);
|
|
unsafe {
|
|
let obj: recv_out = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.ro_datalen as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.ro_fdslen as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.ro_unused as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.ro_flags as *const _ as usize - base, 56);
|
|
}
|
|
}
|
|
|
|
/// Arguments of [`sock_send()`](fn.sock_send.html).
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct send_in {
|
|
/// List of scatter/gather vectors where message data
|
|
/// should be retrieved.
|
|
pub si_data: (*const ciovec, usize),
|
|
/// File descriptors that need to be attached to the
|
|
/// message.
|
|
pub si_fds: (*const fd, usize),
|
|
/// Message flags.
|
|
pub si_flags: siflags,
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "32")]
|
|
fn send_in_layout_test_32() {
|
|
assert_eq!(::core::mem::size_of::<send_in>(), 20);
|
|
assert_eq!(::core::mem::align_of::<send_in>(), 4);
|
|
unsafe {
|
|
let obj: send_in = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.si_data.0 as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.si_data.1 as *const _ as usize - base, 4);
|
|
assert_eq!(&obj.si_fds.0 as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.si_fds.1 as *const _ as usize - base, 12);
|
|
assert_eq!(&obj.si_flags as *const _ as usize - base, 16);
|
|
}
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "64")]
|
|
fn send_in_layout_test_64() {
|
|
assert_eq!(::core::mem::size_of::<send_in>(), 40);
|
|
assert_eq!(::core::mem::align_of::<send_in>(), 8);
|
|
unsafe {
|
|
let obj: send_in = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.si_data.0 as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.si_data.1 as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.si_fds.0 as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.si_fds.1 as *const _ as usize - base, 24);
|
|
assert_eq!(&obj.si_flags as *const _ as usize - base, 32);
|
|
}
|
|
}
|
|
|
|
/// Results of [`sock_send()`](fn.sock_send.html).
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct send_out {
|
|
/// Number of bytes transmitted.
|
|
pub so_datalen: usize,
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "32")]
|
|
fn send_out_layout_test_32() {
|
|
assert_eq!(::core::mem::size_of::<send_out>(), 4);
|
|
assert_eq!(::core::mem::align_of::<send_out>(), 4);
|
|
unsafe {
|
|
let obj: send_out = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.so_datalen as *const _ as usize - base, 0);
|
|
}
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "64")]
|
|
fn send_out_layout_test_64() {
|
|
assert_eq!(::core::mem::size_of::<send_out>(), 8);
|
|
assert_eq!(::core::mem::align_of::<send_out>(), 8);
|
|
unsafe {
|
|
let obj: send_out = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.so_datalen as *const _ as usize - base, 0);
|
|
}
|
|
}
|
|
|
|
/// Subscription to an event.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct subscription {
|
|
/// User-provided value that is attached to the
|
|
/// subscription in the kernel and returned through
|
|
/// [`event.userdata`](struct.event.html#structfield.userdata).
|
|
pub userdata: userdata,
|
|
/// Used by previous implementations. Ignored.
|
|
pub unused: u16,
|
|
/// The type of the event to which to subscribe.
|
|
///
|
|
/// Currently, [`CONDVAR`](enum.eventtype.html#variant.CONDVAR),
|
|
/// [`LOCK_RDLOCK`](enum.eventtype.html#variant.LOCK_RDLOCK), and [`LOCK_WRLOCK`](enum.eventtype.html#variant.LOCK_WRLOCK)
|
|
/// must be provided as the first subscription and may
|
|
/// only be followed by up to one other subscription,
|
|
/// having type [`CLOCK`](enum.eventtype.html#variant.CLOCK).
|
|
pub type_: eventtype,
|
|
pub union: subscription_union
|
|
}
|
|
/// A union inside `subscription`.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub union subscription_union {
|
|
/// Used when `type_` is [`CLOCK`](enum.eventtype.html#variant.CLOCK).
|
|
pub clock: subscription_clock,
|
|
/// Used when `type_` is [`CONDVAR`](enum.eventtype.html#variant.CONDVAR).
|
|
pub condvar: subscription_condvar,
|
|
/// Used when `type_` is [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
|
|
pub fd_readwrite: subscription_fd_readwrite,
|
|
/// Used when `type_` is [`LOCK_RDLOCK`](enum.eventtype.html#variant.LOCK_RDLOCK) or [`LOCK_WRLOCK`](enum.eventtype.html#variant.LOCK_WRLOCK).
|
|
pub lock: subscription_lock,
|
|
/// Used when `type_` is [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
|
|
pub proc_terminate: subscription_proc_terminate,
|
|
}
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct subscription_clock {
|
|
/// The user-defined unique
|
|
/// identifier of the clock.
|
|
pub identifier: userdata,
|
|
/// The clock against which the
|
|
/// timestamp should be compared.
|
|
pub clock_id: clockid,
|
|
/// The absolute or relative
|
|
/// timestamp.
|
|
pub timeout: timestamp,
|
|
/// The amount of time that the
|
|
/// kernel may wait additionally
|
|
/// to coalesce with other events.
|
|
pub precision: timestamp,
|
|
/// Flags specifying whether the
|
|
/// timeout is absolute or
|
|
/// relative.
|
|
pub flags: subclockflags,
|
|
}
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct subscription_condvar {
|
|
/// The condition variable on
|
|
/// which to wait to be woken up.
|
|
pub condvar: *mut condvar,
|
|
/// The lock that will be
|
|
/// released while waiting.
|
|
///
|
|
/// The lock will be reacquired
|
|
/// for writing when the condition
|
|
/// variable triggers.
|
|
pub lock: *mut lock,
|
|
/// Whether the condition variable
|
|
/// is stored in private or shared
|
|
/// memory.
|
|
pub condvar_scope: scope,
|
|
/// Whether the lock is stored in
|
|
/// private or shared memory.
|
|
pub lock_scope: scope,
|
|
}
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct subscription_fd_readwrite {
|
|
/// The file descriptor on which
|
|
/// to wait for it to become ready
|
|
/// for reading or writing.
|
|
pub fd: fd,
|
|
/// Under which conditions to
|
|
/// trigger.
|
|
pub flags: subrwflags,
|
|
}
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct subscription_lock {
|
|
/// The lock that will be acquired
|
|
/// for reading or writing.
|
|
pub lock: *mut lock,
|
|
/// Whether the lock is stored in
|
|
/// private or shared memory.
|
|
pub lock_scope: scope,
|
|
}
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct subscription_proc_terminate {
|
|
/// The process descriptor on
|
|
/// which to wait for process
|
|
/// termination.
|
|
pub fd: fd,
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "32")]
|
|
fn subscription_layout_test_32() {
|
|
assert_eq!(::core::mem::size_of::<subscription>(), 56);
|
|
assert_eq!(::core::mem::align_of::<subscription>(), 8);
|
|
unsafe {
|
|
let obj: subscription = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.userdata as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.unused as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.type_ as *const _ as usize - base, 10);
|
|
assert_eq!(&obj.union.clock.identifier as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.union.clock.clock_id as *const _ as usize - base, 24);
|
|
assert_eq!(&obj.union.clock.timeout as *const _ as usize - base, 32);
|
|
assert_eq!(&obj.union.clock.precision as *const _ as usize - base, 40);
|
|
assert_eq!(&obj.union.clock.flags as *const _ as usize - base, 48);
|
|
assert_eq!(&obj.union.condvar.condvar as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.union.condvar.lock as *const _ as usize - base, 20);
|
|
assert_eq!(&obj.union.condvar.condvar_scope as *const _ as usize - base, 24);
|
|
assert_eq!(&obj.union.condvar.lock_scope as *const _ as usize - base, 25);
|
|
assert_eq!(&obj.union.fd_readwrite.fd as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 20);
|
|
assert_eq!(&obj.union.lock.lock as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.union.lock.lock_scope as *const _ as usize - base, 20);
|
|
assert_eq!(&obj.union.proc_terminate.fd as *const _ as usize - base, 16);
|
|
}
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "64")]
|
|
fn subscription_layout_test_64() {
|
|
assert_eq!(::core::mem::size_of::<subscription>(), 56);
|
|
assert_eq!(::core::mem::align_of::<subscription>(), 8);
|
|
unsafe {
|
|
let obj: subscription = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.userdata as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.unused as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.type_ as *const _ as usize - base, 10);
|
|
assert_eq!(&obj.union.clock.identifier as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.union.clock.clock_id as *const _ as usize - base, 24);
|
|
assert_eq!(&obj.union.clock.timeout as *const _ as usize - base, 32);
|
|
assert_eq!(&obj.union.clock.precision as *const _ as usize - base, 40);
|
|
assert_eq!(&obj.union.clock.flags as *const _ as usize - base, 48);
|
|
assert_eq!(&obj.union.condvar.condvar as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.union.condvar.lock as *const _ as usize - base, 24);
|
|
assert_eq!(&obj.union.condvar.condvar_scope as *const _ as usize - base, 32);
|
|
assert_eq!(&obj.union.condvar.lock_scope as *const _ as usize - base, 33);
|
|
assert_eq!(&obj.union.fd_readwrite.fd as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 20);
|
|
assert_eq!(&obj.union.lock.lock as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.union.lock.lock_scope as *const _ as usize - base, 24);
|
|
assert_eq!(&obj.union.proc_terminate.fd as *const _ as usize - base, 16);
|
|
}
|
|
}
|
|
|
|
/// The Thread Control Block (TCB).
|
|
///
|
|
/// After a thread begins execution (at program startup or when
|
|
/// created through [`thread_create()`](fn.thread_create.html)), the CPU's registers
|
|
/// controlling Thread-Local Storage (TLS) will already be
|
|
/// initialized. They will point to an area only containing the
|
|
/// TCB.
|
|
///
|
|
/// If the thread needs space for storing thread-specific
|
|
/// variables, the thread may allocate a larger area and adjust
|
|
/// the CPU's registers to point to that area instead. However, it
|
|
/// does need to make sure that the TCB is copied over to the new
|
|
/// TLS area.
|
|
///
|
|
/// The purpose of the TCB is that it allows light-weight
|
|
/// emulators to store information related to individual threads.
|
|
/// For example, it may be used to store a copy of the CPU
|
|
/// registers prior emulation, so that TLS for the host system
|
|
/// can be restored if needed.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct tcb {
|
|
/// Pointer that may be freely assigned by the system. Its
|
|
/// value cannot be interpreted by the application.
|
|
pub parent: *mut (),
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "32")]
|
|
fn tcb_layout_test_32() {
|
|
assert_eq!(::core::mem::size_of::<tcb>(), 4);
|
|
assert_eq!(::core::mem::align_of::<tcb>(), 4);
|
|
unsafe {
|
|
let obj: tcb = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.parent as *const _ as usize - base, 0);
|
|
}
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "64")]
|
|
fn tcb_layout_test_64() {
|
|
assert_eq!(::core::mem::size_of::<tcb>(), 8);
|
|
assert_eq!(::core::mem::align_of::<tcb>(), 8);
|
|
unsafe {
|
|
let obj: tcb = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.parent as *const _ as usize - base, 0);
|
|
}
|
|
}
|
|
|
|
/// Entry point for additionally created threads.
|
|
///
|
|
/// **tid**:
|
|
/// Thread ID of the current thread.
|
|
///
|
|
/// **aux**:
|
|
/// Copy of the value stored in
|
|
/// [`threadattr.argument`](struct.threadattr.html#structfield.argument).
|
|
pub type threadentry = unsafe extern "C" fn(
|
|
tid: tid,
|
|
aux: *mut (),
|
|
) -> ();
|
|
|
|
/// Attributes for thread creation.
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct threadattr {
|
|
/// Initial program counter value.
|
|
pub entry_point: threadentry,
|
|
/// Region allocated to serve as stack space.
|
|
pub stack: (*mut (), usize),
|
|
/// Argument to be forwarded to the entry point function.
|
|
pub argument: *mut (),
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "32")]
|
|
fn threadattr_layout_test_32() {
|
|
assert_eq!(::core::mem::size_of::<threadattr>(), 16);
|
|
assert_eq!(::core::mem::align_of::<threadattr>(), 4);
|
|
unsafe {
|
|
let obj: threadattr = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.entry_point as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.stack.0 as *const _ as usize - base, 4);
|
|
assert_eq!(&obj.stack.1 as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.argument as *const _ as usize - base, 12);
|
|
}
|
|
}
|
|
#[test]
|
|
#[cfg(target_pointer_width = "64")]
|
|
fn threadattr_layout_test_64() {
|
|
assert_eq!(::core::mem::size_of::<threadattr>(), 32);
|
|
assert_eq!(::core::mem::align_of::<threadattr>(), 8);
|
|
unsafe {
|
|
let obj: threadattr = ::core::mem::uninitialized();
|
|
let base = &obj as *const _ as usize;
|
|
assert_eq!(&obj.entry_point as *const _ as usize - base, 0);
|
|
assert_eq!(&obj.stack.0 as *const _ as usize - base, 8);
|
|
assert_eq!(&obj.stack.1 as *const _ as usize - base, 16);
|
|
assert_eq!(&obj.argument as *const _ as usize - base, 24);
|
|
}
|
|
}
|
|
|
|
/// The table with pointers to all syscall implementations.
|
|
#[allow(improper_ctypes)]
|
|
extern "C" {
|
|
fn cloudabi_sys_clock_res_get(_: clockid, _: *mut timestamp) -> errno;
|
|
fn cloudabi_sys_clock_time_get(_: clockid, _: timestamp, _: *mut timestamp) -> errno;
|
|
fn cloudabi_sys_condvar_signal(_: *mut condvar, _: scope, _: nthreads) -> errno;
|
|
fn cloudabi_sys_fd_close(_: fd) -> errno;
|
|
fn cloudabi_sys_fd_create1(_: filetype, _: *mut fd) -> errno;
|
|
fn cloudabi_sys_fd_create2(_: filetype, _: *mut fd, _: *mut fd) -> errno;
|
|
fn cloudabi_sys_fd_datasync(_: fd) -> errno;
|
|
fn cloudabi_sys_fd_dup(_: fd, _: *mut fd) -> errno;
|
|
fn cloudabi_sys_fd_pread(_: fd, _: *const iovec, _: usize, _: filesize, _: *mut usize) -> errno;
|
|
fn cloudabi_sys_fd_pwrite(_: fd, _: *const ciovec, _: usize, _: filesize, _: *mut usize) -> errno;
|
|
fn cloudabi_sys_fd_read(_: fd, _: *const iovec, _: usize, _: *mut usize) -> errno;
|
|
fn cloudabi_sys_fd_replace(_: fd, _: fd) -> errno;
|
|
fn cloudabi_sys_fd_seek(_: fd, _: filedelta, _: whence, _: *mut filesize) -> errno;
|
|
fn cloudabi_sys_fd_stat_get(_: fd, _: *mut fdstat) -> errno;
|
|
fn cloudabi_sys_fd_stat_put(_: fd, _: *const fdstat, _: fdsflags) -> errno;
|
|
fn cloudabi_sys_fd_sync(_: fd) -> errno;
|
|
fn cloudabi_sys_fd_write(_: fd, _: *const ciovec, _: usize, _: *mut usize) -> errno;
|
|
fn cloudabi_sys_file_advise(_: fd, _: filesize, _: filesize, _: advice) -> errno;
|
|
fn cloudabi_sys_file_allocate(_: fd, _: filesize, _: filesize) -> errno;
|
|
fn cloudabi_sys_file_create(_: fd, _: *const u8, _: usize, _: filetype) -> errno;
|
|
fn cloudabi_sys_file_link(_: lookup, _: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
|
|
fn cloudabi_sys_file_open(_: lookup, _: *const u8, _: usize, _: oflags, _: *const fdstat, _: *mut fd) -> errno;
|
|
fn cloudabi_sys_file_readdir(_: fd, _: *mut (), _: usize, _: dircookie, _: *mut usize) -> errno;
|
|
fn cloudabi_sys_file_readlink(_: fd, _: *const u8, _: usize, _: *mut u8, _: usize, _: *mut usize) -> errno;
|
|
fn cloudabi_sys_file_rename(_: fd, _: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
|
|
fn cloudabi_sys_file_stat_fget(_: fd, _: *mut filestat) -> errno;
|
|
fn cloudabi_sys_file_stat_fput(_: fd, _: *const filestat, _: fsflags) -> errno;
|
|
fn cloudabi_sys_file_stat_get(_: lookup, _: *const u8, _: usize, _: *mut filestat) -> errno;
|
|
fn cloudabi_sys_file_stat_put(_: lookup, _: *const u8, _: usize, _: *const filestat, _: fsflags) -> errno;
|
|
fn cloudabi_sys_file_symlink(_: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
|
|
fn cloudabi_sys_file_unlink(_: fd, _: *const u8, _: usize, _: ulflags) -> errno;
|
|
fn cloudabi_sys_lock_unlock(_: *mut lock, _: scope) -> errno;
|
|
fn cloudabi_sys_mem_advise(_: *mut (), _: usize, _: advice) -> errno;
|
|
fn cloudabi_sys_mem_map(_: *mut (), _: usize, _: mprot, _: mflags, _: fd, _: filesize, _: *mut *mut ()) -> errno;
|
|
fn cloudabi_sys_mem_protect(_: *mut (), _: usize, _: mprot) -> errno;
|
|
fn cloudabi_sys_mem_sync(_: *mut (), _: usize, _: msflags) -> errno;
|
|
fn cloudabi_sys_mem_unmap(_: *mut (), _: usize) -> errno;
|
|
fn cloudabi_sys_poll(_: *const subscription, _: *mut event, _: usize, _: *mut usize) -> errno;
|
|
fn cloudabi_sys_proc_exec(_: fd, _: *const (), _: usize, _: *const fd, _: usize) -> errno;
|
|
fn cloudabi_sys_proc_exit(_: exitcode) -> !;
|
|
fn cloudabi_sys_proc_fork(_: *mut fd, _: *mut tid) -> errno;
|
|
fn cloudabi_sys_proc_raise(_: signal) -> errno;
|
|
fn cloudabi_sys_random_get(_: *mut (), _: usize) -> errno;
|
|
fn cloudabi_sys_sock_recv(_: fd, _: *const recv_in, _: *mut recv_out) -> errno;
|
|
fn cloudabi_sys_sock_send(_: fd, _: *const send_in, _: *mut send_out) -> errno;
|
|
fn cloudabi_sys_sock_shutdown(_: fd, _: sdflags) -> errno;
|
|
fn cloudabi_sys_thread_create(_: *mut threadattr, _: *mut tid) -> errno;
|
|
fn cloudabi_sys_thread_exit(_: *mut lock, _: scope) -> !;
|
|
fn cloudabi_sys_thread_yield() -> errno;
|
|
}
|
|
|
|
/// Obtains the resolution of a clock.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **clock_id**:
|
|
/// The clock for which the resolution needs to be
|
|
/// returned.
|
|
///
|
|
/// **resolution**:
|
|
/// The resolution of the clock.
|
|
#[inline]
|
|
pub unsafe fn clock_res_get(clock_id_: clockid, resolution_: &mut timestamp) -> errno {
|
|
cloudabi_sys_clock_res_get(clock_id_, resolution_)
|
|
}
|
|
|
|
/// Obtains the time value of a clock.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **clock_id**:
|
|
/// The clock for which the time needs to be
|
|
/// returned.
|
|
///
|
|
/// **precision**:
|
|
/// The maximum lag (exclusive) that the returned
|
|
/// time value may have, compared to its actual
|
|
/// value.
|
|
///
|
|
/// **time**:
|
|
/// The time value of the clock.
|
|
#[inline]
|
|
pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: &mut timestamp) -> errno {
|
|
cloudabi_sys_clock_time_get(clock_id_, precision_, time_)
|
|
}
|
|
|
|
/// Wakes up threads waiting on a userspace condition variable.
|
|
///
|
|
/// If an invocation of this system call causes all waiting
|
|
/// threads to be woken up, the value of the condition variable
|
|
/// is set to [`CONDVAR_HAS_NO_WAITERS`](constant.CONDVAR_HAS_NO_WAITERS.html). As long as the condition
|
|
/// variable is set to this value, it is not needed to invoke this
|
|
/// system call.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **condvar**:
|
|
/// The userspace condition variable that has
|
|
/// waiting threads.
|
|
///
|
|
/// **scope**:
|
|
/// Whether the condition variable is stored in
|
|
/// private or shared memory.
|
|
///
|
|
/// **nwaiters**:
|
|
/// The number of threads that need to be woken
|
|
/// up. If it exceeds the number of waiting
|
|
/// threads, all threads are woken up.
|
|
#[inline]
|
|
pub unsafe fn condvar_signal(condvar_: *mut condvar, scope_: scope, nwaiters_: nthreads) -> errno {
|
|
cloudabi_sys_condvar_signal(condvar_, scope_, nwaiters_)
|
|
}
|
|
|
|
/// Closes a file descriptor.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor that needs to be closed.
|
|
#[inline]
|
|
pub unsafe fn fd_close(fd_: fd) -> errno {
|
|
cloudabi_sys_fd_close(fd_)
|
|
}
|
|
|
|
/// Creates a file descriptor.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **type**:
|
|
/// Possible values:
|
|
///
|
|
/// - [`SHARED_MEMORY`](enum.filetype.html#variant.SHARED_MEMORY):
|
|
/// Creates an anonymous shared memory
|
|
/// object.
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor that has been created.
|
|
#[inline]
|
|
pub unsafe fn fd_create1(type_: filetype, fd_: &mut fd) -> errno {
|
|
cloudabi_sys_fd_create1(type_, fd_)
|
|
}
|
|
|
|
/// Creates a pair of file descriptors.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **type**:
|
|
/// Possible values:
|
|
///
|
|
/// - [`SOCKET_DGRAM`](enum.filetype.html#variant.SOCKET_DGRAM):
|
|
/// Creates a UNIX datagram socket pair.
|
|
/// - [`SOCKET_STREAM`](enum.filetype.html#variant.SOCKET_STREAM):
|
|
/// Creates a UNIX byte-stream socket
|
|
/// pair.
|
|
///
|
|
/// **fd1**:
|
|
/// The first file descriptor of the pair.
|
|
///
|
|
/// **fd2**:
|
|
/// The second file descriptor of the pair.
|
|
#[inline]
|
|
pub unsafe fn fd_create2(type_: filetype, fd1_: &mut fd, fd2_: &mut fd) -> errno {
|
|
cloudabi_sys_fd_create2(type_, fd1_, fd2_)
|
|
}
|
|
|
|
/// Synchronizes the data of a file to disk.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor of the file whose data
|
|
/// needs to be synchronized to disk.
|
|
#[inline]
|
|
pub unsafe fn fd_datasync(fd_: fd) -> errno {
|
|
cloudabi_sys_fd_datasync(fd_)
|
|
}
|
|
|
|
/// Duplicates a file descriptor.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **from**:
|
|
/// The file descriptor that needs to be
|
|
/// duplicated.
|
|
///
|
|
/// **fd**:
|
|
/// The new file descriptor.
|
|
#[inline]
|
|
pub unsafe fn fd_dup(from_: fd, fd_: &mut fd) -> errno {
|
|
cloudabi_sys_fd_dup(from_, fd_)
|
|
}
|
|
|
|
/// Reads from a file descriptor, without using and updating the
|
|
/// file descriptor's offset.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor from which data should be
|
|
/// read.
|
|
///
|
|
/// **iovs**:
|
|
/// List of scatter/gather vectors where data
|
|
/// should be stored.
|
|
///
|
|
/// **offset**:
|
|
/// The offset within the file at which reading
|
|
/// should start.
|
|
///
|
|
/// **nread**:
|
|
/// The number of bytes read.
|
|
#[inline]
|
|
pub unsafe fn fd_pread(fd_: fd, iovs_: &[iovec], offset_: filesize, nread_: &mut usize) -> errno {
|
|
cloudabi_sys_fd_pread(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nread_)
|
|
}
|
|
|
|
/// Writes to a file descriptor, without using and updating the
|
|
/// file descriptor's offset.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor to which data should be
|
|
/// written.
|
|
///
|
|
/// **iovs**:
|
|
/// List of scatter/gather vectors where data
|
|
/// should be retrieved.
|
|
///
|
|
/// **offset**:
|
|
/// The offset within the file at which writing
|
|
/// should start.
|
|
///
|
|
/// **nwritten**:
|
|
/// The number of bytes written.
|
|
#[inline]
|
|
pub unsafe fn fd_pwrite(fd_: fd, iovs_: &[ciovec], offset_: filesize, nwritten_: &mut usize) -> errno {
|
|
cloudabi_sys_fd_pwrite(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nwritten_)
|
|
}
|
|
|
|
/// Reads from a file descriptor.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor from which data should be
|
|
/// read.
|
|
///
|
|
/// **iovs**:
|
|
/// List of scatter/gather vectors where data
|
|
/// should be stored.
|
|
///
|
|
/// **nread**:
|
|
/// The number of bytes read.
|
|
#[inline]
|
|
pub unsafe fn fd_read(fd_: fd, iovs_: &[iovec], nread_: &mut usize) -> errno {
|
|
cloudabi_sys_fd_read(fd_, iovs_.as_ptr(), iovs_.len(), nread_)
|
|
}
|
|
|
|
/// Atomically replaces a file descriptor by a copy of another
|
|
/// file descriptor.
|
|
///
|
|
/// Due to the strong focus on thread safety, this environment
|
|
/// does not provide a mechanism to duplicate a file descriptor to
|
|
/// an arbitrary number, like dup2(). This would be prone to race
|
|
/// conditions, as an actual file descriptor with the same number
|
|
/// could be allocated by a different thread at the same time.
|
|
///
|
|
/// This system call provides a way to atomically replace file
|
|
/// descriptors, which would disappear if dup2() were to be
|
|
/// removed entirely.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **from**:
|
|
/// The file descriptor that needs to be copied.
|
|
///
|
|
/// **to**:
|
|
/// The file descriptor that needs to be
|
|
/// overwritten.
|
|
#[inline]
|
|
pub unsafe fn fd_replace(from_: fd, to_: fd) -> errno {
|
|
cloudabi_sys_fd_replace(from_, to_)
|
|
}
|
|
|
|
/// Moves the offset of the file descriptor.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor whose offset has to be
|
|
/// moved.
|
|
///
|
|
/// **offset**:
|
|
/// The number of bytes to move.
|
|
///
|
|
/// **whence**:
|
|
/// Relative to which position the move should
|
|
/// take place.
|
|
///
|
|
/// **newoffset**:
|
|
/// The new offset of the file descriptor,
|
|
/// relative to the start of the file.
|
|
#[inline]
|
|
pub unsafe fn fd_seek(fd_: fd, offset_: filedelta, whence_: whence, newoffset_: &mut filesize) -> errno {
|
|
cloudabi_sys_fd_seek(fd_, offset_, whence_, newoffset_)
|
|
}
|
|
|
|
/// Gets attributes of a file descriptor.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor whose attributes have to
|
|
/// be obtained.
|
|
///
|
|
/// **buf**:
|
|
/// The buffer where the file descriptor's
|
|
/// attributes are stored.
|
|
#[inline]
|
|
pub unsafe fn fd_stat_get(fd_: fd, buf_: *mut fdstat) -> errno {
|
|
cloudabi_sys_fd_stat_get(fd_, buf_)
|
|
}
|
|
|
|
/// Adjusts attributes of a file descriptor.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor whose attributes have to
|
|
/// be adjusted.
|
|
///
|
|
/// **buf**:
|
|
/// The desired values of the file descriptor
|
|
/// attributes that are adjusted.
|
|
///
|
|
/// **flags**:
|
|
/// A bitmask indicating which attributes have to
|
|
/// be adjusted.
|
|
#[inline]
|
|
pub unsafe fn fd_stat_put(fd_: fd, buf_: *const fdstat, flags_: fdsflags) -> errno {
|
|
cloudabi_sys_fd_stat_put(fd_, buf_, flags_)
|
|
}
|
|
|
|
/// Synchronizes the data and metadata of a file to disk.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor of the file whose data
|
|
/// and metadata needs to be synchronized to disk.
|
|
#[inline]
|
|
pub unsafe fn fd_sync(fd_: fd) -> errno {
|
|
cloudabi_sys_fd_sync(fd_)
|
|
}
|
|
|
|
/// Writes to a file descriptor.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor to which data should be
|
|
/// written.
|
|
///
|
|
/// **iovs**:
|
|
/// List of scatter/gather vectors where data
|
|
/// should be retrieved.
|
|
///
|
|
/// **nwritten**:
|
|
/// The number of bytes written.
|
|
#[inline]
|
|
pub unsafe fn fd_write(fd_: fd, iovs_: &[ciovec], nwritten_: &mut usize) -> errno {
|
|
cloudabi_sys_fd_write(fd_, iovs_.as_ptr(), iovs_.len(), nwritten_)
|
|
}
|
|
|
|
/// Provides file advisory information on a file descriptor.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor for which to provide file
|
|
/// advisory information.
|
|
///
|
|
/// **offset**:
|
|
/// The offset within the file to which the
|
|
/// advisory applies.
|
|
///
|
|
/// **len**:
|
|
/// The length of the region to which the advisory
|
|
/// applies.
|
|
///
|
|
/// **advice**:
|
|
/// The advice.
|
|
#[inline]
|
|
pub unsafe fn file_advise(fd_: fd, offset_: filesize, len_: filesize, advice_: advice) -> errno {
|
|
cloudabi_sys_file_advise(fd_, offset_, len_, advice_)
|
|
}
|
|
|
|
/// Forces the allocation of space in a file.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file in which the space should be
|
|
/// allocated.
|
|
///
|
|
/// **offset**:
|
|
/// The offset at which the allocation should
|
|
/// start.
|
|
///
|
|
/// **len**:
|
|
/// The length of the area that is allocated.
|
|
#[inline]
|
|
pub unsafe fn file_allocate(fd_: fd, offset_: filesize, len_: filesize) -> errno {
|
|
cloudabi_sys_file_allocate(fd_, offset_, len_)
|
|
}
|
|
|
|
/// Creates a file of a specified type.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The working directory at which the resolution
|
|
/// of the file to be created starts.
|
|
///
|
|
/// **path**:
|
|
/// The path at which the file should be created.
|
|
///
|
|
/// **type**:
|
|
/// Possible values:
|
|
///
|
|
/// - [`DIRECTORY`](enum.filetype.html#variant.DIRECTORY):
|
|
/// Creates a directory.
|
|
#[inline]
|
|
pub unsafe fn file_create(fd_: fd, path_: &[u8], type_: filetype) -> errno {
|
|
cloudabi_sys_file_create(fd_, path_.as_ptr(), path_.len(), type_)
|
|
}
|
|
|
|
/// Creates a hard link.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd1**:
|
|
/// The working directory at which the resolution
|
|
/// of the source path starts.
|
|
///
|
|
/// **path1**:
|
|
/// The source path of the file that should be
|
|
/// hard linked.
|
|
///
|
|
/// **fd2**:
|
|
/// The working directory at which the resolution
|
|
/// of the destination path starts.
|
|
///
|
|
/// **path2**:
|
|
/// The destination path at which the hard link
|
|
/// should be created.
|
|
#[inline]
|
|
pub unsafe fn file_link(fd1_: lookup, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> errno {
|
|
cloudabi_sys_file_link(fd1_, path1_.as_ptr(), path1_.len(), fd2_, path2_.as_ptr(), path2_.len())
|
|
}
|
|
|
|
/// Opens a file.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **dirfd**:
|
|
/// The working directory at which the resolution
|
|
/// of the file to be opened starts.
|
|
///
|
|
/// **path**:
|
|
/// The path of the file that should be opened.
|
|
///
|
|
/// **oflags**:
|
|
/// The method at which the file should be opened.
|
|
///
|
|
/// **fds**:
|
|
/// [`fdstat.fs_rights_base`](struct.fdstat.html#structfield.fs_rights_base) and
|
|
/// [`fdstat.fs_rights_inheriting`](struct.fdstat.html#structfield.fs_rights_inheriting) specify the
|
|
/// initial rights of the newly created file
|
|
/// descriptor. The operating system is allowed to
|
|
/// return a file descriptor with fewer rights
|
|
/// than specified, if and only if those rights do
|
|
/// not apply to the type of file being opened.
|
|
///
|
|
/// [`fdstat.fs_flags`](struct.fdstat.html#structfield.fs_flags) specifies the initial flags
|
|
/// of the file descriptor.
|
|
///
|
|
/// [`fdstat.fs_filetype`](struct.fdstat.html#structfield.fs_filetype) is ignored.
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor of the file that has been
|
|
/// opened.
|
|
#[inline]
|
|
pub unsafe fn file_open(dirfd_: lookup, path_: &[u8], oflags_: oflags, fds_: *const fdstat, fd_: &mut fd) -> errno {
|
|
cloudabi_sys_file_open(dirfd_, path_.as_ptr(), path_.len(), oflags_, fds_, fd_)
|
|
}
|
|
|
|
/// Reads directory entries from a directory.
|
|
///
|
|
/// When successful, the contents of the output buffer consist of
|
|
/// a sequence of directory entries. Each directory entry consists
|
|
/// of a [`dirent`](struct.dirent.html) object, followed by [`dirent.d_namlen`](struct.dirent.html#structfield.d_namlen) bytes
|
|
/// holding the name of the directory entry.
|
|
///
|
|
/// This system call fills the output buffer as much as possible,
|
|
/// potentially truncating the last directory entry. This allows
|
|
/// the caller to grow its read buffer size in case it's too small
|
|
/// to fit a single large directory entry, or skip the oversized
|
|
/// directory entry.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The directory from which to read the directory
|
|
/// entries.
|
|
///
|
|
/// **buf**:
|
|
/// The buffer where directory entries are stored.
|
|
///
|
|
/// **cookie**:
|
|
/// The location within the directory to start
|
|
/// reading.
|
|
///
|
|
/// **bufused**:
|
|
/// The number of bytes stored in the read buffer.
|
|
/// If less than the size of the read buffer, the
|
|
/// end of the directory has been reached.
|
|
#[inline]
|
|
pub unsafe fn file_readdir(fd_: fd, buf_: &mut [u8], cookie_: dircookie, bufused_: &mut usize) -> errno {
|
|
cloudabi_sys_file_readdir(fd_, buf_.as_mut_ptr() as *mut (), buf_.len(), cookie_, bufused_)
|
|
}
|
|
|
|
/// Reads the contents of a symbolic link.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The working directory at which the resolution
|
|
/// of the path of the symbolic starts.
|
|
///
|
|
/// **path**:
|
|
/// The path of the symbolic link whose contents
|
|
/// should be read.
|
|
///
|
|
/// **buf**:
|
|
/// The buffer where the contents of the symbolic
|
|
/// link should be stored.
|
|
///
|
|
/// **bufused**:
|
|
/// The number of bytes placed in the buffer.
|
|
#[inline]
|
|
pub unsafe fn file_readlink(fd_: fd, path_: &[u8], buf_: &mut [u8], bufused_: &mut usize) -> errno {
|
|
cloudabi_sys_file_readlink(fd_, path_.as_ptr(), path_.len(), buf_.as_mut_ptr(), buf_.len(), bufused_)
|
|
}
|
|
|
|
/// Renames a file.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd1**:
|
|
/// The working directory at which the resolution
|
|
/// of the source path starts.
|
|
///
|
|
/// **path1**:
|
|
/// The source path of the file that should be
|
|
/// renamed.
|
|
///
|
|
/// **fd2**:
|
|
/// The working directory at which the resolution
|
|
/// of the destination path starts.
|
|
///
|
|
/// **path2**:
|
|
/// The destination path to which the file should
|
|
/// be renamed.
|
|
#[inline]
|
|
pub unsafe fn file_rename(fd1_: fd, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> errno {
|
|
cloudabi_sys_file_rename(fd1_, path1_.as_ptr(), path1_.len(), fd2_, path2_.as_ptr(), path2_.len())
|
|
}
|
|
|
|
/// Gets attributes of a file by file descriptor.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor whose attributes have to
|
|
/// be obtained.
|
|
///
|
|
/// **buf**:
|
|
/// The buffer where the file's attributes are
|
|
/// stored.
|
|
#[inline]
|
|
pub unsafe fn file_stat_fget(fd_: fd, buf_: *mut filestat) -> errno {
|
|
cloudabi_sys_file_stat_fget(fd_, buf_)
|
|
}
|
|
|
|
/// Adjusts attributes of a file by file descriptor.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The file descriptor whose attributes have to
|
|
/// be adjusted.
|
|
///
|
|
/// **buf**:
|
|
/// The desired values of the file attributes that
|
|
/// are adjusted.
|
|
///
|
|
/// **flags**:
|
|
/// A bitmask indicating which attributes have to
|
|
/// be adjusted.
|
|
#[inline]
|
|
pub unsafe fn file_stat_fput(fd_: fd, buf_: *const filestat, flags_: fsflags) -> errno {
|
|
cloudabi_sys_file_stat_fput(fd_, buf_, flags_)
|
|
}
|
|
|
|
/// Gets attributes of a file by path.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The working directory at which the resolution
|
|
/// of the path whose attributes have to be
|
|
/// obtained starts.
|
|
///
|
|
/// **path**:
|
|
/// The path of the file whose attributes have to
|
|
/// be obtained.
|
|
///
|
|
/// **buf**:
|
|
/// The buffer where the file's attributes are
|
|
/// stored.
|
|
#[inline]
|
|
pub unsafe fn file_stat_get(fd_: lookup, path_: &[u8], buf_: *mut filestat) -> errno {
|
|
cloudabi_sys_file_stat_get(fd_, path_.as_ptr(), path_.len(), buf_)
|
|
}
|
|
|
|
/// Adjusts attributes of a file by path.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The working directory at which the resolution
|
|
/// of the path whose attributes have to be
|
|
/// adjusted starts.
|
|
///
|
|
/// **path**:
|
|
/// The path of the file whose attributes have to
|
|
/// be adjusted.
|
|
///
|
|
/// **buf**:
|
|
/// The desired values of the file attributes that
|
|
/// are adjusted.
|
|
///
|
|
/// **flags**:
|
|
/// A bitmask indicating which attributes have to
|
|
/// be adjusted.
|
|
#[inline]
|
|
pub unsafe fn file_stat_put(fd_: lookup, path_: &[u8], buf_: *const filestat, flags_: fsflags) -> errno {
|
|
cloudabi_sys_file_stat_put(fd_, path_.as_ptr(), path_.len(), buf_, flags_)
|
|
}
|
|
|
|
/// Creates a symbolic link.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **path1**:
|
|
/// The contents of the symbolic link.
|
|
///
|
|
/// **fd**:
|
|
/// The working directory at which the resolution
|
|
/// of the destination path starts.
|
|
///
|
|
/// **path2**:
|
|
/// The destination path at which the symbolic
|
|
/// link should be created.
|
|
#[inline]
|
|
pub unsafe fn file_symlink(path1_: &[u8], fd_: fd, path2_: &[u8]) -> errno {
|
|
cloudabi_sys_file_symlink(path1_.as_ptr(), path1_.len(), fd_, path2_.as_ptr(), path2_.len())
|
|
}
|
|
|
|
/// Unlinks a file, or removes a directory.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// The working directory at which the resolution
|
|
/// of the path starts.
|
|
///
|
|
/// **path**:
|
|
/// The path that needs to be unlinked or removed.
|
|
///
|
|
/// **flags**:
|
|
/// Possible values:
|
|
///
|
|
/// - [`REMOVEDIR`](struct.ulflags.html#associatedconstant.REMOVEDIR):
|
|
/// If set, attempt to remove a directory.
|
|
/// Otherwise, unlink a file.
|
|
#[inline]
|
|
pub unsafe fn file_unlink(fd_: fd, path_: &[u8], flags_: ulflags) -> errno {
|
|
cloudabi_sys_file_unlink(fd_, path_.as_ptr(), path_.len(), flags_)
|
|
}
|
|
|
|
/// Unlocks a write-locked userspace lock.
|
|
///
|
|
/// If a userspace lock is unlocked while having its
|
|
/// [`LOCK_KERNEL_MANAGED`](constant.LOCK_KERNEL_MANAGED.html) flag set, the lock cannot be unlocked in
|
|
/// userspace directly. This system call needs to be performed
|
|
/// instead, so that any waiting threads can be woken up.
|
|
///
|
|
/// To prevent spurious invocations of this system call, the lock
|
|
/// must be locked for writing. This prevents other threads from
|
|
/// acquiring additional read locks while the system call is in
|
|
/// progress. If the lock is acquired for reading, it must first
|
|
/// be upgraded to a write lock.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **lock**:
|
|
/// The userspace lock that is locked for writing
|
|
/// by the calling thread.
|
|
///
|
|
/// **scope**:
|
|
/// Whether the lock is stored in private or
|
|
/// shared memory.
|
|
#[inline]
|
|
pub unsafe fn lock_unlock(lock_: *mut lock, scope_: scope) -> errno {
|
|
cloudabi_sys_lock_unlock(lock_, scope_)
|
|
}
|
|
|
|
/// Provides memory advisory information on a region of memory.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **mapping**:
|
|
/// The pages for which to provide memory advisory
|
|
/// information.
|
|
///
|
|
/// **advice**:
|
|
/// The advice.
|
|
#[inline]
|
|
pub unsafe fn mem_advise(mapping_: &mut [u8], advice_: advice) -> errno {
|
|
cloudabi_sys_mem_advise(mapping_.as_mut_ptr() as *mut (), mapping_.len(), advice_)
|
|
}
|
|
|
|
/// Creates a memory mapping, making the contents of a file
|
|
/// accessible through memory.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **addr**:
|
|
/// If [`FIXED`](struct.mflags.html#associatedconstant.FIXED) is set, specifies to which
|
|
/// address the file region is mapped. Otherwise,
|
|
/// the mapping is performed at an unused
|
|
/// location.
|
|
///
|
|
/// **len**:
|
|
/// The length of the memory mapping to be
|
|
/// created.
|
|
///
|
|
/// **prot**:
|
|
/// Initial memory protection options for the
|
|
/// memory mapping.
|
|
///
|
|
/// **flags**:
|
|
/// Memory mapping flags.
|
|
///
|
|
/// **fd**:
|
|
/// If [`ANON`](struct.mflags.html#associatedconstant.ANON) is set, this argument must be
|
|
/// [`MAP_ANON_FD`](constant.MAP_ANON_FD.html). Otherwise, this argument
|
|
/// specifies the file whose contents need to be
|
|
/// mapped.
|
|
///
|
|
/// **off**:
|
|
/// If [`ANON`](struct.mflags.html#associatedconstant.ANON) is set, this argument must be
|
|
/// zero. Otherwise, this argument specifies the
|
|
/// offset within the file at which the mapping
|
|
/// starts.
|
|
///
|
|
/// **mem**:
|
|
/// The starting address of the memory mapping.
|
|
#[inline]
|
|
pub unsafe fn mem_map(addr_: *mut (), len_: usize, prot_: mprot, flags_: mflags, fd_: fd, off_: filesize, mem_: &mut *mut ()) -> errno {
|
|
cloudabi_sys_mem_map(addr_, len_, prot_, flags_, fd_, off_, mem_)
|
|
}
|
|
|
|
/// Change the protection of a memory mapping.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **mapping**:
|
|
/// The pages that need their protection changed.
|
|
///
|
|
/// **prot**:
|
|
/// New protection options.
|
|
#[inline]
|
|
pub unsafe fn mem_protect(mapping_: &mut [u8], prot_: mprot) -> errno {
|
|
cloudabi_sys_mem_protect(mapping_.as_mut_ptr() as *mut (), mapping_.len(), prot_)
|
|
}
|
|
|
|
/// Synchronize a region of memory with its physical storage.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **mapping**:
|
|
/// The pages that need to be synchronized.
|
|
///
|
|
/// **flags**:
|
|
/// The method of synchronization.
|
|
#[inline]
|
|
pub unsafe fn mem_sync(mapping_: &mut [u8], flags_: msflags) -> errno {
|
|
cloudabi_sys_mem_sync(mapping_.as_mut_ptr() as *mut (), mapping_.len(), flags_)
|
|
}
|
|
|
|
/// Unmaps a region of memory.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **mapping**:
|
|
/// The pages that needs to be unmapped.
|
|
#[inline]
|
|
pub unsafe fn mem_unmap(mapping_: &mut [u8]) -> errno {
|
|
cloudabi_sys_mem_unmap(mapping_.as_mut_ptr() as *mut (), mapping_.len())
|
|
}
|
|
|
|
/// Concurrently polls for the occurrence of a set of events.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **in**:
|
|
/// The events to which to subscribe.
|
|
///
|
|
/// **out**:
|
|
/// The events that have occurred.
|
|
///
|
|
/// **nsubscriptions**:
|
|
/// Both the number of subscriptions and events.
|
|
///
|
|
/// **nevents**:
|
|
/// The number of events stored.
|
|
#[inline]
|
|
pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: &mut usize) -> errno {
|
|
cloudabi_sys_poll(in_, out_, nsubscriptions_, nevents_)
|
|
}
|
|
|
|
/// Replaces the process by a new executable.
|
|
///
|
|
/// Process execution in CloudABI differs from POSIX in two ways:
|
|
/// handling of arguments and inheritance of file descriptors.
|
|
///
|
|
/// CloudABI does not use string command line arguments. Instead,
|
|
/// a buffer with binary data is copied into the address space of
|
|
/// the new executable. The kernel does not enforce any specific
|
|
/// structure to this data, although CloudABI's C library uses it
|
|
/// to store a tree structure that is semantically identical to
|
|
/// YAML.
|
|
///
|
|
/// Due to the strong focus on thread safety, file descriptors
|
|
/// aren't inherited through close-on-exec flags. An explicit
|
|
/// list of file descriptors that need to be retained needs to be
|
|
/// provided. After execution, file descriptors are placed in the
|
|
/// order in which they are stored in the array. This not only
|
|
/// makes the execution process deterministic. It also prevents
|
|
/// potential information disclosures about the layout of the
|
|
/// original process.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// A file descriptor of the new executable.
|
|
///
|
|
/// **data**:
|
|
/// Binary argument data that is passed on to the
|
|
/// new executable.
|
|
///
|
|
/// **fds**:
|
|
/// The layout of the file descriptor table after
|
|
/// execution.
|
|
#[inline]
|
|
pub unsafe fn proc_exec(fd_: fd, data_: &[u8], fds_: &[fd]) -> errno {
|
|
cloudabi_sys_proc_exec(fd_, data_.as_ptr() as *const (), data_.len(), fds_.as_ptr(), fds_.len())
|
|
}
|
|
|
|
/// Terminates the process normally.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **rval**:
|
|
/// The exit code returned by the process. The
|
|
/// exit code can be obtained by other processes
|
|
/// through [`event.union.proc_terminate.exitcode`](struct.event_proc_terminate.html#structfield.exitcode).
|
|
#[inline]
|
|
pub unsafe fn proc_exit(rval_: exitcode) -> ! {
|
|
cloudabi_sys_proc_exit(rval_)
|
|
}
|
|
|
|
/// Forks the process of the calling thread.
|
|
///
|
|
/// After forking, a new process shall be created, having only a
|
|
/// copy of the calling thread. The parent process will obtain a
|
|
/// process descriptor. When closed, the child process is
|
|
/// automatically signaled with [`KILL`](enum.signal.html#variant.KILL).
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **fd**:
|
|
/// In the parent process: the file descriptor
|
|
/// number of the process descriptor.
|
|
///
|
|
/// In the child process: [`PROCESS_CHILD`](constant.PROCESS_CHILD.html).
|
|
///
|
|
/// **tid**:
|
|
/// In the parent process: undefined.
|
|
///
|
|
/// In the child process: the thread ID of the
|
|
/// initial thread of the child process.
|
|
#[inline]
|
|
pub unsafe fn proc_fork(fd_: &mut fd, tid_: &mut tid) -> errno {
|
|
cloudabi_sys_proc_fork(fd_, tid_)
|
|
}
|
|
|
|
/// Sends a signal to the process of the calling thread.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **sig**:
|
|
/// The signal condition that should be triggered.
|
|
/// If the signal causes the process to terminate,
|
|
/// its condition can be obtained by other
|
|
/// processes through
|
|
/// [`event.union.proc_terminate.signal`](struct.event_proc_terminate.html#structfield.signal).
|
|
#[inline]
|
|
pub unsafe fn proc_raise(sig_: signal) -> errno {
|
|
cloudabi_sys_proc_raise(sig_)
|
|
}
|
|
|
|
/// Obtains random data from the kernel random number generator.
|
|
///
|
|
/// As this interface is not guaranteed to be fast, it is advised
|
|
/// that the random data obtained through this system call is used
|
|
/// as the seed for a userspace pseudo-random number generator.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **buf**:
|
|
/// The buffer that needs to be filled with random
|
|
/// data.
|
|
#[inline]
|
|
pub unsafe fn random_get(buf_: &mut [u8]) -> errno {
|
|
cloudabi_sys_random_get(buf_.as_mut_ptr() as *mut (), buf_.len())
|
|
}
|
|
|
|
/// Receives a message on a socket.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **sock**:
|
|
/// The socket on which a message should be
|
|
/// received.
|
|
///
|
|
/// **in**:
|
|
/// Input parameters.
|
|
///
|
|
/// **out**:
|
|
/// Output parameters.
|
|
#[inline]
|
|
pub unsafe fn sock_recv(sock_: fd, in_: *const recv_in, out_: *mut recv_out) -> errno {
|
|
cloudabi_sys_sock_recv(sock_, in_, out_)
|
|
}
|
|
|
|
/// Sends a message on a socket.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **sock**:
|
|
/// The socket on which a message should be sent.
|
|
///
|
|
/// **in**:
|
|
/// Input parameters.
|
|
///
|
|
/// **out**:
|
|
/// Output parameters.
|
|
#[inline]
|
|
pub unsafe fn sock_send(sock_: fd, in_: *const send_in, out_: *mut send_out) -> errno {
|
|
cloudabi_sys_sock_send(sock_, in_, out_)
|
|
}
|
|
|
|
/// Shuts down socket send and receive channels.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **sock**:
|
|
/// The socket that needs its channels shut down.
|
|
///
|
|
/// **how**:
|
|
/// Which channels on the socket need to be shut
|
|
/// down.
|
|
#[inline]
|
|
pub unsafe fn sock_shutdown(sock_: fd, how_: sdflags) -> errno {
|
|
cloudabi_sys_sock_shutdown(sock_, how_)
|
|
}
|
|
|
|
/// Creates a new thread within the current process.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **attr**:
|
|
/// The desired attributes of the new thread.
|
|
///
|
|
/// **tid**:
|
|
/// The thread ID of the new thread.
|
|
#[inline]
|
|
pub unsafe fn thread_create(attr_: *mut threadattr, tid_: &mut tid) -> errno {
|
|
cloudabi_sys_thread_create(attr_, tid_)
|
|
}
|
|
|
|
/// Terminates the calling thread.
|
|
///
|
|
/// This system call can also unlock a single userspace lock
|
|
/// after termination, which can be used to implement thread
|
|
/// joining.
|
|
///
|
|
/// ## Parameters
|
|
///
|
|
/// **lock**:
|
|
/// Userspace lock that is locked for writing by
|
|
/// the calling thread.
|
|
///
|
|
/// **scope**:
|
|
/// Whether the lock is stored in private or
|
|
/// shared memory.
|
|
#[inline]
|
|
pub unsafe fn thread_exit(lock_: *mut lock, scope_: scope) -> ! {
|
|
cloudabi_sys_thread_exit(lock_, scope_)
|
|
}
|
|
|
|
/// Temporarily yields execution of the calling thread.
|
|
#[inline]
|
|
pub unsafe fn thread_yield() -> errno {
|
|
cloudabi_sys_thread_yield()
|
|
}
|