1 // Copyright (c) 2016-2017 Nuxi <https://nuxi.nl/> and contributors.
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions
6 // 1. Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // 2. Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
12 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 // This file is automatically generated. Do not edit.
26 // Source: https://github.com/NuxiNL/cloudabi
28 // Appease Rust's tidy.
30 // ignore-tidy-linelength
32 //! **PLEASE NOTE: This entire crate including this
33 //! documentation is automatically generated from
34 //! [`cloudabi.txt`](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt)**
38 //! CloudABI is what you get if you take POSIX, add capability-based
39 //! security, and remove everything that's incompatible with that. The
40 //! result is a minimal ABI consisting of only 49 syscalls.
42 //! CloudABI doesn't have its own kernel, but instead is implemented in existing
43 //! kernels: FreeBSD has CloudABI support for x86-64 and arm64, and [a patch-set
44 //! for NetBSD](https://github.com/NuxiNL/netbsd) and [a patch-set for
45 //! Linux](https://github.com/NuxiNL/linux) are available as well. This means that
46 //! CloudABI binaries can be executed on different operating systems, without any
49 //! ## Capability-Based Security
51 //! Capability-based security means that processes can only perform
52 //! actions that have no global impact. Processes cannot open files by
53 //! their absolute path, cannot open network connections, and cannot
54 //! observe global system state such as the process table.
56 //! The capabilities of a process are fully determined by its set of open
57 //! file descriptors (fds). For example, files can only be opened if the
58 //! process already has a file descriptor to a directory the file is in.
60 //! Unlike in POSIX, where processes are normally started with file
61 //! descriptors 0, 1, and 2 reserved for standard input, output, and
62 //! error, CloudABI does not reserve any file descriptor numbers for
63 //! specific purposes.
65 //! In CloudABI, a process depends on its parent process to launch it with
66 //! the right set of resources, since the process will not be able to open
67 //! any new resources. For example, a simple static web server would need
68 //! to be started with a file descriptor to a [TCP
69 //! listener](https://github.com/NuxiNL/flower), and a file descriptor to
70 //! the directory for which to serve files. The web server will then be
71 //! unable to do anything other than reading files in that directory, and
72 //! process incoming network connections.
74 //! So, unknown CloudABI binaries can safely be executed without the need
75 //! for containers, virtual machines, or other sandboxing technologies.
77 //! Watch [Ed Schouten's Talk at
78 //! 32C3](https://www.youtube.com/watch?v=3N29vrPoDv8) for more
79 //! information about what capability-based security for UNIX means.
83 //! [Cloudlibc](https://github.com/NuxiNL/cloudlibc) is an implementation
84 //! of the C standard library, without all CloudABI-incompatible
85 //! functions. For example, Cloudlibc does not have `printf`, but does
86 //! have `fprintf`. It does not have `open`, but does have `openat`.
90 //! [CloudABI-Ports](https://github.com/NuxiNL/cloudabi-ports) is a
91 //! collection of ports of commonly used libraries and applications to
92 //! CloudABI. It contains software such as `zlib`, `libpng`, `boost`,
93 //! `memcached`, and much more. The software is patched to not depend on
94 //! any global state, such as files in `/etc` or `/dev`, using `open()`,
99 //! Instructions for using CloudABI (including kernel modules/patches,
100 //! toolchain, and ports) are available for several operating systems:
102 //! - [Arch Linux](https://nuxi.nl/cloudabi/archlinux/)
103 //! - [Debian, Ubuntu, and other Debian derivatives](https://nuxi.nl/cloudabi/debian/)
104 //! - [FreeBSD, PC-BSD and DragonFly BSD](https://nuxi.nl/cloudabi/freebsd/)
105 //! - [Mac OS X](https://nuxi.nl/cloudabi/mac/)
106 //! - [NetBSD](https://nuxi.nl/cloudabi/netbsd/)
108 //! ## Specification of the ABI
110 //! The entire ABI is specified in a file called
111 //! [`cloudabi.txt`](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt),
113 //! [headers](https://github.com/NuxiNL/cloudabi/tree/master/headers)
114 //! and documentation (including the one you're reading now) is generated.
117 #![allow(non_camel_case_types)]
119 include!("bitflags.rs");
121 /// File or memory access pattern advisory information.
123 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
126 /// The application expects that it will not access the
127 /// specified data in the near future.
129 /// The application expects to access the specified data
130 /// once and then not reuse it thereafter.
132 /// The application has no advice to give on its behavior
133 /// with respect to the specified data.
135 /// The application expects to access the specified data
136 /// in a random order.
138 /// The application expects to access the specified data
139 /// sequentially from lower offsets to higher offsets.
141 /// The application expects to access the specified data
142 /// in the near future.
146 /// Enumeration describing the kind of value stored in [`auxv`](struct.auxv.html).
148 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
151 /// Base address of the binary argument data provided to
152 /// [`proc_exec()`](fn.proc_exec.html).
154 /// Length of the binary argument data provided to
155 /// [`proc_exec()`](fn.proc_exec.html).
157 /// Base address at which the executable is placed in
160 /// Base address of a buffer of random data that may be
161 /// used for non-cryptographic purposes, for example as a
162 /// canary for stack smashing protection.
164 /// Length of a buffer of random data that may be used
165 /// for non-cryptographic purposes, for example as a
166 /// canary for stack smashing protection.
168 /// Number of CPUs that the system this process is running
171 /// Terminator of the auxiliary vector.
173 /// Smallest memory object size for which individual
174 /// memory protection controls can be configured.
176 /// Address of the first ELF program header of the
179 /// Number of ELF program headers of the executable.
181 /// Identifier of the process.
183 /// This environment does not provide any simple numerical
184 /// process identifiers, for the reason that these are not
185 /// useful in distributed contexts. Instead, processes are
186 /// identified by a UUID.
188 /// This record should point to sixteen bytes of binary
189 /// data, containing a version 4 UUID (fully random).
191 /// Address of the ELF header of the vDSO.
193 /// The vDSO is a shared library that is mapped in the
194 /// address space of the process. It provides entry points
195 /// for every system call supported by the environment,
196 /// all having a corresponding symbol that is prefixed
197 /// with `cloudabi_sys_`. System calls should be invoked
198 /// through these entry points.
200 /// The first advantage of letting processes call into a
201 /// vDSO to perform system calls instead of raising
202 /// hardware traps is that it allows for easy emulation of
203 /// executables on top of existing operating systems. The
204 /// second advantage is that in cases where an operating
205 /// system provides native support for CloudABI executables,
206 /// it may still implement partial userspace
207 /// implementations of these system calls to improve
208 /// performance (e.g., [`clock_time_get()`](fn.clock_time_get.html)). It also provides
209 /// a more dynamic way of adding, removing or replacing
212 /// Thread ID of the initial thread of the process.
216 /// Identifiers for clocks.
218 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
221 /// The system-wide monotonic clock, which is defined as a
222 /// clock measuring real time, whose value cannot be
223 /// adjusted and which cannot have negative clock jumps.
225 /// The epoch of this clock is undefined. The absolute
226 /// time value of this clock therefore has no meaning.
228 /// The CPU-time clock associated with the current
230 PROCESS_CPUTIME_ID = 2,
231 /// The system-wide clock measuring real time. Time value
232 /// zero corresponds with 1970-01-01T00:00:00Z.
234 /// The CPU-time clock associated with the current thread.
235 THREAD_CPUTIME_ID = 4,
238 /// A userspace condition variable.
240 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
241 pub struct condvar(pub u32);
242 /// The condition variable is in its initial state. There
243 /// are no threads waiting to be woken up. If the
244 /// condition variable has any other value, the kernel
245 /// must be called to wake up any sleeping threads.
246 pub const CONDVAR_HAS_NO_WAITERS: condvar = condvar(0);
248 /// Identifier for a device containing a file system. Can be used
249 /// in combination with [`inode`](struct.inode.html) to uniquely identify a file on the
252 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
253 pub struct device(pub u64);
255 /// A reference to the offset of a directory entry.
257 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
258 pub struct dircookie(pub u64);
259 /// Permanent reference to the first directory entry
260 /// within a directory.
261 pub const DIRCOOKIE_START: dircookie = dircookie(0);
263 /// Error codes returned by system calls.
265 /// Not all of these error codes are returned by the system calls
266 /// provided by this environment, but are either used in userspace
267 /// exclusively or merely provided for alignment with POSIX.
269 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
272 /// No error occurred. System call completed successfully.
274 /// Argument list too long.
276 /// Permission denied.
280 /// Address not available.
282 /// Address family not supported.
284 /// Resource unavailable, or operation would block.
286 /// Connection already in progress.
288 /// Bad file descriptor.
292 /// Device or resource busy.
294 /// Operation canceled.
296 /// No child processes.
298 /// Connection aborted.
300 /// Connection refused.
302 /// Connection reset.
304 /// Resource deadlock would occur.
306 /// Destination address required.
308 /// Mathematics argument out of domain of function.
318 /// Host is unreachable.
320 /// Identifier removed.
322 /// Illegal byte sequence.
324 /// Operation in progress.
326 /// Interrupted function.
328 /// Invalid argument.
332 /// Socket is connected.
336 /// Too many levels of symbolic links.
338 /// File descriptor value too large.
342 /// Message too large.
346 /// Filename too long.
350 /// Connection aborted by network.
352 /// Network unreachable.
354 /// Too many files open in system.
356 /// No buffer space available.
360 /// No such file or directory.
362 /// Executable file format error.
364 /// No locks available.
368 /// Not enough space.
370 /// No message of the desired type.
372 /// Protocol not available.
374 /// No space left on device.
376 /// Function not supported.
378 /// The socket is not connected.
380 /// Not a directory or a symbolic link to a directory.
382 /// Directory not empty.
384 /// State not recoverable.
388 /// Not supported, or operation not supported on socket.
390 /// Inappropriate I/O control operation.
392 /// No such device or address.
394 /// Value too large to be stored in data type.
396 /// Previous owner died.
398 /// Operation not permitted.
404 /// Protocol not supported.
406 /// Protocol wrong type for socket.
408 /// Result too large.
410 /// Read-only file system.
418 /// Connection timed out.
422 /// Cross-device link.
424 /// Extension: Capabilities insufficient.
429 /// The state of the file descriptor subscribed to with
430 /// [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
432 pub struct eventrwflags: u16 {
433 /// The peer of this socket has closed or disconnected.
434 const HANGUP = 0x0001;
438 /// Type of a subscription to an event or its occurrence.
440 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
443 /// The time value of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id)
444 /// has reached timestamp [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout).
446 /// Condition variable [`subscription.union.condvar.condvar`](struct.subscription_condvar.html#structfield.condvar) has
447 /// been woken up and [`subscription.union.condvar.lock`](struct.subscription_condvar.html#structfield.lock) has been
448 /// acquired for writing.
450 /// File descriptor [`subscription.union.fd_readwrite.fd`](struct.subscription_fd_readwrite.html#structfield.fd) has
451 /// data available for reading. This event always triggers
452 /// for regular files.
454 /// File descriptor [`subscription.union.fd_readwrite.fd`](struct.subscription_fd_readwrite.html#structfield.fd) has
455 /// capacity available for writing. This event always
456 /// triggers for regular files.
458 /// Lock [`subscription.union.lock.lock`](struct.subscription_lock.html#structfield.lock) has been acquired for
461 /// Lock [`subscription.union.lock.lock`](struct.subscription_lock.html#structfield.lock) has been acquired for
464 /// The process associated with process descriptor
465 /// [`subscription.union.proc_terminate.fd`](struct.subscription_proc_terminate.html#structfield.fd) has terminated.
469 /// Exit code generated by a process when exiting.
470 pub type exitcode = u32;
472 /// A file descriptor number.
474 /// Unlike on POSIX-compliant systems, none of the file descriptor
475 /// numbers are reserved for a purpose (e.g., stdin, stdout,
476 /// stderr). Operating systems are not required to allocate new
477 /// file descriptors in ascending order.
479 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
480 pub struct fd(pub u32);
481 /// Returned to the child process by [`proc_fork()`](fn.proc_fork.html).
482 pub const PROCESS_CHILD: fd = fd(0xffffffff);
483 /// Passed to [`mem_map()`](fn.mem_map.html) when creating a mapping to
484 /// anonymous memory.
485 pub const MAP_ANON_FD : fd = fd(0xffffffff);
488 /// File descriptor flags.
490 pub struct fdflags: u16 {
491 /// Append mode: Data written to the file is always
492 /// appended to the file's end.
493 const APPEND = 0x0001;
494 /// Write according to synchronized I/O data integrity
495 /// completion. Only the data stored in the file is
497 const DSYNC = 0x0002;
498 /// Non-blocking mode.
499 const NONBLOCK = 0x0004;
500 /// Synchronized read I/O operations.
501 const RSYNC = 0x0008;
502 /// Write according to synchronized I/O file integrity
503 /// completion. In addition to synchronizing the data
504 /// stored in the file, the system may also synchronously
505 /// update the file's metadata.
511 /// Which file descriptor attributes to adjust.
513 pub struct fdsflags: u16 {
514 /// Adjust the file descriptor flags stored in
515 /// [`fdstat.fs_flags`](struct.fdstat.html#structfield.fs_flags).
516 const FLAGS = 0x0001;
517 /// Restrict the rights of the file descriptor to the
518 /// rights stored in [`fdstat.fs_rights_base`](struct.fdstat.html#structfield.fs_rights_base) and
519 /// [`fdstat.fs_rights_inheriting`](struct.fdstat.html#structfield.fs_rights_inheriting).
520 const RIGHTS = 0x0002;
524 /// Relative offset within a file.
525 pub type filedelta = i64;
527 /// Non-negative file size or length of a region within a file.
528 pub type filesize = u64;
530 /// The type of a file descriptor or file.
532 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
535 /// The type of the file descriptor or file is unknown or
536 /// is different from any of the other types specified.
538 /// The file descriptor or file refers to a block device
541 /// The file descriptor or file refers to a character
543 CHARACTER_DEVICE = 17,
544 /// The file descriptor or file refers to a directory
547 /// The file descriptor refers to a process handle.
549 /// The file descriptor or file refers to a regular file
552 /// The file descriptor refers to a shared memory object.
554 /// The file descriptor or file refers to a datagram
557 /// The file descriptor or file refers to a byte-stream
560 /// The file refers to a symbolic link inode.
565 /// Which file attributes to adjust.
567 pub struct fsflags: u16 {
568 /// Adjust the last data access timestamp to the value
569 /// stored in [`filestat.st_atim`](struct.filestat.html#structfield.st_atim).
571 /// Adjust the last data access timestamp to the time
572 /// of clock [`REALTIME`](enum.clockid.html#variant.REALTIME).
573 const ATIM_NOW = 0x0002;
574 /// Adjust the last data modification timestamp to the
575 /// value stored in [`filestat.st_mtim`](struct.filestat.html#structfield.st_mtim).
577 /// Adjust the last data modification timestamp to the
578 /// time of clock [`REALTIME`](enum.clockid.html#variant.REALTIME).
579 const MTIM_NOW = 0x0008;
580 /// Truncate or extend the file to the size stored in
581 /// [`filestat.st_size`](struct.filestat.html#structfield.st_size).
586 /// File serial number that is unique within its file system.
588 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
589 pub struct inode(pub u64);
591 /// Number of hard links to an inode.
592 pub type linkcount = u32;
594 /// A userspace read-recursive readers-writer lock, similar to a
595 /// Linux futex or a FreeBSD umtx.
597 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
598 pub struct lock(pub u32);
599 /// Value indicating that the lock is in its initial
601 pub const LOCK_UNLOCKED : lock = lock(0x00000000);
602 /// Bitmask indicating that the lock is write-locked. If
603 /// set, the lower 30 bits of the lock contain the
604 /// identifier of the thread that owns the write lock.
605 /// Otherwise, the lower 30 bits of the lock contain the
606 /// number of acquired read locks.
607 pub const LOCK_WRLOCKED : lock = lock(0x40000000);
608 /// Bitmask indicating that the lock is either read locked
609 /// or write locked, and that one or more threads have
610 /// their execution suspended, waiting to acquire the
611 /// lock. The last owner of the lock must call the
612 /// kernel to unlock.
614 /// When the lock is acquired for reading and this bit is
615 /// set, it means that one or more threads are attempting
616 /// to acquire this lock for writing. In that case, other
617 /// threads should only acquire additional read locks if
618 /// suspending execution would cause a deadlock. It is
619 /// preferred to suspend execution, as this prevents
620 /// starvation of writers.
621 pub const LOCK_KERNEL_MANAGED: lock = lock(0x80000000);
622 /// Value indicating that the lock is in an incorrect
623 /// state. A lock cannot be in its initial unlocked state,
624 /// while also managed by the kernel.
625 pub const LOCK_BOGUS : lock = lock(0x80000000);
628 /// Flags determining the method of how paths are resolved.
630 pub struct lookupflags: u32 {
631 /// As long as the resolved path corresponds to a symbolic
632 /// link, it is expanded.
633 const SYMLINK_FOLLOW = 0x00000001;
638 /// Memory mapping flags.
640 pub struct mflags: u8 {
641 /// Instead of mapping the contents of the file provided,
642 /// create a mapping to anonymous memory. The file
643 /// descriptor argument must be set to [`MAP_ANON_FD`](constant.MAP_ANON_FD.html),
644 /// and the offset must be set to zero.
646 /// Require that the mapping is performed at the base
647 /// address provided.
649 /// Changes are private.
650 const PRIVATE = 0x04;
651 /// Changes are shared.
657 /// Memory page protection options.
659 /// This implementation enforces the `W^X` property: Pages cannot be
660 /// mapped for execution while also mapped for writing.
662 pub struct mprot: u8 {
663 /// Page can be executed.
665 /// Page can be written.
667 /// Page can be read.
673 /// Methods of synchronizing memory with physical storage.
675 pub struct msflags: u8 {
676 /// Perform asynchronous writes.
678 /// Invalidate cached data.
679 const INVALIDATE = 0x02;
680 /// Perform synchronous writes.
685 /// Specifies the number of threads sleeping on a condition
686 /// variable that should be woken up.
687 pub type nthreads = u32;
690 /// Open flags used by [`file_open()`](fn.file_open.html).
692 pub struct oflags: u16 {
693 /// Create file if it does not exist.
694 const CREAT = 0x0001;
695 /// Fail if not a directory.
696 const DIRECTORY = 0x0002;
697 /// Fail if file already exists.
699 /// Truncate file to size 0.
700 const TRUNC = 0x0008;
705 /// Flags provided to [`sock_recv()`](fn.sock_recv.html).
707 pub struct riflags: u16 {
708 /// Returns the message without removing it from the
709 /// socket's receive queue.
711 /// On byte-stream sockets, block until the full amount
712 /// of data can be returned.
713 const WAITALL = 0x0010;
718 /// File descriptor rights, determining which actions may be
721 pub struct rights: u64 {
722 /// The right to invoke [`fd_datasync()`](fn.fd_datasync.html).
724 /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
725 /// invoke [`file_open()`](fn.file_open.html) with [`DSYNC`](struct.fdflags.html#associatedconstant.DSYNC).
726 const FD_DATASYNC = 0x0000000000000001;
727 /// The right to invoke [`fd_read()`](fn.fd_read.html) and [`sock_recv()`](fn.sock_recv.html).
729 /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, includes the right to
730 /// invoke [`mem_map()`](fn.mem_map.html) with memory protection option
731 /// [`READ`](struct.mprot.html#associatedconstant.READ).
733 /// If [`FD_SEEK`](struct.rights.html#associatedconstant.FD_SEEK) is set, includes the right to invoke
734 /// [`fd_pread()`](fn.fd_pread.html).
735 const FD_READ = 0x0000000000000002;
736 /// The right to invoke [`fd_seek()`](fn.fd_seek.html). This flag implies
737 /// [`FD_TELL`](struct.rights.html#associatedconstant.FD_TELL).
738 const FD_SEEK = 0x0000000000000004;
739 /// The right to invoke [`fd_stat_put()`](fn.fd_stat_put.html) with
740 /// [`FLAGS`](struct.fdsflags.html#associatedconstant.FLAGS).
741 const FD_STAT_PUT_FLAGS = 0x0000000000000008;
742 /// The right to invoke [`fd_sync()`](fn.fd_sync.html).
744 /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
745 /// invoke [`file_open()`](fn.file_open.html) with [`RSYNC`](struct.fdflags.html#associatedconstant.RSYNC) and
746 /// [`DSYNC`](struct.fdflags.html#associatedconstant.DSYNC).
747 const FD_SYNC = 0x0000000000000010;
748 /// The right to invoke [`fd_seek()`](fn.fd_seek.html) in such a way that the
749 /// file offset remains unaltered (i.e., [`CUR`](enum.whence.html#variant.CUR) with
751 const FD_TELL = 0x0000000000000020;
752 /// The right to invoke [`fd_write()`](fn.fd_write.html) and [`sock_send()`](fn.sock_send.html).
754 /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, includes the right to
755 /// invoke [`mem_map()`](fn.mem_map.html) with memory protection option
756 /// [`WRITE`](struct.mprot.html#associatedconstant.WRITE).
758 /// If [`FD_SEEK`](struct.rights.html#associatedconstant.FD_SEEK) is set, includes the right to
759 /// invoke [`fd_pwrite()`](fn.fd_pwrite.html).
760 const FD_WRITE = 0x0000000000000040;
761 /// The right to invoke [`file_advise()`](fn.file_advise.html).
762 const FILE_ADVISE = 0x0000000000000080;
763 /// The right to invoke [`file_allocate()`](fn.file_allocate.html).
764 const FILE_ALLOCATE = 0x0000000000000100;
765 /// The right to invoke [`file_create()`](fn.file_create.html) with
766 /// [`DIRECTORY`](enum.filetype.html#variant.DIRECTORY).
767 const FILE_CREATE_DIRECTORY = 0x0000000000000200;
768 /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, the right to invoke
769 /// [`file_open()`](fn.file_open.html) with [`CREAT`](struct.oflags.html#associatedconstant.CREAT).
770 const FILE_CREATE_FILE = 0x0000000000000400;
771 /// The right to invoke [`file_link()`](fn.file_link.html) with the file
772 /// descriptor as the source directory.
773 const FILE_LINK_SOURCE = 0x0000000000001000;
774 /// The right to invoke [`file_link()`](fn.file_link.html) with the file
775 /// descriptor as the target directory.
776 const FILE_LINK_TARGET = 0x0000000000002000;
777 /// The right to invoke [`file_open()`](fn.file_open.html).
778 const FILE_OPEN = 0x0000000000004000;
779 /// The right to invoke [`file_readdir()`](fn.file_readdir.html).
780 const FILE_READDIR = 0x0000000000008000;
781 /// The right to invoke [`file_readlink()`](fn.file_readlink.html).
782 const FILE_READLINK = 0x0000000000010000;
783 /// The right to invoke [`file_rename()`](fn.file_rename.html) with the file
784 /// descriptor as the source directory.
785 const FILE_RENAME_SOURCE = 0x0000000000020000;
786 /// The right to invoke [`file_rename()`](fn.file_rename.html) with the file
787 /// descriptor as the target directory.
788 const FILE_RENAME_TARGET = 0x0000000000040000;
789 /// The right to invoke [`file_stat_fget()`](fn.file_stat_fget.html).
790 const FILE_STAT_FGET = 0x0000000000080000;
791 /// The right to invoke [`file_stat_fput()`](fn.file_stat_fput.html) with
792 /// [`SIZE`](struct.fsflags.html#associatedconstant.SIZE).
794 /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
795 /// invoke [`file_open()`](fn.file_open.html) with [`TRUNC`](struct.oflags.html#associatedconstant.TRUNC).
796 const FILE_STAT_FPUT_SIZE = 0x0000000000100000;
797 /// The right to invoke [`file_stat_fput()`](fn.file_stat_fput.html) with
798 /// [`ATIM`](struct.fsflags.html#associatedconstant.ATIM), [`ATIM_NOW`](struct.fsflags.html#associatedconstant.ATIM_NOW), [`MTIM`](struct.fsflags.html#associatedconstant.MTIM),
799 /// and [`MTIM_NOW`](struct.fsflags.html#associatedconstant.MTIM_NOW).
800 const FILE_STAT_FPUT_TIMES = 0x0000000000200000;
801 /// The right to invoke [`file_stat_get()`](fn.file_stat_get.html).
802 const FILE_STAT_GET = 0x0000000000400000;
803 /// The right to invoke [`file_stat_put()`](fn.file_stat_put.html) with
804 /// [`ATIM`](struct.fsflags.html#associatedconstant.ATIM), [`ATIM_NOW`](struct.fsflags.html#associatedconstant.ATIM_NOW), [`MTIM`](struct.fsflags.html#associatedconstant.MTIM),
805 /// and [`MTIM_NOW`](struct.fsflags.html#associatedconstant.MTIM_NOW).
806 const FILE_STAT_PUT_TIMES = 0x0000000000800000;
807 /// The right to invoke [`file_symlink()`](fn.file_symlink.html).
808 const FILE_SYMLINK = 0x0000000001000000;
809 /// The right to invoke [`file_unlink()`](fn.file_unlink.html).
810 const FILE_UNLINK = 0x0000000002000000;
811 /// The right to invoke [`mem_map()`](fn.mem_map.html) with [`mprot`](struct.mprot.html) set to
813 const MEM_MAP = 0x0000000004000000;
814 /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, the right to invoke
815 /// [`mem_map()`](fn.mem_map.html) with [`EXEC`](struct.mprot.html#associatedconstant.EXEC).
816 const MEM_MAP_EXEC = 0x0000000008000000;
817 /// If [`FD_READ`](struct.rights.html#associatedconstant.FD_READ) is set, includes the right to
818 /// invoke [`poll()`](fn.poll.html) to subscribe to [`FD_READ`](enum.eventtype.html#variant.FD_READ).
820 /// If [`FD_WRITE`](struct.rights.html#associatedconstant.FD_WRITE) is set, includes the right to
821 /// invoke [`poll()`](fn.poll.html) to subscribe to [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
822 const POLL_FD_READWRITE = 0x0000000010000000;
823 /// The right to invoke [`poll()`](fn.poll.html) to subscribe to
824 /// [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
825 const POLL_PROC_TERMINATE = 0x0000000040000000;
826 /// The right to invoke [`proc_exec()`](fn.proc_exec.html).
827 const PROC_EXEC = 0x0000000100000000;
828 /// The right to invoke [`sock_shutdown()`](fn.sock_shutdown.html).
829 const SOCK_SHUTDOWN = 0x0000008000000000;
834 /// Flags returned by [`sock_recv()`](fn.sock_recv.html).
836 pub struct roflags: u16 {
837 /// Returned by [`sock_recv()`](fn.sock_recv.html): List of file descriptors
838 /// has been truncated.
839 const FDS_TRUNCATED = 0x0001;
840 /// Returned by [`sock_recv()`](fn.sock_recv.html): Message data has been
842 const DATA_TRUNCATED = 0x0008;
846 /// Indicates whether an object is stored in private or shared
849 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
852 /// The object is stored in private memory.
854 /// The object is stored in shared memory.
859 /// Which channels on a socket need to be shut down.
861 pub struct sdflags: u8 {
862 /// Disables further receive operations.
864 /// Disables further send operations.
870 /// Flags provided to [`sock_send()`](fn.sock_send.html). As there are currently no flags
871 /// defined, it must be set to zero.
873 pub struct siflags: u16 {
878 /// Signal condition.
880 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
883 /// Process abort signal.
885 /// Action: Terminates the process.
889 /// Action: Terminates the process.
891 /// Access to an undefined portion of a memory object.
893 /// Action: Terminates the process.
895 /// Child process terminated, stopped, or continued.
899 /// Continue executing, if stopped.
901 /// Action: Continues executing, if stopped.
903 /// Erroneous arithmetic operation.
905 /// Action: Terminates the process.
909 /// Action: Terminates the process.
911 /// Illegal instruction.
913 /// Action: Terminates the process.
915 /// Terminate interrupt signal.
917 /// Action: Terminates the process.
921 /// Action: Terminates the process.
923 /// Write on a pipe with no one to read it.
927 /// Terminal quit signal.
929 /// Action: Terminates the process.
931 /// Invalid memory reference.
933 /// Action: Terminates the process.
937 /// Action: Stops executing.
941 /// Action: Terminates the process.
943 /// Termination signal.
945 /// Action: Terminates the process.
947 /// Trace/breakpoint trap.
949 /// Action: Terminates the process.
951 /// Terminal stop signal.
953 /// Action: Stops executing.
955 /// Background process attempting read.
957 /// Action: Stops executing.
959 /// Background process attempting write.
961 /// Action: Stops executing.
963 /// High bandwidth data is available at a socket.
967 /// User-defined signal 1.
969 /// Action: Terminates the process.
971 /// User-defined signal 2.
973 /// Action: Terminates the process.
975 /// Virtual timer expired.
977 /// Action: Terminates the process.
979 /// CPU time limit exceeded.
981 /// Action: Terminates the process.
983 /// File size limit exceeded.
985 /// Action: Terminates the process.
990 /// Flags determining how the timestamp provided in
991 /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) should be interpreted.
993 pub struct subclockflags: u16 {
994 /// If set, treat the timestamp provided in
995 /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) as an absolute timestamp
996 /// of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id).
998 /// If clear, treat the timestamp provided in
999 /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) relative to the current
1000 /// time value of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id).
1001 const ABSTIME = 0x0001;
1006 /// Flags influencing the method of polling for read or writing on
1007 /// a file descriptor.
1009 pub struct subrwflags: u16 {
1010 /// Deprecated. Must be set by callers and ignored by
1011 /// implementations.
1012 const POLL = 0x0001;
1016 /// Unique system-local identifier of a thread. This identifier is
1017 /// only valid during the lifetime of the thread.
1019 /// Threads must be aware of their thread identifier, as it is
1020 /// written it into locks when acquiring them for writing. It is
1021 /// not advised to use these identifiers for any other purpose.
1023 /// As the thread identifier is also stored in [`lock`](struct.lock.html) when
1024 /// [`LOCK_WRLOCKED`](constant.LOCK_WRLOCKED.html) is set, the top two bits of the thread
1025 /// must always be set to zero.
1027 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1028 pub struct tid(pub u32);
1030 /// Timestamp in nanoseconds.
1031 pub type timestamp = u64;
1034 /// Specifies whether files are unlinked or directories are
1037 pub struct ulflags: u8 {
1038 /// If set, removes a directory. Otherwise, unlinks any
1039 /// non-directory file.
1040 const REMOVEDIR = 0x01;
1044 /// User-provided value that can be attached to objects that is
1045 /// retained when extracted from the kernel.
1046 pub type userdata = u64;
1048 /// Relative to which position the offset of the file descriptor
1051 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1054 /// Seek relative to current position.
1056 /// Seek relative to end-of-file.
1058 /// Seek relative to start-of-file.
1062 /// Auxiliary vector entry.
1064 /// The auxiliary vector is a list of key-value pairs that is
1065 /// provided to the process on startup. Unlike structures, it is
1066 /// extensible, as it is possible to add new records later on.
1067 /// The auxiliary vector is always terminated by an entry having
1068 /// type [`NULL`](enum.auxtype.html#variant.NULL).
1070 /// The auxiliary vector is part of the x86-64 ABI, but is used by
1071 /// this environment on all architectures.
1073 #[derive(Copy, Clone)]
1075 /// The type of the auxiliary vector entry.
1076 pub a_type: auxtype,
1077 pub union: auxv_union
1079 /// A union inside `auxv`.
1081 #[derive(Copy, Clone)]
1082 pub union auxv_union {
1083 /// 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).
1084 /// A numerical value.
1086 /// 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).
1087 /// A pointer value.
1091 #[cfg(target_pointer_width = "32")]
1092 fn auxv_layout_test_32() {
1093 assert_eq!(::core::mem::size_of::<auxv>(), 8);
1094 assert_eq!(::core::mem::align_of::<auxv>(), 4);
1096 let obj: auxv = ::core::mem::uninitialized();
1097 let base = &obj as *const _ as usize;
1098 assert_eq!(&obj.a_type as *const _ as usize - base, 0);
1099 assert_eq!(&obj.union.a_val as *const _ as usize - base, 4);
1100 assert_eq!(&obj.union.a_ptr as *const _ as usize - base, 4);
1104 #[cfg(target_pointer_width = "64")]
1105 fn auxv_layout_test_64() {
1106 assert_eq!(::core::mem::size_of::<auxv>(), 16);
1107 assert_eq!(::core::mem::align_of::<auxv>(), 8);
1109 let obj: auxv = ::core::mem::uninitialized();
1110 let base = &obj as *const _ as usize;
1111 assert_eq!(&obj.a_type as *const _ as usize - base, 0);
1112 assert_eq!(&obj.union.a_val as *const _ as usize - base, 8);
1113 assert_eq!(&obj.union.a_ptr as *const _ as usize - base, 8);
1117 /// A region of memory for scatter/gather writes.
1119 #[derive(Copy, Clone)]
1121 /// The address and length of the buffer to be written.
1122 pub buf: (*const (), usize),
1125 #[cfg(target_pointer_width = "32")]
1126 fn ciovec_layout_test_32() {
1127 assert_eq!(::core::mem::size_of::<ciovec>(), 8);
1128 assert_eq!(::core::mem::align_of::<ciovec>(), 4);
1130 let obj: ciovec = ::core::mem::uninitialized();
1131 let base = &obj as *const _ as usize;
1132 assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
1133 assert_eq!(&obj.buf.1 as *const _ as usize - base, 4);
1137 #[cfg(target_pointer_width = "64")]
1138 fn ciovec_layout_test_64() {
1139 assert_eq!(::core::mem::size_of::<ciovec>(), 16);
1140 assert_eq!(::core::mem::align_of::<ciovec>(), 8);
1142 let obj: ciovec = ::core::mem::uninitialized();
1143 let base = &obj as *const _ as usize;
1144 assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
1145 assert_eq!(&obj.buf.1 as *const _ as usize - base, 8);
1149 /// A directory entry.
1151 #[derive(Copy, Clone)]
1153 /// The offset of the next directory entry stored in this
1155 pub d_next: dircookie,
1156 /// The serial number of the file referred to by this
1157 /// directory entry.
1159 /// The length of the name of the directory entry.
1161 /// The type of the file referred to by this directory
1163 pub d_type: filetype,
1166 fn dirent_layout_test() {
1167 assert_eq!(::core::mem::size_of::<dirent>(), 24);
1168 assert_eq!(::core::mem::align_of::<dirent>(), 8);
1170 let obj: dirent = ::core::mem::uninitialized();
1171 let base = &obj as *const _ as usize;
1172 assert_eq!(&obj.d_next as *const _ as usize - base, 0);
1173 assert_eq!(&obj.d_ino as *const _ as usize - base, 8);
1174 assert_eq!(&obj.d_namlen as *const _ as usize - base, 16);
1175 assert_eq!(&obj.d_type as *const _ as usize - base, 20);
1179 /// An event that occurred.
1181 #[derive(Copy, Clone)]
1183 /// User-provided value that got attached to
1184 /// [`subscription.userdata`](struct.subscription.html#structfield.userdata).
1185 pub userdata: userdata,
1186 /// If non-zero, an error that occurred while processing
1187 /// the subscription request.
1189 /// The type of the event that occurred.
1190 pub type_: eventtype,
1191 pub union: event_union
1193 /// A union inside `event`.
1195 #[derive(Copy, Clone)]
1196 pub union event_union {
1197 /// Used when `type_` is [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
1198 pub fd_readwrite: event_fd_readwrite,
1199 /// Used when `type_` is [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
1200 pub proc_terminate: event_proc_terminate,
1203 #[derive(Copy, Clone)]
1204 pub struct event_fd_readwrite {
1205 /// The number of bytes available
1206 /// for reading or writing.
1207 pub nbytes: filesize,
1209 pub unused: [u8; 4],
1210 /// The state of the file
1212 pub flags: eventrwflags,
1215 #[derive(Copy, Clone)]
1216 pub struct event_proc_terminate {
1218 pub unused: [u8; 4],
1219 /// If zero, the process has
1221 /// Otherwise, the signal
1222 /// condition causing it to
1225 /// If exited, the exit code of
1227 pub exitcode: exitcode,
1230 fn event_layout_test() {
1231 assert_eq!(::core::mem::size_of::<event>(), 32);
1232 assert_eq!(::core::mem::align_of::<event>(), 8);
1234 let obj: event = ::core::mem::uninitialized();
1235 let base = &obj as *const _ as usize;
1236 assert_eq!(&obj.userdata as *const _ as usize - base, 0);
1237 assert_eq!(&obj.error as *const _ as usize - base, 8);
1238 assert_eq!(&obj.type_ as *const _ as usize - base, 10);
1239 assert_eq!(&obj.union.fd_readwrite.nbytes as *const _ as usize - base, 16);
1240 assert_eq!(&obj.union.fd_readwrite.unused as *const _ as usize - base, 24);
1241 assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 28);
1242 assert_eq!(&obj.union.proc_terminate.unused as *const _ as usize - base, 16);
1243 assert_eq!(&obj.union.proc_terminate.signal as *const _ as usize - base, 20);
1244 assert_eq!(&obj.union.proc_terminate.exitcode as *const _ as usize - base, 24);
1248 /// File descriptor attributes.
1250 #[derive(Copy, Clone)]
1253 pub fs_filetype: filetype,
1254 /// File descriptor flags.
1255 pub fs_flags: fdflags,
1256 /// Rights that apply to this file descriptor.
1257 pub fs_rights_base: rights,
1258 /// Maximum set of rights that can be installed on new
1259 /// file descriptors that are created through this file
1260 /// descriptor, e.g., through [`file_open()`](fn.file_open.html).
1261 pub fs_rights_inheriting: rights,
1264 fn fdstat_layout_test() {
1265 assert_eq!(::core::mem::size_of::<fdstat>(), 24);
1266 assert_eq!(::core::mem::align_of::<fdstat>(), 8);
1268 let obj: fdstat = ::core::mem::uninitialized();
1269 let base = &obj as *const _ as usize;
1270 assert_eq!(&obj.fs_filetype as *const _ as usize - base, 0);
1271 assert_eq!(&obj.fs_flags as *const _ as usize - base, 2);
1272 assert_eq!(&obj.fs_rights_base as *const _ as usize - base, 8);
1273 assert_eq!(&obj.fs_rights_inheriting as *const _ as usize - base, 16);
1277 /// File attributes.
1279 #[derive(Copy, Clone)]
1280 pub struct filestat {
1281 /// Device ID of device containing the file.
1283 /// File serial number.
1286 pub st_filetype: filetype,
1287 /// Number of hard links to the file.
1288 pub st_nlink: linkcount,
1289 /// For regular files, the file size in bytes. For
1290 /// symbolic links, the length in bytes of the pathname
1291 /// contained in the symbolic link.
1292 pub st_size: filesize,
1293 /// Last data access timestamp.
1294 pub st_atim: timestamp,
1295 /// Last data modification timestamp.
1296 pub st_mtim: timestamp,
1297 /// Last file status change timestamp.
1298 pub st_ctim: timestamp,
1301 fn filestat_layout_test() {
1302 assert_eq!(::core::mem::size_of::<filestat>(), 56);
1303 assert_eq!(::core::mem::align_of::<filestat>(), 8);
1305 let obj: filestat = ::core::mem::uninitialized();
1306 let base = &obj as *const _ as usize;
1307 assert_eq!(&obj.st_dev as *const _ as usize - base, 0);
1308 assert_eq!(&obj.st_ino as *const _ as usize - base, 8);
1309 assert_eq!(&obj.st_filetype as *const _ as usize - base, 16);
1310 assert_eq!(&obj.st_nlink as *const _ as usize - base, 20);
1311 assert_eq!(&obj.st_size as *const _ as usize - base, 24);
1312 assert_eq!(&obj.st_atim as *const _ as usize - base, 32);
1313 assert_eq!(&obj.st_mtim as *const _ as usize - base, 40);
1314 assert_eq!(&obj.st_ctim as *const _ as usize - base, 48);
1318 /// A region of memory for scatter/gather reads.
1320 #[derive(Copy, Clone)]
1322 /// The address and length of the buffer to be filled.
1323 pub buf: (*mut (), usize),
1326 #[cfg(target_pointer_width = "32")]
1327 fn iovec_layout_test_32() {
1328 assert_eq!(::core::mem::size_of::<iovec>(), 8);
1329 assert_eq!(::core::mem::align_of::<iovec>(), 4);
1331 let obj: iovec = ::core::mem::uninitialized();
1332 let base = &obj as *const _ as usize;
1333 assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
1334 assert_eq!(&obj.buf.1 as *const _ as usize - base, 4);
1338 #[cfg(target_pointer_width = "64")]
1339 fn iovec_layout_test_64() {
1340 assert_eq!(::core::mem::size_of::<iovec>(), 16);
1341 assert_eq!(::core::mem::align_of::<iovec>(), 8);
1343 let obj: iovec = ::core::mem::uninitialized();
1344 let base = &obj as *const _ as usize;
1345 assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
1346 assert_eq!(&obj.buf.1 as *const _ as usize - base, 8);
1350 /// Path lookup properties.
1352 #[derive(Copy, Clone)]
1354 /// The working directory at which the resolution of the
1357 /// Flags determining the method of how the path is
1359 pub flags: lookupflags,
1362 fn lookup_layout_test() {
1363 assert_eq!(::core::mem::size_of::<lookup>(), 8);
1364 assert_eq!(::core::mem::align_of::<lookup>(), 4);
1366 let obj: lookup = ::core::mem::uninitialized();
1367 let base = &obj as *const _ as usize;
1368 assert_eq!(&obj.fd as *const _ as usize - base, 0);
1369 assert_eq!(&obj.flags as *const _ as usize - base, 4);
1373 /// Entry point for a process (`_start`).
1376 /// The auxiliary vector. See [`auxv`](struct.auxv.html).
1377 pub type processentry = unsafe extern "C" fn(
1381 /// Arguments of [`sock_recv()`](fn.sock_recv.html).
1383 #[derive(Copy, Clone)]
1384 pub struct recv_in {
1385 /// List of scatter/gather vectors where message data
1386 /// should be stored.
1387 pub ri_data: (*const iovec, usize),
1388 /// Buffer where numbers of incoming file descriptors
1389 /// should be stored.
1390 pub ri_fds: (*mut fd, usize),
1392 pub ri_flags: riflags,
1395 #[cfg(target_pointer_width = "32")]
1396 fn recv_in_layout_test_32() {
1397 assert_eq!(::core::mem::size_of::<recv_in>(), 20);
1398 assert_eq!(::core::mem::align_of::<recv_in>(), 4);
1400 let obj: recv_in = ::core::mem::uninitialized();
1401 let base = &obj as *const _ as usize;
1402 assert_eq!(&obj.ri_data.0 as *const _ as usize - base, 0);
1403 assert_eq!(&obj.ri_data.1 as *const _ as usize - base, 4);
1404 assert_eq!(&obj.ri_fds.0 as *const _ as usize - base, 8);
1405 assert_eq!(&obj.ri_fds.1 as *const _ as usize - base, 12);
1406 assert_eq!(&obj.ri_flags as *const _ as usize - base, 16);
1410 #[cfg(target_pointer_width = "64")]
1411 fn recv_in_layout_test_64() {
1412 assert_eq!(::core::mem::size_of::<recv_in>(), 40);
1413 assert_eq!(::core::mem::align_of::<recv_in>(), 8);
1415 let obj: recv_in = ::core::mem::uninitialized();
1416 let base = &obj as *const _ as usize;
1417 assert_eq!(&obj.ri_data.0 as *const _ as usize - base, 0);
1418 assert_eq!(&obj.ri_data.1 as *const _ as usize - base, 8);
1419 assert_eq!(&obj.ri_fds.0 as *const _ as usize - base, 16);
1420 assert_eq!(&obj.ri_fds.1 as *const _ as usize - base, 24);
1421 assert_eq!(&obj.ri_flags as *const _ as usize - base, 32);
1425 /// Results of [`sock_recv()`](fn.sock_recv.html).
1427 #[derive(Copy, Clone)]
1428 pub struct recv_out {
1429 /// Number of bytes stored in [`recv_in.ri_data`](struct.recv_in.html#structfield.ri_data).
1430 pub ro_datalen: usize,
1431 /// Number of file descriptors stored in [`recv_in.ri_fds`](struct.recv_in.html#structfield.ri_fds).
1432 pub ro_fdslen: usize,
1433 /// Fields that were used by previous implementations.
1434 pub ro_unused: [u8; 40],
1436 pub ro_flags: roflags,
1439 #[cfg(target_pointer_width = "32")]
1440 fn recv_out_layout_test_32() {
1441 assert_eq!(::core::mem::size_of::<recv_out>(), 52);
1442 assert_eq!(::core::mem::align_of::<recv_out>(), 4);
1444 let obj: recv_out = ::core::mem::uninitialized();
1445 let base = &obj as *const _ as usize;
1446 assert_eq!(&obj.ro_datalen as *const _ as usize - base, 0);
1447 assert_eq!(&obj.ro_fdslen as *const _ as usize - base, 4);
1448 assert_eq!(&obj.ro_unused as *const _ as usize - base, 8);
1449 assert_eq!(&obj.ro_flags as *const _ as usize - base, 48);
1453 #[cfg(target_pointer_width = "64")]
1454 fn recv_out_layout_test_64() {
1455 assert_eq!(::core::mem::size_of::<recv_out>(), 64);
1456 assert_eq!(::core::mem::align_of::<recv_out>(), 8);
1458 let obj: recv_out = ::core::mem::uninitialized();
1459 let base = &obj as *const _ as usize;
1460 assert_eq!(&obj.ro_datalen as *const _ as usize - base, 0);
1461 assert_eq!(&obj.ro_fdslen as *const _ as usize - base, 8);
1462 assert_eq!(&obj.ro_unused as *const _ as usize - base, 16);
1463 assert_eq!(&obj.ro_flags as *const _ as usize - base, 56);
1467 /// Arguments of [`sock_send()`](fn.sock_send.html).
1469 #[derive(Copy, Clone)]
1470 pub struct send_in {
1471 /// List of scatter/gather vectors where message data
1472 /// should be retrieved.
1473 pub si_data: (*const ciovec, usize),
1474 /// File descriptors that need to be attached to the
1476 pub si_fds: (*const fd, usize),
1478 pub si_flags: siflags,
1481 #[cfg(target_pointer_width = "32")]
1482 fn send_in_layout_test_32() {
1483 assert_eq!(::core::mem::size_of::<send_in>(), 20);
1484 assert_eq!(::core::mem::align_of::<send_in>(), 4);
1486 let obj: send_in = ::core::mem::uninitialized();
1487 let base = &obj as *const _ as usize;
1488 assert_eq!(&obj.si_data.0 as *const _ as usize - base, 0);
1489 assert_eq!(&obj.si_data.1 as *const _ as usize - base, 4);
1490 assert_eq!(&obj.si_fds.0 as *const _ as usize - base, 8);
1491 assert_eq!(&obj.si_fds.1 as *const _ as usize - base, 12);
1492 assert_eq!(&obj.si_flags as *const _ as usize - base, 16);
1496 #[cfg(target_pointer_width = "64")]
1497 fn send_in_layout_test_64() {
1498 assert_eq!(::core::mem::size_of::<send_in>(), 40);
1499 assert_eq!(::core::mem::align_of::<send_in>(), 8);
1501 let obj: send_in = ::core::mem::uninitialized();
1502 let base = &obj as *const _ as usize;
1503 assert_eq!(&obj.si_data.0 as *const _ as usize - base, 0);
1504 assert_eq!(&obj.si_data.1 as *const _ as usize - base, 8);
1505 assert_eq!(&obj.si_fds.0 as *const _ as usize - base, 16);
1506 assert_eq!(&obj.si_fds.1 as *const _ as usize - base, 24);
1507 assert_eq!(&obj.si_flags as *const _ as usize - base, 32);
1511 /// Results of [`sock_send()`](fn.sock_send.html).
1513 #[derive(Copy, Clone)]
1514 pub struct send_out {
1515 /// Number of bytes transmitted.
1516 pub so_datalen: usize,
1519 #[cfg(target_pointer_width = "32")]
1520 fn send_out_layout_test_32() {
1521 assert_eq!(::core::mem::size_of::<send_out>(), 4);
1522 assert_eq!(::core::mem::align_of::<send_out>(), 4);
1524 let obj: send_out = ::core::mem::uninitialized();
1525 let base = &obj as *const _ as usize;
1526 assert_eq!(&obj.so_datalen as *const _ as usize - base, 0);
1530 #[cfg(target_pointer_width = "64")]
1531 fn send_out_layout_test_64() {
1532 assert_eq!(::core::mem::size_of::<send_out>(), 8);
1533 assert_eq!(::core::mem::align_of::<send_out>(), 8);
1535 let obj: send_out = ::core::mem::uninitialized();
1536 let base = &obj as *const _ as usize;
1537 assert_eq!(&obj.so_datalen as *const _ as usize - base, 0);
1541 /// Subscription to an event.
1543 #[derive(Copy, Clone)]
1544 pub struct subscription {
1545 /// User-provided value that is attached to the
1546 /// subscription in the kernel and returned through
1547 /// [`event.userdata`](struct.event.html#structfield.userdata).
1548 pub userdata: userdata,
1549 /// Used by previous implementations. Ignored.
1551 /// The type of the event to which to subscribe.
1553 /// Currently, [`CONDVAR`](enum.eventtype.html#variant.CONDVAR),
1554 /// [`LOCK_RDLOCK`](enum.eventtype.html#variant.LOCK_RDLOCK), and [`LOCK_WRLOCK`](enum.eventtype.html#variant.LOCK_WRLOCK)
1555 /// must be provided as the first subscription and may
1556 /// only be followed by up to one other subscription,
1557 /// having type [`CLOCK`](enum.eventtype.html#variant.CLOCK).
1558 pub type_: eventtype,
1559 pub union: subscription_union
1561 /// A union inside `subscription`.
1563 #[derive(Copy, Clone)]
1564 pub union subscription_union {
1565 /// Used when `type_` is [`CLOCK`](enum.eventtype.html#variant.CLOCK).
1566 pub clock: subscription_clock,
1567 /// Used when `type_` is [`CONDVAR`](enum.eventtype.html#variant.CONDVAR).
1568 pub condvar: subscription_condvar,
1569 /// Used when `type_` is [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
1570 pub fd_readwrite: subscription_fd_readwrite,
1571 /// Used when `type_` is [`LOCK_RDLOCK`](enum.eventtype.html#variant.LOCK_RDLOCK) or [`LOCK_WRLOCK`](enum.eventtype.html#variant.LOCK_WRLOCK).
1572 pub lock: subscription_lock,
1573 /// Used when `type_` is [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
1574 pub proc_terminate: subscription_proc_terminate,
1577 #[derive(Copy, Clone)]
1578 pub struct subscription_clock {
1579 /// The user-defined unique
1580 /// identifier of the clock.
1581 pub identifier: userdata,
1582 /// The clock against which the
1583 /// timestamp should be compared.
1584 pub clock_id: clockid,
1585 /// The absolute or relative
1587 pub timeout: timestamp,
1588 /// The amount of time that the
1589 /// kernel may wait additionally
1590 /// to coalesce with other events.
1591 pub precision: timestamp,
1592 /// Flags specifying whether the
1593 /// timeout is absolute or
1595 pub flags: subclockflags,
1598 #[derive(Copy, Clone)]
1599 pub struct subscription_condvar {
1600 /// The condition variable on
1601 /// which to wait to be woken up.
1602 pub condvar: *mut condvar,
1603 /// The lock that will be
1604 /// released while waiting.
1606 /// The lock will be reacquired
1607 /// for writing when the condition
1608 /// variable triggers.
1609 pub lock: *mut lock,
1610 /// Whether the condition variable
1611 /// is stored in private or shared
1613 pub condvar_scope: scope,
1614 /// Whether the lock is stored in
1615 /// private or shared memory.
1616 pub lock_scope: scope,
1619 #[derive(Copy, Clone)]
1620 pub struct subscription_fd_readwrite {
1621 /// The file descriptor on which
1622 /// to wait for it to become ready
1623 /// for reading or writing.
1625 /// Under which conditions to
1627 pub flags: subrwflags,
1630 #[derive(Copy, Clone)]
1631 pub struct subscription_lock {
1632 /// The lock that will be acquired
1633 /// for reading or writing.
1634 pub lock: *mut lock,
1635 /// Whether the lock is stored in
1636 /// private or shared memory.
1637 pub lock_scope: scope,
1640 #[derive(Copy, Clone)]
1641 pub struct subscription_proc_terminate {
1642 /// The process descriptor on
1643 /// which to wait for process
1648 #[cfg(target_pointer_width = "32")]
1649 fn subscription_layout_test_32() {
1650 assert_eq!(::core::mem::size_of::<subscription>(), 56);
1651 assert_eq!(::core::mem::align_of::<subscription>(), 8);
1653 let obj: subscription = ::core::mem::uninitialized();
1654 let base = &obj as *const _ as usize;
1655 assert_eq!(&obj.userdata as *const _ as usize - base, 0);
1656 assert_eq!(&obj.unused as *const _ as usize - base, 8);
1657 assert_eq!(&obj.type_ as *const _ as usize - base, 10);
1658 assert_eq!(&obj.union.clock.identifier as *const _ as usize - base, 16);
1659 assert_eq!(&obj.union.clock.clock_id as *const _ as usize - base, 24);
1660 assert_eq!(&obj.union.clock.timeout as *const _ as usize - base, 32);
1661 assert_eq!(&obj.union.clock.precision as *const _ as usize - base, 40);
1662 assert_eq!(&obj.union.clock.flags as *const _ as usize - base, 48);
1663 assert_eq!(&obj.union.condvar.condvar as *const _ as usize - base, 16);
1664 assert_eq!(&obj.union.condvar.lock as *const _ as usize - base, 20);
1665 assert_eq!(&obj.union.condvar.condvar_scope as *const _ as usize - base, 24);
1666 assert_eq!(&obj.union.condvar.lock_scope as *const _ as usize - base, 25);
1667 assert_eq!(&obj.union.fd_readwrite.fd as *const _ as usize - base, 16);
1668 assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 20);
1669 assert_eq!(&obj.union.lock.lock as *const _ as usize - base, 16);
1670 assert_eq!(&obj.union.lock.lock_scope as *const _ as usize - base, 20);
1671 assert_eq!(&obj.union.proc_terminate.fd as *const _ as usize - base, 16);
1675 #[cfg(target_pointer_width = "64")]
1676 fn subscription_layout_test_64() {
1677 assert_eq!(::core::mem::size_of::<subscription>(), 56);
1678 assert_eq!(::core::mem::align_of::<subscription>(), 8);
1680 let obj: subscription = ::core::mem::uninitialized();
1681 let base = &obj as *const _ as usize;
1682 assert_eq!(&obj.userdata as *const _ as usize - base, 0);
1683 assert_eq!(&obj.unused as *const _ as usize - base, 8);
1684 assert_eq!(&obj.type_ as *const _ as usize - base, 10);
1685 assert_eq!(&obj.union.clock.identifier as *const _ as usize - base, 16);
1686 assert_eq!(&obj.union.clock.clock_id as *const _ as usize - base, 24);
1687 assert_eq!(&obj.union.clock.timeout as *const _ as usize - base, 32);
1688 assert_eq!(&obj.union.clock.precision as *const _ as usize - base, 40);
1689 assert_eq!(&obj.union.clock.flags as *const _ as usize - base, 48);
1690 assert_eq!(&obj.union.condvar.condvar as *const _ as usize - base, 16);
1691 assert_eq!(&obj.union.condvar.lock as *const _ as usize - base, 24);
1692 assert_eq!(&obj.union.condvar.condvar_scope as *const _ as usize - base, 32);
1693 assert_eq!(&obj.union.condvar.lock_scope as *const _ as usize - base, 33);
1694 assert_eq!(&obj.union.fd_readwrite.fd as *const _ as usize - base, 16);
1695 assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 20);
1696 assert_eq!(&obj.union.lock.lock as *const _ as usize - base, 16);
1697 assert_eq!(&obj.union.lock.lock_scope as *const _ as usize - base, 24);
1698 assert_eq!(&obj.union.proc_terminate.fd as *const _ as usize - base, 16);
1702 /// The Thread Control Block (TCB).
1704 /// After a thread begins execution (at program startup or when
1705 /// created through [`thread_create()`](fn.thread_create.html)), the CPU's registers
1706 /// controlling Thread-Local Storage (TLS) will already be
1707 /// initialized. They will point to an area only containing the
1710 /// If the thread needs space for storing thread-specific
1711 /// variables, the thread may allocate a larger area and adjust
1712 /// the CPU's registers to point to that area instead. However, it
1713 /// does need to make sure that the TCB is copied over to the new
1716 /// The purpose of the TCB is that it allows light-weight
1717 /// emulators to store information related to individual threads.
1718 /// For example, it may be used to store a copy of the CPU
1719 /// registers prior emulation, so that TLS for the host system
1720 /// can be restored if needed.
1722 #[derive(Copy, Clone)]
1724 /// Pointer that may be freely assigned by the system. Its
1725 /// value cannot be interpreted by the application.
1726 pub parent: *mut (),
1729 #[cfg(target_pointer_width = "32")]
1730 fn tcb_layout_test_32() {
1731 assert_eq!(::core::mem::size_of::<tcb>(), 4);
1732 assert_eq!(::core::mem::align_of::<tcb>(), 4);
1734 let obj: tcb = ::core::mem::uninitialized();
1735 let base = &obj as *const _ as usize;
1736 assert_eq!(&obj.parent as *const _ as usize - base, 0);
1740 #[cfg(target_pointer_width = "64")]
1741 fn tcb_layout_test_64() {
1742 assert_eq!(::core::mem::size_of::<tcb>(), 8);
1743 assert_eq!(::core::mem::align_of::<tcb>(), 8);
1745 let obj: tcb = ::core::mem::uninitialized();
1746 let base = &obj as *const _ as usize;
1747 assert_eq!(&obj.parent as *const _ as usize - base, 0);
1751 /// Entry point for additionally created threads.
1754 /// Thread ID of the current thread.
1757 /// Copy of the value stored in
1758 /// [`threadattr.argument`](struct.threadattr.html#structfield.argument).
1759 pub type threadentry = unsafe extern "C" fn(
1764 /// Attributes for thread creation.
1766 #[derive(Copy, Clone)]
1767 pub struct threadattr {
1768 /// Initial program counter value.
1769 pub entry_point: threadentry,
1770 /// Region allocated to serve as stack space.
1771 pub stack: (*mut (), usize),
1772 /// Argument to be forwarded to the entry point function.
1773 pub argument: *mut (),
1776 #[cfg(target_pointer_width = "32")]
1777 fn threadattr_layout_test_32() {
1778 assert_eq!(::core::mem::size_of::<threadattr>(), 16);
1779 assert_eq!(::core::mem::align_of::<threadattr>(), 4);
1781 let obj: threadattr = ::core::mem::uninitialized();
1782 let base = &obj as *const _ as usize;
1783 assert_eq!(&obj.entry_point as *const _ as usize - base, 0);
1784 assert_eq!(&obj.stack.0 as *const _ as usize - base, 4);
1785 assert_eq!(&obj.stack.1 as *const _ as usize - base, 8);
1786 assert_eq!(&obj.argument as *const _ as usize - base, 12);
1790 #[cfg(target_pointer_width = "64")]
1791 fn threadattr_layout_test_64() {
1792 assert_eq!(::core::mem::size_of::<threadattr>(), 32);
1793 assert_eq!(::core::mem::align_of::<threadattr>(), 8);
1795 let obj: threadattr = ::core::mem::uninitialized();
1796 let base = &obj as *const _ as usize;
1797 assert_eq!(&obj.entry_point as *const _ as usize - base, 0);
1798 assert_eq!(&obj.stack.0 as *const _ as usize - base, 8);
1799 assert_eq!(&obj.stack.1 as *const _ as usize - base, 16);
1800 assert_eq!(&obj.argument as *const _ as usize - base, 24);
1804 /// The table with pointers to all syscall implementations.
1805 #[allow(improper_ctypes)]
1807 fn cloudabi_sys_clock_res_get(_: clockid, _: *mut timestamp) -> errno;
1808 fn cloudabi_sys_clock_time_get(_: clockid, _: timestamp, _: *mut timestamp) -> errno;
1809 fn cloudabi_sys_condvar_signal(_: *mut condvar, _: scope, _: nthreads) -> errno;
1810 fn cloudabi_sys_fd_close(_: fd) -> errno;
1811 fn cloudabi_sys_fd_create1(_: filetype, _: *mut fd) -> errno;
1812 fn cloudabi_sys_fd_create2(_: filetype, _: *mut fd, _: *mut fd) -> errno;
1813 fn cloudabi_sys_fd_datasync(_: fd) -> errno;
1814 fn cloudabi_sys_fd_dup(_: fd, _: *mut fd) -> errno;
1815 fn cloudabi_sys_fd_pread(_: fd, _: *const iovec, _: usize, _: filesize, _: *mut usize) -> errno;
1816 fn cloudabi_sys_fd_pwrite(_: fd, _: *const ciovec, _: usize, _: filesize, _: *mut usize) -> errno;
1817 fn cloudabi_sys_fd_read(_: fd, _: *const iovec, _: usize, _: *mut usize) -> errno;
1818 fn cloudabi_sys_fd_replace(_: fd, _: fd) -> errno;
1819 fn cloudabi_sys_fd_seek(_: fd, _: filedelta, _: whence, _: *mut filesize) -> errno;
1820 fn cloudabi_sys_fd_stat_get(_: fd, _: *mut fdstat) -> errno;
1821 fn cloudabi_sys_fd_stat_put(_: fd, _: *const fdstat, _: fdsflags) -> errno;
1822 fn cloudabi_sys_fd_sync(_: fd) -> errno;
1823 fn cloudabi_sys_fd_write(_: fd, _: *const ciovec, _: usize, _: *mut usize) -> errno;
1824 fn cloudabi_sys_file_advise(_: fd, _: filesize, _: filesize, _: advice) -> errno;
1825 fn cloudabi_sys_file_allocate(_: fd, _: filesize, _: filesize) -> errno;
1826 fn cloudabi_sys_file_create(_: fd, _: *const u8, _: usize, _: filetype) -> errno;
1827 fn cloudabi_sys_file_link(_: lookup, _: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
1828 fn cloudabi_sys_file_open(_: lookup, _: *const u8, _: usize, _: oflags, _: *const fdstat, _: *mut fd) -> errno;
1829 fn cloudabi_sys_file_readdir(_: fd, _: *mut (), _: usize, _: dircookie, _: *mut usize) -> errno;
1830 fn cloudabi_sys_file_readlink(_: fd, _: *const u8, _: usize, _: *mut u8, _: usize, _: *mut usize) -> errno;
1831 fn cloudabi_sys_file_rename(_: fd, _: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
1832 fn cloudabi_sys_file_stat_fget(_: fd, _: *mut filestat) -> errno;
1833 fn cloudabi_sys_file_stat_fput(_: fd, _: *const filestat, _: fsflags) -> errno;
1834 fn cloudabi_sys_file_stat_get(_: lookup, _: *const u8, _: usize, _: *mut filestat) -> errno;
1835 fn cloudabi_sys_file_stat_put(_: lookup, _: *const u8, _: usize, _: *const filestat, _: fsflags) -> errno;
1836 fn cloudabi_sys_file_symlink(_: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
1837 fn cloudabi_sys_file_unlink(_: fd, _: *const u8, _: usize, _: ulflags) -> errno;
1838 fn cloudabi_sys_lock_unlock(_: *mut lock, _: scope) -> errno;
1839 fn cloudabi_sys_mem_advise(_: *mut (), _: usize, _: advice) -> errno;
1840 fn cloudabi_sys_mem_map(_: *mut (), _: usize, _: mprot, _: mflags, _: fd, _: filesize, _: *mut *mut ()) -> errno;
1841 fn cloudabi_sys_mem_protect(_: *mut (), _: usize, _: mprot) -> errno;
1842 fn cloudabi_sys_mem_sync(_: *mut (), _: usize, _: msflags) -> errno;
1843 fn cloudabi_sys_mem_unmap(_: *mut (), _: usize) -> errno;
1844 fn cloudabi_sys_poll(_: *const subscription, _: *mut event, _: usize, _: *mut usize) -> errno;
1845 fn cloudabi_sys_proc_exec(_: fd, _: *const (), _: usize, _: *const fd, _: usize) -> errno;
1846 fn cloudabi_sys_proc_exit(_: exitcode) -> !;
1847 fn cloudabi_sys_proc_fork(_: *mut fd, _: *mut tid) -> errno;
1848 fn cloudabi_sys_proc_raise(_: signal) -> errno;
1849 fn cloudabi_sys_random_get(_: *mut (), _: usize) -> errno;
1850 fn cloudabi_sys_sock_recv(_: fd, _: *const recv_in, _: *mut recv_out) -> errno;
1851 fn cloudabi_sys_sock_send(_: fd, _: *const send_in, _: *mut send_out) -> errno;
1852 fn cloudabi_sys_sock_shutdown(_: fd, _: sdflags) -> errno;
1853 fn cloudabi_sys_thread_create(_: *mut threadattr, _: *mut tid) -> errno;
1854 fn cloudabi_sys_thread_exit(_: *mut lock, _: scope) -> !;
1855 fn cloudabi_sys_thread_yield() -> errno;
1858 /// Obtains the resolution of a clock.
1863 /// The clock for which the resolution needs to be
1867 /// The resolution of the clock.
1869 pub unsafe fn clock_res_get(clock_id_: clockid, resolution_: &mut timestamp) -> errno {
1870 cloudabi_sys_clock_res_get(clock_id_, resolution_)
1873 /// Obtains the time value of a clock.
1878 /// The clock for which the time needs to be
1882 /// The maximum lag (exclusive) that the returned
1883 /// time value may have, compared to its actual
1887 /// The time value of the clock.
1889 pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: &mut timestamp) -> errno {
1890 cloudabi_sys_clock_time_get(clock_id_, precision_, time_)
1893 /// Wakes up threads waiting on a userspace condition variable.
1895 /// If an invocation of this system call causes all waiting
1896 /// threads to be woken up, the value of the condition variable
1897 /// is set to [`CONDVAR_HAS_NO_WAITERS`](constant.CONDVAR_HAS_NO_WAITERS.html). As long as the condition
1898 /// variable is set to this value, it is not needed to invoke this
1904 /// The userspace condition variable that has
1905 /// waiting threads.
1908 /// Whether the condition variable is stored in
1909 /// private or shared memory.
1912 /// The number of threads that need to be woken
1913 /// up. If it exceeds the number of waiting
1914 /// threads, all threads are woken up.
1916 pub unsafe fn condvar_signal(condvar_: *mut condvar, scope_: scope, nwaiters_: nthreads) -> errno {
1917 cloudabi_sys_condvar_signal(condvar_, scope_, nwaiters_)
1920 /// Closes a file descriptor.
1925 /// The file descriptor that needs to be closed.
1927 pub unsafe fn fd_close(fd_: fd) -> errno {
1928 cloudabi_sys_fd_close(fd_)
1931 /// Creates a file descriptor.
1936 /// Possible values:
1938 /// - [`SHARED_MEMORY`](enum.filetype.html#variant.SHARED_MEMORY):
1939 /// Creates an anonymous shared memory
1943 /// The file descriptor that has been created.
1945 pub unsafe fn fd_create1(type_: filetype, fd_: &mut fd) -> errno {
1946 cloudabi_sys_fd_create1(type_, fd_)
1949 /// Creates a pair of file descriptors.
1954 /// Possible values:
1956 /// - [`SOCKET_DGRAM`](enum.filetype.html#variant.SOCKET_DGRAM):
1957 /// Creates a UNIX datagram socket pair.
1958 /// - [`SOCKET_STREAM`](enum.filetype.html#variant.SOCKET_STREAM):
1959 /// Creates a UNIX byte-stream socket
1963 /// The first file descriptor of the pair.
1966 /// The second file descriptor of the pair.
1968 pub unsafe fn fd_create2(type_: filetype, fd1_: &mut fd, fd2_: &mut fd) -> errno {
1969 cloudabi_sys_fd_create2(type_, fd1_, fd2_)
1972 /// Synchronizes the data of a file to disk.
1977 /// The file descriptor of the file whose data
1978 /// needs to be synchronized to disk.
1980 pub unsafe fn fd_datasync(fd_: fd) -> errno {
1981 cloudabi_sys_fd_datasync(fd_)
1984 /// Duplicates a file descriptor.
1989 /// The file descriptor that needs to be
1993 /// The new file descriptor.
1995 pub unsafe fn fd_dup(from_: fd, fd_: &mut fd) -> errno {
1996 cloudabi_sys_fd_dup(from_, fd_)
1999 /// Reads from a file descriptor, without using and updating the
2000 /// file descriptor's offset.
2005 /// The file descriptor from which data should be
2009 /// List of scatter/gather vectors where data
2010 /// should be stored.
2013 /// The offset within the file at which reading
2017 /// The number of bytes read.
2019 pub unsafe fn fd_pread(fd_: fd, iovs_: &[iovec], offset_: filesize, nread_: &mut usize) -> errno {
2020 cloudabi_sys_fd_pread(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nread_)
2023 /// Writes to a file descriptor, without using and updating the
2024 /// file descriptor's offset.
2029 /// The file descriptor to which data should be
2033 /// List of scatter/gather vectors where data
2034 /// should be retrieved.
2037 /// The offset within the file at which writing
2041 /// The number of bytes written.
2043 pub unsafe fn fd_pwrite(fd_: fd, iovs_: &[ciovec], offset_: filesize, nwritten_: &mut usize) -> errno {
2044 cloudabi_sys_fd_pwrite(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nwritten_)
2047 /// Reads from a file descriptor.
2052 /// The file descriptor from which data should be
2056 /// List of scatter/gather vectors where data
2057 /// should be stored.
2060 /// The number of bytes read.
2062 pub unsafe fn fd_read(fd_: fd, iovs_: &[iovec], nread_: &mut usize) -> errno {
2063 cloudabi_sys_fd_read(fd_, iovs_.as_ptr(), iovs_.len(), nread_)
2066 /// Atomically replaces a file descriptor by a copy of another
2067 /// file descriptor.
2069 /// Due to the strong focus on thread safety, this environment
2070 /// does not provide a mechanism to duplicate a file descriptor to
2071 /// an arbitrary number, like dup2(). This would be prone to race
2072 /// conditions, as an actual file descriptor with the same number
2073 /// could be allocated by a different thread at the same time.
2075 /// This system call provides a way to atomically replace file
2076 /// descriptors, which would disappear if dup2() were to be
2077 /// removed entirely.
2082 /// The file descriptor that needs to be copied.
2085 /// The file descriptor that needs to be
2088 pub unsafe fn fd_replace(from_: fd, to_: fd) -> errno {
2089 cloudabi_sys_fd_replace(from_, to_)
2092 /// Moves the offset of the file descriptor.
2097 /// The file descriptor whose offset has to be
2101 /// The number of bytes to move.
2104 /// Relative to which position the move should
2108 /// The new offset of the file descriptor,
2109 /// relative to the start of the file.
2111 pub unsafe fn fd_seek(fd_: fd, offset_: filedelta, whence_: whence, newoffset_: &mut filesize) -> errno {
2112 cloudabi_sys_fd_seek(fd_, offset_, whence_, newoffset_)
2115 /// Gets attributes of a file descriptor.
2120 /// The file descriptor whose attributes have to
2124 /// The buffer where the file descriptor's
2125 /// attributes are stored.
2127 pub unsafe fn fd_stat_get(fd_: fd, buf_: *mut fdstat) -> errno {
2128 cloudabi_sys_fd_stat_get(fd_, buf_)
2131 /// Adjusts attributes of a file descriptor.
2136 /// The file descriptor whose attributes have to
2140 /// The desired values of the file descriptor
2141 /// attributes that are adjusted.
2144 /// A bitmask indicating which attributes have to
2147 pub unsafe fn fd_stat_put(fd_: fd, buf_: *const fdstat, flags_: fdsflags) -> errno {
2148 cloudabi_sys_fd_stat_put(fd_, buf_, flags_)
2151 /// Synchronizes the data and metadata of a file to disk.
2156 /// The file descriptor of the file whose data
2157 /// and metadata needs to be synchronized to disk.
2159 pub unsafe fn fd_sync(fd_: fd) -> errno {
2160 cloudabi_sys_fd_sync(fd_)
2163 /// Writes to a file descriptor.
2168 /// The file descriptor to which data should be
2172 /// List of scatter/gather vectors where data
2173 /// should be retrieved.
2176 /// The number of bytes written.
2178 pub unsafe fn fd_write(fd_: fd, iovs_: &[ciovec], nwritten_: &mut usize) -> errno {
2179 cloudabi_sys_fd_write(fd_, iovs_.as_ptr(), iovs_.len(), nwritten_)
2182 /// Provides file advisory information on a file descriptor.
2187 /// The file descriptor for which to provide file
2188 /// advisory information.
2191 /// The offset within the file to which the
2192 /// advisory applies.
2195 /// The length of the region to which the advisory
2201 pub unsafe fn file_advise(fd_: fd, offset_: filesize, len_: filesize, advice_: advice) -> errno {
2202 cloudabi_sys_file_advise(fd_, offset_, len_, advice_)
2205 /// Forces the allocation of space in a file.
2210 /// The file in which the space should be
2214 /// The offset at which the allocation should
2218 /// The length of the area that is allocated.
2220 pub unsafe fn file_allocate(fd_: fd, offset_: filesize, len_: filesize) -> errno {
2221 cloudabi_sys_file_allocate(fd_, offset_, len_)
2224 /// Creates a file of a specified type.
2229 /// The working directory at which the resolution
2230 /// of the file to be created starts.
2233 /// The path at which the file should be created.
2236 /// Possible values:
2238 /// - [`DIRECTORY`](enum.filetype.html#variant.DIRECTORY):
2239 /// Creates a directory.
2241 pub unsafe fn file_create(fd_: fd, path_: &[u8], type_: filetype) -> errno {
2242 cloudabi_sys_file_create(fd_, path_.as_ptr(), path_.len(), type_)
2245 /// Creates a hard link.
2250 /// The working directory at which the resolution
2251 /// of the source path starts.
2254 /// The source path of the file that should be
2258 /// The working directory at which the resolution
2259 /// of the destination path starts.
2262 /// The destination path at which the hard link
2263 /// should be created.
2265 pub unsafe fn file_link(fd1_: lookup, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> errno {
2266 cloudabi_sys_file_link(fd1_, path1_.as_ptr(), path1_.len(), fd2_, path2_.as_ptr(), path2_.len())
2274 /// The working directory at which the resolution
2275 /// of the file to be opened starts.
2278 /// The path of the file that should be opened.
2281 /// The method at which the file should be opened.
2284 /// [`fdstat.fs_rights_base`](struct.fdstat.html#structfield.fs_rights_base) and
2285 /// [`fdstat.fs_rights_inheriting`](struct.fdstat.html#structfield.fs_rights_inheriting) specify the
2286 /// initial rights of the newly created file
2287 /// descriptor. The operating system is allowed to
2288 /// return a file descriptor with fewer rights
2289 /// than specified, if and only if those rights do
2290 /// not apply to the type of file being opened.
2292 /// [`fdstat.fs_flags`](struct.fdstat.html#structfield.fs_flags) specifies the initial flags
2293 /// of the file descriptor.
2295 /// [`fdstat.fs_filetype`](struct.fdstat.html#structfield.fs_filetype) is ignored.
2298 /// The file descriptor of the file that has been
2301 pub unsafe fn file_open(dirfd_: lookup, path_: &[u8], oflags_: oflags, fds_: *const fdstat, fd_: &mut fd) -> errno {
2302 cloudabi_sys_file_open(dirfd_, path_.as_ptr(), path_.len(), oflags_, fds_, fd_)
2305 /// Reads directory entries from a directory.
2307 /// When successful, the contents of the output buffer consist of
2308 /// a sequence of directory entries. Each directory entry consists
2309 /// of a [`dirent`](struct.dirent.html) object, followed by [`dirent.d_namlen`](struct.dirent.html#structfield.d_namlen) bytes
2310 /// holding the name of the directory entry.
2312 /// This system call fills the output buffer as much as possible,
2313 /// potentially truncating the last directory entry. This allows
2314 /// the caller to grow its read buffer size in case it's too small
2315 /// to fit a single large directory entry, or skip the oversized
2316 /// directory entry.
2321 /// The directory from which to read the directory
2325 /// The buffer where directory entries are stored.
2328 /// The location within the directory to start
2332 /// The number of bytes stored in the read buffer.
2333 /// If less than the size of the read buffer, the
2334 /// end of the directory has been reached.
2336 pub unsafe fn file_readdir(fd_: fd, buf_: &mut [u8], cookie_: dircookie, bufused_: &mut usize) -> errno {
2337 cloudabi_sys_file_readdir(fd_, buf_.as_mut_ptr() as *mut (), buf_.len(), cookie_, bufused_)
2340 /// Reads the contents of a symbolic link.
2345 /// The working directory at which the resolution
2346 /// of the path of the symbolic starts.
2349 /// The path of the symbolic link whose contents
2353 /// The buffer where the contents of the symbolic
2354 /// link should be stored.
2357 /// The number of bytes placed in the buffer.
2359 pub unsafe fn file_readlink(fd_: fd, path_: &[u8], buf_: &mut [u8], bufused_: &mut usize) -> errno {
2360 cloudabi_sys_file_readlink(fd_, path_.as_ptr(), path_.len(), buf_.as_mut_ptr(), buf_.len(), bufused_)
2368 /// The working directory at which the resolution
2369 /// of the source path starts.
2372 /// The source path of the file that should be
2376 /// The working directory at which the resolution
2377 /// of the destination path starts.
2380 /// The destination path to which the file should
2383 pub unsafe fn file_rename(fd1_: fd, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> errno {
2384 cloudabi_sys_file_rename(fd1_, path1_.as_ptr(), path1_.len(), fd2_, path2_.as_ptr(), path2_.len())
2387 /// Gets attributes of a file by file descriptor.
2392 /// The file descriptor whose attributes have to
2396 /// The buffer where the file's attributes are
2399 pub unsafe fn file_stat_fget(fd_: fd, buf_: *mut filestat) -> errno {
2400 cloudabi_sys_file_stat_fget(fd_, buf_)
2403 /// Adjusts attributes of a file by file descriptor.
2408 /// The file descriptor whose attributes have to
2412 /// The desired values of the file attributes that
2416 /// A bitmask indicating which attributes have to
2419 pub unsafe fn file_stat_fput(fd_: fd, buf_: *const filestat, flags_: fsflags) -> errno {
2420 cloudabi_sys_file_stat_fput(fd_, buf_, flags_)
2423 /// Gets attributes of a file by path.
2428 /// The working directory at which the resolution
2429 /// of the path whose attributes have to be
2430 /// obtained starts.
2433 /// The path of the file whose attributes have to
2437 /// The buffer where the file's attributes are
2440 pub unsafe fn file_stat_get(fd_: lookup, path_: &[u8], buf_: *mut filestat) -> errno {
2441 cloudabi_sys_file_stat_get(fd_, path_.as_ptr(), path_.len(), buf_)
2444 /// Adjusts attributes of a file by path.
2449 /// The working directory at which the resolution
2450 /// of the path whose attributes have to be
2451 /// adjusted starts.
2454 /// The path of the file whose attributes have to
2458 /// The desired values of the file attributes that
2462 /// A bitmask indicating which attributes have to
2465 pub unsafe fn file_stat_put(fd_: lookup, path_: &[u8], buf_: *const filestat, flags_: fsflags) -> errno {
2466 cloudabi_sys_file_stat_put(fd_, path_.as_ptr(), path_.len(), buf_, flags_)
2469 /// Creates a symbolic link.
2474 /// The contents of the symbolic link.
2477 /// The working directory at which the resolution
2478 /// of the destination path starts.
2481 /// The destination path at which the symbolic
2482 /// link should be created.
2484 pub unsafe fn file_symlink(path1_: &[u8], fd_: fd, path2_: &[u8]) -> errno {
2485 cloudabi_sys_file_symlink(path1_.as_ptr(), path1_.len(), fd_, path2_.as_ptr(), path2_.len())
2488 /// Unlinks a file, or removes a directory.
2493 /// The working directory at which the resolution
2494 /// of the path starts.
2497 /// The path that needs to be unlinked or removed.
2500 /// Possible values:
2502 /// - [`REMOVEDIR`](struct.ulflags.html#associatedconstant.REMOVEDIR):
2503 /// If set, attempt to remove a directory.
2504 /// Otherwise, unlink a file.
2506 pub unsafe fn file_unlink(fd_: fd, path_: &[u8], flags_: ulflags) -> errno {
2507 cloudabi_sys_file_unlink(fd_, path_.as_ptr(), path_.len(), flags_)
2510 /// Unlocks a write-locked userspace lock.
2512 /// If a userspace lock is unlocked while having its
2513 /// [`LOCK_KERNEL_MANAGED`](constant.LOCK_KERNEL_MANAGED.html) flag set, the lock cannot be unlocked in
2514 /// userspace directly. This system call needs to be performed
2515 /// instead, so that any waiting threads can be woken up.
2517 /// To prevent spurious invocations of this system call, the lock
2518 /// must be locked for writing. This prevents other threads from
2519 /// acquiring additional read locks while the system call is in
2520 /// progress. If the lock is acquired for reading, it must first
2521 /// be upgraded to a write lock.
2526 /// The userspace lock that is locked for writing
2527 /// by the calling thread.
2530 /// Whether the lock is stored in private or
2533 pub unsafe fn lock_unlock(lock_: *mut lock, scope_: scope) -> errno {
2534 cloudabi_sys_lock_unlock(lock_, scope_)
2537 /// Provides memory advisory information on a region of memory.
2542 /// The pages for which to provide memory advisory
2548 pub unsafe fn mem_advise(mapping_: &mut [u8], advice_: advice) -> errno {
2549 cloudabi_sys_mem_advise(mapping_.as_mut_ptr() as *mut (), mapping_.len(), advice_)
2552 /// Creates a memory mapping, making the contents of a file
2553 /// accessible through memory.
2558 /// If [`FIXED`](struct.mflags.html#associatedconstant.FIXED) is set, specifies to which
2559 /// address the file region is mapped. Otherwise,
2560 /// the mapping is performed at an unused
2564 /// The length of the memory mapping to be
2568 /// Initial memory protection options for the
2572 /// Memory mapping flags.
2575 /// If [`ANON`](struct.mflags.html#associatedconstant.ANON) is set, this argument must be
2576 /// [`MAP_ANON_FD`](constant.MAP_ANON_FD.html). Otherwise, this argument
2577 /// specifies the file whose contents need to be
2581 /// If [`ANON`](struct.mflags.html#associatedconstant.ANON) is set, this argument must be
2582 /// zero. Otherwise, this argument specifies the
2583 /// offset within the file at which the mapping
2587 /// The starting address of the memory mapping.
2589 pub unsafe fn mem_map(addr_: *mut (), len_: usize, prot_: mprot, flags_: mflags, fd_: fd, off_: filesize, mem_: &mut *mut ()) -> errno {
2590 cloudabi_sys_mem_map(addr_, len_, prot_, flags_, fd_, off_, mem_)
2593 /// Change the protection of a memory mapping.
2598 /// The pages that need their protection changed.
2601 /// New protection options.
2603 pub unsafe fn mem_protect(mapping_: &mut [u8], prot_: mprot) -> errno {
2604 cloudabi_sys_mem_protect(mapping_.as_mut_ptr() as *mut (), mapping_.len(), prot_)
2607 /// Synchronize a region of memory with its physical storage.
2612 /// The pages that need to be synchronized.
2615 /// The method of synchronization.
2617 pub unsafe fn mem_sync(mapping_: &mut [u8], flags_: msflags) -> errno {
2618 cloudabi_sys_mem_sync(mapping_.as_mut_ptr() as *mut (), mapping_.len(), flags_)
2621 /// Unmaps a region of memory.
2626 /// The pages that needs to be unmapped.
2628 pub unsafe fn mem_unmap(mapping_: &mut [u8]) -> errno {
2629 cloudabi_sys_mem_unmap(mapping_.as_mut_ptr() as *mut (), mapping_.len())
2632 /// Concurrently polls for the occurrence of a set of events.
2637 /// The events to which to subscribe.
2640 /// The events that have occurred.
2642 /// **nsubscriptions**:
2643 /// Both the number of subscriptions and events.
2646 /// The number of events stored.
2648 pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: &mut usize) -> errno {
2649 cloudabi_sys_poll(in_, out_, nsubscriptions_, nevents_)
2652 /// Replaces the process by a new executable.
2654 /// Process execution in CloudABI differs from POSIX in two ways:
2655 /// handling of arguments and inheritance of file descriptors.
2657 /// CloudABI does not use string command line arguments. Instead,
2658 /// a buffer with binary data is copied into the address space of
2659 /// the new executable. The kernel does not enforce any specific
2660 /// structure to this data, although CloudABI's C library uses it
2661 /// to store a tree structure that is semantically identical to
2664 /// Due to the strong focus on thread safety, file descriptors
2665 /// aren't inherited through close-on-exec flags. An explicit
2666 /// list of file descriptors that need to be retained needs to be
2667 /// provided. After execution, file descriptors are placed in the
2668 /// order in which they are stored in the array. This not only
2669 /// makes the execution process deterministic. It also prevents
2670 /// potential information disclosures about the layout of the
2671 /// original process.
2676 /// A file descriptor of the new executable.
2679 /// Binary argument data that is passed on to the
2683 /// The layout of the file descriptor table after
2686 pub unsafe fn proc_exec(fd_: fd, data_: &[u8], fds_: &[fd]) -> errno {
2687 cloudabi_sys_proc_exec(fd_, data_.as_ptr() as *const (), data_.len(), fds_.as_ptr(), fds_.len())
2690 /// Terminates the process normally.
2695 /// The exit code returned by the process. The
2696 /// exit code can be obtained by other processes
2697 /// through [`event.union.proc_terminate.exitcode`](struct.event_proc_terminate.html#structfield.exitcode).
2699 pub unsafe fn proc_exit(rval_: exitcode) -> ! {
2700 cloudabi_sys_proc_exit(rval_)
2703 /// Forks the process of the calling thread.
2705 /// After forking, a new process shall be created, having only a
2706 /// copy of the calling thread. The parent process will obtain a
2707 /// process descriptor. When closed, the child process is
2708 /// automatically signaled with [`KILL`](enum.signal.html#variant.KILL).
2713 /// In the parent process: the file descriptor
2714 /// number of the process descriptor.
2716 /// In the child process: [`PROCESS_CHILD`](constant.PROCESS_CHILD.html).
2719 /// In the parent process: undefined.
2721 /// In the child process: the thread ID of the
2722 /// initial thread of the child process.
2724 pub unsafe fn proc_fork(fd_: &mut fd, tid_: &mut tid) -> errno {
2725 cloudabi_sys_proc_fork(fd_, tid_)
2728 /// Sends a signal to the process of the calling thread.
2733 /// The signal condition that should be triggered.
2734 /// If the signal causes the process to terminate,
2735 /// its condition can be obtained by other
2736 /// processes through
2737 /// [`event.union.proc_terminate.signal`](struct.event_proc_terminate.html#structfield.signal).
2739 pub unsafe fn proc_raise(sig_: signal) -> errno {
2740 cloudabi_sys_proc_raise(sig_)
2743 /// Obtains random data from the kernel random number generator.
2745 /// As this interface is not guaranteed to be fast, it is advised
2746 /// that the random data obtained through this system call is used
2747 /// as the seed for a userspace pseudo-random number generator.
2752 /// The buffer that needs to be filled with random
2755 pub unsafe fn random_get(buf_: &mut [u8]) -> errno {
2756 cloudabi_sys_random_get(buf_.as_mut_ptr() as *mut (), buf_.len())
2759 /// Receives a message on a socket.
2764 /// The socket on which a message should be
2768 /// Input parameters.
2771 /// Output parameters.
2773 pub unsafe fn sock_recv(sock_: fd, in_: *const recv_in, out_: *mut recv_out) -> errno {
2774 cloudabi_sys_sock_recv(sock_, in_, out_)
2777 /// Sends a message on a socket.
2782 /// The socket on which a message should be sent.
2785 /// Input parameters.
2788 /// Output parameters.
2790 pub unsafe fn sock_send(sock_: fd, in_: *const send_in, out_: *mut send_out) -> errno {
2791 cloudabi_sys_sock_send(sock_, in_, out_)
2794 /// Shuts down socket send and receive channels.
2799 /// The socket that needs its channels shut down.
2802 /// Which channels on the socket need to be shut
2805 pub unsafe fn sock_shutdown(sock_: fd, how_: sdflags) -> errno {
2806 cloudabi_sys_sock_shutdown(sock_, how_)
2809 /// Creates a new thread within the current process.
2814 /// The desired attributes of the new thread.
2817 /// The thread ID of the new thread.
2819 pub unsafe fn thread_create(attr_: *mut threadattr, tid_: &mut tid) -> errno {
2820 cloudabi_sys_thread_create(attr_, tid_)
2823 /// Terminates the calling thread.
2825 /// This system call can also unlock a single userspace lock
2826 /// after termination, which can be used to implement thread
2832 /// Userspace lock that is locked for writing by
2833 /// the calling thread.
2836 /// Whether the lock is stored in private or
2839 pub unsafe fn thread_exit(lock_: *mut lock, scope_: scope) -> ! {
2840 cloudabi_sys_thread_exit(lock_, scope_)
2843 /// Temporarily yields execution of the calling thread.
2845 pub unsafe fn thread_yield() -> errno {
2846 cloudabi_sys_thread_yield()