1 // Copyright (c) 2016-2017 Nuxi (https://nuxi.nl/) and contributors. 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions 5 // are met: 6 // 1. Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // 2. Redistributions in binary form must reproduce the above copyright 9 // notice, this list of conditions and the following disclaimer in the 10 // documentation and/or other materials provided with the distribution. 11 // 12 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 13 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 16 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 18 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 19 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 20 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 21 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 22 // SUCH DAMAGE. 23 // 24 // This file is automatically generated. Do not edit. 25 // 26 // Source: https://github.com/NuxiNL/cloudabi 27 28 // Appease Rust's tidy. 29 // ignore-license 30 // ignore-tidy-linelength 31 32 //! **PLEASE NOTE: This entire crate including this 33 //! documentation is automatically generated from 34 //! [`cloudabi.txt`](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt)** 35 //! 36 //! # Nuxi CloudABI 37 //! 38 //! CloudABI is what you get if you take POSIX, add capability-based 39 //! security, and remove everything that's incompatible with that. The 40 //! result is a minimal ABI consisting of only 49 syscalls. 41 //! 42 //! CloudABI doesn't have its own kernel, but instead is implemented in existing 43 //! kernels: FreeBSD has CloudABI support for x86-64 and arm64, and [a patch-set 44 //! for NetBSD](https://github.com/NuxiNL/netbsd) and [a patch-set for 45 //! Linux](https://github.com/NuxiNL/linux) are available as well. This means that 46 //! CloudABI binaries can be executed on different operating systems, without any 47 //! modification. 48 //! 49 //! ## Capability-Based Security 50 //! 51 //! Capability-based security means that processes can only perform 52 //! actions that have no global impact. Processes cannot open files by 53 //! their absolute path, cannot open network connections, and cannot 54 //! observe global system state such as the process table. 55 //! 56 //! The capabilities of a process are fully determined by its set of open 57 //! file descriptors (fds). For example, files can only be opened if the 58 //! process already has a file descriptor to a directory the file is in. 59 //! 60 //! Unlike in POSIX, where processes are normally started with file 61 //! descriptors 0, 1, and 2 reserved for standard input, output, and 62 //! error, CloudABI does not reserve any file descriptor numbers for 63 //! specific purposes. 64 //! 65 //! In CloudABI, a process depends on its parent process to launch it with 66 //! the right set of resources, since the process will not be able to open 67 //! any new resources. For example, a simple static web server would need 68 //! to be started with a file descriptor to a [TCP 69 //! listener](https://github.com/NuxiNL/flower), and a file descriptor to 70 //! the directory for which to serve files. The web server will then be 71 //! unable to do anything other than reading files in that directory, and 72 //! process incoming network connections. 73 //! 74 //! So, unknown CloudABI binaries can safely be executed without the need 75 //! for containers, virtual machines, or other sandboxing technologies. 76 //! 77 //! Watch [Ed Schouten's Talk at 78 //! 32C3](https://www.youtube.com/watch?v=3N29vrPoDv8) for more 79 //! information about what capability-based security for UNIX means. 80 //! 81 //! ## Cloudlibc 82 //! 83 //! [Cloudlibc](https://github.com/NuxiNL/cloudlibc) is an implementation 84 //! of the C standard library, without all CloudABI-incompatible 85 //! functions. For example, Cloudlibc does not have `printf`, but does 86 //! have `fprintf`. It does not have `open`, but does have `openat`. 87 //! 88 //! ## CloudABI-Ports 89 //! 90 //! [CloudABI-Ports](https://github.com/NuxiNL/cloudabi-ports) is a 91 //! collection of ports of commonly used libraries and applications to 92 //! CloudABI. It contains software such as `zlib`, `libpng`, `boost`, 93 //! `memcached`, and much more. The software is patched to not depend on 94 //! any global state, such as files in `/etc` or `/dev`, using `open()`, 95 //! etc. 96 //! 97 //! ## Using CloudABI 98 //! 99 //! Instructions for using CloudABI (including kernel modules/patches, 100 //! toolchain, and ports) are available for several operating systems: 101 //! 102 //! - [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/) 107 //! 108 //! ## Specification of the ABI 109 //! 110 //! The entire ABI is specified in a a file called 111 //! [`cloudabi.txt`](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt), 112 //! from which all 113 //! [headers](https://github.com/NuxiNL/cloudabi/tree/master/headers) 114 //! and documentation (including the one you're reading now) is generated. 115 116 #![no_std] 117 #![allow(non_camel_case_types)] 118 119 include!("bitflags.rs"); 120 121 /// File or memory access pattern advisory information. 122 #[repr(u8)] 123 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 124 pub enum advice { 125 /// The application expects that it will not access the 126 /// specified data in the near future. 127 DONTNEED = 1, 128 /// The application expects to access the specified data 129 /// once and then not reuse it thereafter. 130 NOREUSE = 2, 131 /// The application has no advice to give on its behavior 132 /// with respect to the specified data. 133 NORMAL = 3, 134 /// The application expects to access the specified data 135 /// in a random order. 136 RANDOM = 4, 137 /// The application expects to access the specified data 138 /// sequentially from lower offsets to higher offsets. 139 SEQUENTIAL = 5, 140 /// The application expects to access the specified data 141 /// in the near future. 142 WILLNEED = 6, 143 #[doc(hidden)] _NonExhaustive = -1 as isize as u8, 144 } 145 146 /// Enumeration describing the kind of value stored in [`auxv`](struct.auxv.html). 147 #[repr(u32)] 148 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 149 pub enum auxtype { 150 /// Base address of the binary argument data provided to 151 /// [`proc_exec()`](fn.proc_exec.html). 152 ARGDATA = 256, 153 /// Length of the binary argument data provided to 154 /// [`proc_exec()`](fn.proc_exec.html). 155 ARGDATALEN = 257, 156 /// Base address at which the executable is placed in 157 /// memory. 158 BASE = 7, 159 /// Base address of a buffer of random data that may be 160 /// used for non-cryptographic purposes, for example as a 161 /// canary for stack smashing protection. 162 CANARY = 258, 163 /// Length of a buffer of random data that may be used 164 /// for non-cryptographic purposes, for example as a 165 /// canary for stack smashing protection. 166 CANARYLEN = 259, 167 /// Number of CPUs that the system this process is running 168 /// on has. 169 NCPUS = 260, 170 /// Terminator of the auxiliary vector. 171 NULL = 0, 172 /// Smallest memory object size for which individual 173 /// memory protection controls can be configured. 174 PAGESZ = 6, 175 /// Address of the first ELF program header of the 176 /// executable. 177 PHDR = 3, 178 /// Number of ELF program headers of the executable. 179 PHNUM = 4, 180 /// Identifier of the process. 181 /// 182 /// This environment does not provide any simple numerical 183 /// process identifiers, for the reason that these are not 184 /// useful in distributed contexts. Instead, processes are 185 /// identified by a UUID. 186 /// 187 /// This record should point to sixteen bytes of binary 188 /// data, containing a version 4 UUID (fully random). 189 PID = 263, 190 /// Address of the ELF header of the vDSO. 191 /// 192 /// The vDSO is a shared library that is mapped in the 193 /// address space of the process. It provides entry points 194 /// for every system call supported by the environment, 195 /// all having a corresponding symbol that is prefixed 196 /// with `cloudabi_sys_`. System calls should be invoked 197 /// through these entry points. 198 /// 199 /// The first advantage of letting processes call into a 200 /// vDSO to perform system calls instead of raising 201 /// hardware traps is that it allows for easy emulation of 202 /// executables on top of existing operating systems. The 203 /// second advantage is that in cases where an operating 204 /// system provides native support for CloudABI executables, 205 /// it may still implement partial userspace 206 /// implementations of these system calls to improve 207 /// performance (e.g., [`clock_time_get()`](fn.clock_time_get.html)). It also provides 208 /// a more dynamic way of adding, removing or replacing 209 /// system calls. 210 SYSINFO_EHDR = 262, 211 /// Thread ID of the initial thread of the process. 212 TID = 261, 213 #[doc(hidden)] _NonExhaustive = -1 as isize as u32, 214 } 215 216 /// Identifiers for clocks. 217 #[repr(u32)] 218 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 219 pub enum clockid { 220 /// The system-wide monotonic clock, which is defined as a 221 /// clock measuring real time, whose value cannot be 222 /// adjusted and which cannot have negative clock jumps. 223 /// 224 /// The epoch of this clock is undefined. The absolute 225 /// time value of this clock therefore has no meaning. 226 MONOTONIC = 1, 227 /// The CPU-time clock associated with the current 228 /// process. 229 PROCESS_CPUTIME_ID = 2, 230 /// The system-wide clock measuring real time. Time value 231 /// zero corresponds with 1970-01-01T00:00:00Z. 232 REALTIME = 3, 233 /// The CPU-time clock associated with the current thread. 234 THREAD_CPUTIME_ID = 4, 235 #[doc(hidden)] _NonExhaustive = -1 as isize as u32, 236 } 237 238 /// A userspace condition variable. 239 #[repr(C)] 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); 247 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 250 /// local system. 251 #[repr(C)] 252 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 253 pub struct device(pub u64); 254 255 /// A reference to the offset of a directory entry. 256 #[repr(C)] 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); 262 263 /// Error codes returned by system calls. 264 /// 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. 268 #[repr(u16)] 269 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 270 pub enum errno { 271 /// No error occurred. System call completed successfully. 272 SUCCESS = 0, 273 /// Argument list too long. 274 TOOBIG = 1, 275 /// Permission denied. 276 ACCES = 2, 277 /// Address in use. 278 ADDRINUSE = 3, 279 /// Address not available. 280 ADDRNOTAVAIL = 4, 281 /// Address family not supported. 282 AFNOSUPPORT = 5, 283 /// Resource unavailable, or operation would block. 284 AGAIN = 6, 285 /// Connection already in progress. 286 ALREADY = 7, 287 /// Bad file descriptor. 288 BADF = 8, 289 /// Bad message. 290 BADMSG = 9, 291 /// Device or resource busy. 292 BUSY = 10, 293 /// Operation canceled. 294 CANCELED = 11, 295 /// No child processes. 296 CHILD = 12, 297 /// Connection aborted. 298 CONNABORTED = 13, 299 /// Connection refused. 300 CONNREFUSED = 14, 301 /// Connection reset. 302 CONNRESET = 15, 303 /// Resource deadlock would occur. 304 DEADLK = 16, 305 /// Destination address required. 306 DESTADDRREQ = 17, 307 /// Mathematics argument out of domain of function. 308 DOM = 18, 309 /// Reserved. 310 DQUOT = 19, 311 /// File exists. 312 EXIST = 20, 313 /// Bad address. 314 FAULT = 21, 315 /// File too large. 316 FBIG = 22, 317 /// Host is unreachable. 318 HOSTUNREACH = 23, 319 /// Identifier removed. 320 IDRM = 24, 321 /// Illegal byte sequence. 322 ILSEQ = 25, 323 /// Operation in progress. 324 INPROGRESS = 26, 325 /// Interrupted function. 326 INTR = 27, 327 /// Invalid argument. 328 INVAL = 28, 329 /// I/O error. 330 IO = 29, 331 /// Socket is connected. 332 ISCONN = 30, 333 /// Is a directory. 334 ISDIR = 31, 335 /// Too many levels of symbolic links. 336 LOOP = 32, 337 /// File descriptor value too large. 338 MFILE = 33, 339 /// Too many links. 340 MLINK = 34, 341 /// Message too large. 342 MSGSIZE = 35, 343 /// Reserved. 344 MULTIHOP = 36, 345 /// Filename too long. 346 NAMETOOLONG = 37, 347 /// Network is down. 348 NETDOWN = 38, 349 /// Connection aborted by network. 350 NETRESET = 39, 351 /// Network unreachable. 352 NETUNREACH = 40, 353 /// Too many files open in system. 354 NFILE = 41, 355 /// No buffer space available. 356 NOBUFS = 42, 357 /// No such device. 358 NODEV = 43, 359 /// No such file or directory. 360 NOENT = 44, 361 /// Executable file format error. 362 NOEXEC = 45, 363 /// No locks available. 364 NOLCK = 46, 365 /// Reserved. 366 NOLINK = 47, 367 /// Not enough space. 368 NOMEM = 48, 369 /// No message of the desired type. 370 NOMSG = 49, 371 /// Protocol not available. 372 NOPROTOOPT = 50, 373 /// No space left on device. 374 NOSPC = 51, 375 /// Function not supported. 376 NOSYS = 52, 377 /// The socket is not connected. 378 NOTCONN = 53, 379 /// Not a directory or a symbolic link to a directory. 380 NOTDIR = 54, 381 /// Directory not empty. 382 NOTEMPTY = 55, 383 /// State not recoverable. 384 NOTRECOVERABLE = 56, 385 /// Not a socket. 386 NOTSOCK = 57, 387 /// Not supported, or operation not supported on socket. 388 NOTSUP = 58, 389 /// Inappropriate I/O control operation. 390 NOTTY = 59, 391 /// No such device or address. 392 NXIO = 60, 393 /// Value too large to be stored in data type. 394 OVERFLOW = 61, 395 /// Previous owner died. 396 OWNERDEAD = 62, 397 /// Operation not permitted. 398 PERM = 63, 399 /// Broken pipe. 400 PIPE = 64, 401 /// Protocol error. 402 PROTO = 65, 403 /// Protocol not supported. 404 PROTONOSUPPORT = 66, 405 /// Protocol wrong type for socket. 406 PROTOTYPE = 67, 407 /// Result too large. 408 RANGE = 68, 409 /// Read-only file system. 410 ROFS = 69, 411 /// Invalid seek. 412 SPIPE = 70, 413 /// No such process. 414 SRCH = 71, 415 /// Reserved. 416 STALE = 72, 417 /// Connection timed out. 418 TIMEDOUT = 73, 419 /// Text file busy. 420 TXTBSY = 74, 421 /// Cross-device link. 422 XDEV = 75, 423 /// Extension: Capabilities insufficient. 424 NOTCAPABLE = 76, 425 #[doc(hidden)] _NonExhaustive = -1 as isize as u16, 426 } 427 428 bitflags! { 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). 431 #[repr(C)] 432 pub struct eventrwflags: u16 { 433 /// The peer of this socket has closed or disconnected. 434 const HANGUP = 0x0001; 435 } 436 } 437 438 /// Type of a subscription to an event or its occurrence. 439 #[repr(u8)] 440 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 441 pub enum eventtype { 442 /// The time value of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id) 443 /// has reached timestamp [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout). 444 CLOCK = 1, 445 /// Condition variable [`subscription.union.condvar.condvar`](struct.subscription_condvar.html#structfield.condvar) has 446 /// been woken up and [`subscription.union.condvar.lock`](struct.subscription_condvar.html#structfield.lock) has been 447 /// acquired for writing. 448 CONDVAR = 2, 449 /// File descriptor [`subscription.union.fd_readwrite.fd`](struct.subscription_fd_readwrite.html#structfield.fd) has 450 /// data available for reading. This event always triggers 451 /// for regular files. 452 FD_READ = 3, 453 /// File descriptor [`subscription.union.fd_readwrite.fd`](struct.subscription_fd_readwrite.html#structfield.fd) has 454 /// capacity available for writing. This event always 455 /// triggers for regular files. 456 FD_WRITE = 4, 457 /// Lock [`subscription.union.lock.lock`](struct.subscription_lock.html#structfield.lock) has been acquired for 458 /// reading. 459 LOCK_RDLOCK = 5, 460 /// Lock [`subscription.union.lock.lock`](struct.subscription_lock.html#structfield.lock) has been acquired for 461 /// writing. 462 LOCK_WRLOCK = 6, 463 /// The process associated with process descriptor 464 /// [`subscription.union.proc_terminate.fd`](struct.subscription_proc_terminate.html#structfield.fd) has terminated. 465 PROC_TERMINATE = 7, 466 #[doc(hidden)] _NonExhaustive = -1 as isize as u8, 467 } 468 469 /// Exit code generated by a process when exiting. 470 pub type exitcode = u32; 471 472 /// A file descriptor number. 473 /// 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. 478 #[repr(C)] 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); 486 487 bitflags! { 488 /// File descriptor flags. 489 #[repr(C)] 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 496 /// synchronized. 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. 506 const SYNC = 0x0010; 507 } 508 } 509 510 bitflags! { 511 /// Which file descriptor attributes to adjust. 512 #[repr(C)] 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; 521 } 522 } 523 524 /// Relative offset within a file. 525 pub type filedelta = i64; 526 527 /// Non-negative file size or length of a region within a file. 528 pub type filesize = u64; 529 530 /// The type of a file descriptor or file. 531 #[repr(u8)] 532 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 533 pub enum filetype { 534 /// The type of the file descriptor or file is unknown or 535 /// is different from any of the other types specified. 536 UNKNOWN = 0, 537 /// The file descriptor or file refers to a block device 538 /// inode. 539 BLOCK_DEVICE = 16, 540 /// The file descriptor or file refers to a character 541 /// device inode. 542 CHARACTER_DEVICE = 17, 543 /// The file descriptor or file refers to a directory 544 /// inode. 545 DIRECTORY = 32, 546 /// The file descriptor refers to a process handle. 547 PROCESS = 80, 548 /// The file descriptor or file refers to a regular file 549 /// inode. 550 REGULAR_FILE = 96, 551 /// The file descriptor refers to a shared memory object. 552 SHARED_MEMORY = 112, 553 /// The file descriptor or file refers to a datagram 554 /// socket. 555 SOCKET_DGRAM = 128, 556 /// The file descriptor or file refers to a byte-stream 557 /// socket. 558 SOCKET_STREAM = 130, 559 /// The file refers to a symbolic link inode. 560 SYMBOLIC_LINK = 144, 561 #[doc(hidden)] _NonExhaustive = -1 as isize as u8, 562 } 563 564 bitflags! { 565 /// Which file attributes to adjust. 566 #[repr(C)] 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). 570 const ATIM = 0x0001; 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). 576 const MTIM = 0x0004; 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). 582 const SIZE = 0x0010; 583 } 584 } 585 586 /// File serial number that is unique within its file system. 587 #[repr(C)] 588 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 589 pub struct inode(pub u64); 590 591 /// Number of hard links to an inode. 592 pub type linkcount = u32; 593 594 /// A userspace read-recursive readers-writer lock, similar to a 595 /// Linux futex or a FreeBSD umtx. 596 #[repr(C)] 597 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 598 pub struct lock(pub u32); 599 /// Value indicating that the lock is in its initial 600 /// unlocked state. 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. 613 /// 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); 626 627 bitflags! { 628 /// Flags determining the method of how paths are resolved. 629 #[repr(C)] 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; 634 } 635 } 636 637 bitflags! { 638 /// Memory mapping flags. 639 #[repr(C)] 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. 645 const ANON = 0x01; 646 /// Require that the mapping is performed at the base 647 /// address provided. 648 const FIXED = 0x02; 649 /// Changes are private. 650 const PRIVATE = 0x04; 651 /// Changes are shared. 652 const SHARED = 0x08; 653 } 654 } 655 656 bitflags! { 657 /// Memory page protection options. 658 /// 659 /// This implementation enforces the `W^X` property: Pages cannot be 660 /// mapped for execution while also mapped for writing. 661 #[repr(C)] 662 pub struct mprot: u8 { 663 /// Page can be executed. 664 const EXEC = 0x01; 665 /// Page can be written. 666 const WRITE = 0x02; 667 /// Page can be read. 668 const READ = 0x04; 669 } 670 } 671 672 bitflags! { 673 /// Methods of synchronizing memory with physical storage. 674 #[repr(C)] 675 pub struct msflags: u8 { 676 /// Perform asynchronous writes. 677 const ASYNC = 0x01; 678 /// Invalidate cached data. 679 const INVALIDATE = 0x02; 680 /// Perform synchronous writes. 681 const SYNC = 0x04; 682 } 683 } 684 685 /// Specifies the number of threads sleeping on a condition 686 /// variable that should be woken up. 687 pub type nthreads = u32; 688 689 bitflags! { 690 /// Open flags used by [`file_open()`](fn.file_open.html). 691 #[repr(C)] 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. 698 const EXCL = 0x0004; 699 /// Truncate file to size 0. 700 const TRUNC = 0x0008; 701 } 702 } 703 704 bitflags! { 705 /// Flags provided to [`sock_recv()`](fn.sock_recv.html). 706 #[repr(C)] 707 pub struct riflags: u16 { 708 /// Returns the message without removing it from the 709 /// socket's receive queue. 710 const PEEK = 0x0004; 711 /// On byte-stream sockets, block until the full amount 712 /// of data can be returned. 713 const WAITALL = 0x0010; 714 } 715 } 716 717 bitflags! { 718 /// File descriptor rights, determining which actions may be 719 /// performed. 720 #[repr(C)] 721 pub struct rights: u64 { 722 /// The right to invoke [`fd_datasync()`](fn.fd_datasync.html). 723 /// 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). 728 /// 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). 732 /// 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). 743 /// 744 /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to 745 /// invoke [`file_open()`](fn.file_open.html) with [`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 750 /// offset zero). 751 const FD_TELL = 0x0000000000000020; 752 /// The right to invoke [`fd_write()`](fn.fd_write.html) and [`sock_send()`](fn.sock_send.html). 753 /// 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). 757 /// 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). 793 /// 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 812 /// zero. 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). 819 /// 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; 830 } 831 } 832 833 bitflags! { 834 /// Flags returned by [`sock_recv()`](fn.sock_recv.html). 835 #[repr(C)] 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 841 /// truncated. 842 const DATA_TRUNCATED = 0x0008; 843 } 844 } 845 846 /// Indicates whether an object is stored in private or shared 847 /// memory. 848 #[repr(u8)] 849 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 850 pub enum scope { 851 /// The object is stored in private memory. 852 PRIVATE = 4, 853 /// The object is stored in shared memory. 854 SHARED = 8, 855 #[doc(hidden)] _NonExhaustive = -1 as isize as u8, 856 } 857 858 bitflags! { 859 /// Which channels on a socket need to be shut down. 860 #[repr(C)] 861 pub struct sdflags: u8 { 862 /// Disables further receive operations. 863 const RD = 0x01; 864 /// Disables further send operations. 865 const WR = 0x02; 866 } 867 } 868 869 bitflags! { 870 /// Flags provided to [`sock_send()`](fn.sock_send.html). As there are currently no flags 871 /// defined, it must be set to zero. 872 #[repr(C)] 873 pub struct siflags: u16 { 874 const DEFAULT = 0; 875 } 876 } 877 878 /// Signal condition. 879 #[repr(u8)] 880 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 881 pub enum signal { 882 /// Process abort signal. 883 /// 884 /// Action: Terminates the process. 885 ABRT = 1, 886 /// Alarm clock. 887 /// 888 /// Action: Terminates the process. 889 ALRM = 2, 890 /// Access to an undefined portion of a memory object. 891 /// 892 /// Action: Terminates the process. 893 BUS = 3, 894 /// Child process terminated, stopped, or continued. 895 /// 896 /// Action: Ignored. 897 CHLD = 4, 898 /// Continue executing, if stopped. 899 /// 900 /// Action: Continues executing, if stopped. 901 CONT = 5, 902 /// Erroneous arithmetic operation. 903 /// 904 /// Action: Terminates the process. 905 FPE = 6, 906 /// Hangup. 907 /// 908 /// Action: Terminates the process. 909 HUP = 7, 910 /// Illegal instruction. 911 /// 912 /// Action: Terminates the process. 913 ILL = 8, 914 /// Terminate interrupt signal. 915 /// 916 /// Action: Terminates the process. 917 INT = 9, 918 /// Kill. 919 /// 920 /// Action: Terminates the process. 921 KILL = 10, 922 /// Write on a pipe with no one to read it. 923 /// 924 /// Action: Ignored. 925 PIPE = 11, 926 /// Terminal quit signal. 927 /// 928 /// Action: Terminates the process. 929 QUIT = 12, 930 /// Invalid memory reference. 931 /// 932 /// Action: Terminates the process. 933 SEGV = 13, 934 /// Stop executing. 935 /// 936 /// Action: Stops executing. 937 STOP = 14, 938 /// Bad system call. 939 /// 940 /// Action: Terminates the process. 941 SYS = 15, 942 /// Termination signal. 943 /// 944 /// Action: Terminates the process. 945 TERM = 16, 946 /// Trace/breakpoint trap. 947 /// 948 /// Action: Terminates the process. 949 TRAP = 17, 950 /// Terminal stop signal. 951 /// 952 /// Action: Stops executing. 953 TSTP = 18, 954 /// Background process attempting read. 955 /// 956 /// Action: Stops executing. 957 TTIN = 19, 958 /// Background process attempting write. 959 /// 960 /// Action: Stops executing. 961 TTOU = 20, 962 /// High bandwidth data is available at a socket. 963 /// 964 /// Action: Ignored. 965 URG = 21, 966 /// User-defined signal 1. 967 /// 968 /// Action: Terminates the process. 969 USR1 = 22, 970 /// User-defined signal 2. 971 /// 972 /// Action: Terminates the process. 973 USR2 = 23, 974 /// Virtual timer expired. 975 /// 976 /// Action: Terminates the process. 977 VTALRM = 24, 978 /// CPU time limit exceeded. 979 /// 980 /// Action: Terminates the process. 981 XCPU = 25, 982 /// File size limit exceeded. 983 /// 984 /// Action: Terminates the process. 985 XFSZ = 26, 986 #[doc(hidden)] _NonExhaustive = -1 as isize as u8, 987 } 988 989 bitflags! { 990 /// Flags determining how the timestamp provided in 991 /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) should be interpreted. 992 #[repr(C)] 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). 997 /// 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; 1002 } 1003 } 1004 1005 bitflags! { 1006 /// Flags influencing the method of polling for read or writing on 1007 /// a file descriptor. 1008 #[repr(C)] 1009 pub struct subrwflags: u16 { 1010 /// Deprecated. Must be set by callers and ignored by 1011 /// implementations. 1012 const POLL = 0x0001; 1013 } 1014 } 1015 1016 /// Unique system-local identifier of a thread. This identifier is 1017 /// only valid during the lifetime of the thread. 1018 /// 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. 1022 /// 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. 1026 #[repr(C)] 1027 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 1028 pub struct tid(pub u32); 1029 1030 /// Timestamp in nanoseconds. 1031 pub type timestamp = u64; 1032 1033 bitflags! { 1034 /// Specifies whether files are unlinked or directories are 1035 /// removed. 1036 #[repr(C)] 1037 pub struct ulflags: u8 { 1038 /// If set, removes a directory. Otherwise, unlinks any 1039 /// non-directory file. 1040 const REMOVEDIR = 0x01; 1041 } 1042 } 1043 1044 /// User-provided value that can be attached to objects that is 1045 /// retained when extracted from the kernel. 1046 pub type userdata = u64; 1047 1048 /// Relative to which position the offset of the file descriptor 1049 /// should be set. 1050 #[repr(u8)] 1051 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] 1052 pub enum whence { 1053 /// Seek relative to current position. 1054 CUR = 1, 1055 /// Seek relative to end-of-file. 1056 END = 2, 1057 /// Seek relative to start-of-file. 1058 SET = 3, 1059 #[doc(hidden)] _NonExhaustive = -1 as isize as u8, 1060 } 1061 1062 /// Auxiliary vector entry. 1063 /// 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). 1069 /// 1070 /// The auxiliary vector is part of the x86-64 ABI, but is used by 1071 /// this environment on all architectures. 1072 #[repr(C)] 1073 #[derive(Copy, Clone)] 1074 pub struct auxv { 1075 /// The type of the auxiliary vector entry. 1076 pub a_type: auxtype, 1077 pub union: auxv_union 1078 } 1079 /// A union inside `auxv`. 1080 #[repr(C)] 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. 1085 pub a_val: usize, 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. 1088 pub a_ptr: *mut (), 1089 } 1090 #[test] 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); 1095 unsafe { 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); 1101 } 1102 } 1103 #[test] 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); 1108 unsafe { 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); 1114 } 1115 } 1116 1117 /// A region of memory for scatter/gather writes. 1118 #[repr(C)] 1119 #[derive(Copy, Clone)] 1120 pub struct ciovec { 1121 /// The address and length of the buffer to be written. 1122 pub buf: (*const (), usize), 1123 } 1124 #[test] 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); 1129 unsafe { 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); 1134 } 1135 } 1136 #[test] 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); 1141 unsafe { 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); 1146 } 1147 } 1148 1149 /// A directory entry. 1150 #[repr(C)] 1151 #[derive(Copy, Clone)] 1152 pub struct dirent { 1153 /// The offset of the next directory entry stored in this 1154 /// directory. 1155 pub d_next: dircookie, 1156 /// The serial number of the file referred to by this 1157 /// directory entry. 1158 pub d_ino: inode, 1159 /// The length of the name of the directory entry. 1160 pub d_namlen: u32, 1161 /// The type of the file referred to by this directory 1162 /// entry. 1163 pub d_type: filetype, 1164 } 1165 #[test] 1166 fn dirent_layout_test() { 1167 assert_eq!(::core::mem::size_of::<dirent>(), 24); 1168 assert_eq!(::core::mem::align_of::<dirent>(), 8); 1169 unsafe { 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); 1176 } 1177 } 1178 1179 /// An event that occurred. 1180 #[repr(C)] 1181 #[derive(Copy, Clone)] 1182 pub struct event { 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. 1188 pub error: errno, 1189 /// The type of the event that occurred. 1190 pub type_: eventtype, 1191 pub union: event_union 1192 } 1193 /// A union inside `event`. 1194 #[repr(C)] 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, 1201 } 1202 #[repr(C)] 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, 1208 /// Obsolete. 1209 pub unused: [u8; 4], 1210 /// The state of the file 1211 /// descriptor. 1212 pub flags: eventrwflags, 1213 } 1214 #[repr(C)] 1215 #[derive(Copy, Clone)] 1216 pub struct event_proc_terminate { 1217 /// Obsolete. 1218 pub unused: [u8; 4], 1219 /// If zero, the process has 1220 /// exited. 1221 /// Otherwise, the signal 1222 /// condition causing it to 1223 /// terminated. 1224 pub signal: signal, 1225 /// If exited, the exit code of 1226 /// the process. 1227 pub exitcode: exitcode, 1228 } 1229 #[test] 1230 fn event_layout_test() { 1231 assert_eq!(::core::mem::size_of::<event>(), 32); 1232 assert_eq!(::core::mem::align_of::<event>(), 8); 1233 unsafe { 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); 1245 } 1246 } 1247 1248 /// File descriptor attributes. 1249 #[repr(C)] 1250 #[derive(Copy, Clone)] 1251 pub struct fdstat { 1252 /// File type. 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, 1262 } 1263 #[test] 1264 fn fdstat_layout_test() { 1265 assert_eq!(::core::mem::size_of::<fdstat>(), 24); 1266 assert_eq!(::core::mem::align_of::<fdstat>(), 8); 1267 unsafe { 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); 1274 } 1275 } 1276 1277 /// File attributes. 1278 #[repr(C)] 1279 #[derive(Copy, Clone)] 1280 pub struct filestat { 1281 /// Device ID of device containing the file. 1282 pub st_dev: device, 1283 /// File serial number. 1284 pub st_ino: inode, 1285 /// File type. 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, 1299 } 1300 #[test] 1301 fn filestat_layout_test() { 1302 assert_eq!(::core::mem::size_of::<filestat>(), 56); 1303 assert_eq!(::core::mem::align_of::<filestat>(), 8); 1304 unsafe { 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); 1315 } 1316 } 1317 1318 /// A region of memory for scatter/gather reads. 1319 #[repr(C)] 1320 #[derive(Copy, Clone)] 1321 pub struct iovec { 1322 /// The address and length of the buffer to be filled. 1323 pub buf: (*mut (), usize), 1324 } 1325 #[test] 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); 1330 unsafe { 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); 1335 } 1336 } 1337 #[test] 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); 1342 unsafe { 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); 1347 } 1348 } 1349 1350 /// Path lookup properties. 1351 #[repr(C)] 1352 #[derive(Copy, Clone)] 1353 pub struct lookup { 1354 /// The working directory at which the resolution of the 1355 /// path starts. 1356 pub fd: fd, 1357 /// Flags determining the method of how the path is 1358 /// resolved. 1359 pub flags: lookupflags, 1360 } 1361 #[test] 1362 fn lookup_layout_test() { 1363 assert_eq!(::core::mem::size_of::<lookup>(), 8); 1364 assert_eq!(::core::mem::align_of::<lookup>(), 4); 1365 unsafe { 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); 1370 } 1371 } 1372 1373 /// Entry point for a process (`_start`). 1374 /// 1375 /// **auxv**: 1376 /// The auxiliary vector. See [`auxv`](struct.auxv.html). 1377 pub type processentry = unsafe extern "C" fn( 1378 auxv: *const auxv, 1379 ) -> (); 1380 1381 /// Arguments of [`sock_recv()`](fn.sock_recv.html). 1382 #[repr(C)] 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), 1391 /// Message flags. 1392 pub ri_flags: riflags, 1393 } 1394 #[test] 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); 1399 unsafe { 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); 1407 } 1408 } 1409 #[test] 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); 1414 unsafe { 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); 1422 } 1423 } 1424 1425 /// Results of [`sock_recv()`](fn.sock_recv.html). 1426 #[repr(C)] 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], 1435 /// Message flags. 1436 pub ro_flags: roflags, 1437 } 1438 #[test] 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); 1443 unsafe { 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); 1450 } 1451 } 1452 #[test] 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); 1457 unsafe { 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); 1464 } 1465 } 1466 1467 /// Arguments of [`sock_send()`](fn.sock_send.html). 1468 #[repr(C)] 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 1475 /// message. 1476 pub si_fds: (*const fd, usize), 1477 /// Message flags. 1478 pub si_flags: siflags, 1479 } 1480 #[test] 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); 1485 unsafe { 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); 1493 } 1494 } 1495 #[test] 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); 1500 unsafe { 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); 1508 } 1509 } 1510 1511 /// Results of [`sock_send()`](fn.sock_send.html). 1512 #[repr(C)] 1513 #[derive(Copy, Clone)] 1514 pub struct send_out { 1515 /// Number of bytes transmitted. 1516 pub so_datalen: usize, 1517 } 1518 #[test] 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); 1523 unsafe { 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); 1527 } 1528 } 1529 #[test] 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); 1534 unsafe { 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); 1538 } 1539 } 1540 1541 /// Subscription to an event. 1542 #[repr(C)] 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. 1550 pub unused: u16, 1551 /// The type of the event to which to subscribe. 1552 /// 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 1560 } 1561 /// A union inside `subscription`. 1562 #[repr(C)] 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, 1575 } 1576 #[repr(C)] 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 1586 /// timestamp. 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 1594 /// relative. 1595 pub flags: subclockflags, 1596 } 1597 #[repr(C)] 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. 1605 /// 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 1612 /// memory. 1613 pub condvar_scope: scope, 1614 /// Whether the lock is stored in 1615 /// private or shared memory. 1616 pub lock_scope: scope, 1617 } 1618 #[repr(C)] 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. 1624 pub fd: fd, 1625 /// Under which conditions to 1626 /// trigger. 1627 pub flags: subrwflags, 1628 } 1629 #[repr(C)] 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, 1638 } 1639 #[repr(C)] 1640 #[derive(Copy, Clone)] 1641 pub struct subscription_proc_terminate { 1642 /// The process descriptor on 1643 /// which to wait for process 1644 /// termination. 1645 pub fd: fd, 1646 } 1647 #[test] 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); 1652 unsafe { 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); 1672 } 1673 } 1674 #[test] 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); 1679 unsafe { 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); 1699 } 1700 } 1701 1702 /// The Thread Control Block (TCB). 1703 /// 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 1708 /// TCB. 1709 /// 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 1714 /// TLS area. 1715 /// 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. 1721 #[repr(C)] 1722 #[derive(Copy, Clone)] 1723 pub struct tcb { 1724 /// Pointer that may be freely assigned by the system. Its 1725 /// value cannot be interpreted by the application. 1726 pub parent: *mut (), 1727 } 1728 #[test] 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); 1733 unsafe { 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); 1737 } 1738 } 1739 #[test] 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); 1744 unsafe { 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); 1748 } 1749 } 1750 1751 /// Entry point for additionally created threads. 1752 /// 1753 /// **tid**: 1754 /// Thread ID of the current thread. 1755 /// 1756 /// **aux**: 1757 /// Copy of the value stored in 1758 /// [`threadattr.argument`](struct.threadattr.html#structfield.argument). 1759 pub type threadentry = unsafe extern "C" fn( 1760 tid: tid, 1761 aux: *mut (), 1762 ) -> (); 1763 1764 /// Attributes for thread creation. 1765 #[repr(C)] 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 (), 1774 } 1775 #[test] 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); 1780 unsafe { 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); 1787 } 1788 } 1789 #[test] 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); 1794 unsafe { 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); 1801 } 1802 } 1803 1804 /// The table with pointers to all syscall implementations. 1805 #[allow(improper_ctypes)] 1806 extern "C" { 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; 1856 } 1857 1858 /// Obtains the resolution of a clock. 1859 /// 1860 /// ## Parameters 1861 /// 1862 /// **clock_id**: 1863 /// The clock for which the resolution needs to be 1864 /// returned. 1865 /// 1866 /// **resolution**: 1867 /// The resolution of the clock. 1868 #[inline] 1869 pub unsafe fn clock_res_get(clock_id_: clockid, resolution_: &mut timestamp) -> errno { 1870 cloudabi_sys_clock_res_get(clock_id_, resolution_) 1871 } 1872 1873 /// Obtains the time value of a clock. 1874 /// 1875 /// ## Parameters 1876 /// 1877 /// **clock_id**: 1878 /// The clock for which the time needs to be 1879 /// returned. 1880 /// 1881 /// **precision**: 1882 /// The maximum lag (exclusive) that the returned 1883 /// time value may have, compared to its actual 1884 /// value. 1885 /// 1886 /// **time**: 1887 /// The time value of the clock. 1888 #[inline] 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_) 1891 } 1892 1893 /// Wakes up threads waiting on a userspace condition variable. 1894 /// 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 1899 /// system call. 1900 /// 1901 /// ## Parameters 1902 /// 1903 /// **condvar**: 1904 /// The userspace condition variable that has 1905 /// waiting threads. 1906 /// 1907 /// **scope**: 1908 /// Whether the condition variable is stored in 1909 /// private or shared memory. 1910 /// 1911 /// **nwaiters**: 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. 1915 #[inline] 1916 pub unsafe fn condvar_signal(condvar_: *mut condvar, scope_: scope, nwaiters_: nthreads) -> errno { 1917 cloudabi_sys_condvar_signal(condvar_, scope_, nwaiters_) 1918 } 1919 1920 /// Closes a file descriptor. 1921 /// 1922 /// ## Parameters 1923 /// 1924 /// **fd**: 1925 /// The file descriptor that needs to be closed. 1926 #[inline] 1927 pub unsafe fn fd_close(fd_: fd) -> errno { 1928 cloudabi_sys_fd_close(fd_) 1929 } 1930 1931 /// Creates a file descriptor. 1932 /// 1933 /// ## Parameters 1934 /// 1935 /// **type**: 1936 /// Possible values: 1937 /// 1938 /// - [`SHARED_MEMORY`](enum.filetype.html#variant.SHARED_MEMORY): 1939 /// Creates an anonymous shared memory 1940 /// object. 1941 /// 1942 /// **fd**: 1943 /// The file descriptor that has been created. 1944 #[inline] 1945 pub unsafe fn fd_create1(type_: filetype, fd_: &mut fd) -> errno { 1946 cloudabi_sys_fd_create1(type_, fd_) 1947 } 1948 1949 /// Creates a pair of file descriptors. 1950 /// 1951 /// ## Parameters 1952 /// 1953 /// **type**: 1954 /// Possible values: 1955 /// 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 1960 /// pair. 1961 /// 1962 /// **fd1**: 1963 /// The first file descriptor of the pair. 1964 /// 1965 /// **fd2**: 1966 /// The second file descriptor of the pair. 1967 #[inline] 1968 pub unsafe fn fd_create2(type_: filetype, fd1_: &mut fd, fd2_: &mut fd) -> errno { 1969 cloudabi_sys_fd_create2(type_, fd1_, fd2_) 1970 } 1971 1972 /// Synchronizes the data of a file to disk. 1973 /// 1974 /// ## Parameters 1975 /// 1976 /// **fd**: 1977 /// The file descriptor of the file whose data 1978 /// needs to be synchronized to disk. 1979 #[inline] 1980 pub unsafe fn fd_datasync(fd_: fd) -> errno { 1981 cloudabi_sys_fd_datasync(fd_) 1982 } 1983 1984 /// Duplicates a file descriptor. 1985 /// 1986 /// ## Parameters 1987 /// 1988 /// **from**: 1989 /// The file descriptor that needs to be 1990 /// duplicated. 1991 /// 1992 /// **fd**: 1993 /// The new file descriptor. 1994 #[inline] 1995 pub unsafe fn fd_dup(from_: fd, fd_: &mut fd) -> errno { 1996 cloudabi_sys_fd_dup(from_, fd_) 1997 } 1998 1999 /// Reads from a file descriptor, without using and updating the 2000 /// file descriptor's offset. 2001 /// 2002 /// ## Parameters 2003 /// 2004 /// **fd**: 2005 /// The file descriptor from which data should be 2006 /// read. 2007 /// 2008 /// **iovs**: 2009 /// List of scatter/gather vectors where data 2010 /// should be stored. 2011 /// 2012 /// **offset**: 2013 /// The offset within the file at which reading 2014 /// should start. 2015 /// 2016 /// **nread**: 2017 /// The number of bytes read. 2018 #[inline] 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_) 2021 } 2022 2023 /// Writes to a file descriptor, without using and updating the 2024 /// file descriptor's offset. 2025 /// 2026 /// ## Parameters 2027 /// 2028 /// **fd**: 2029 /// The file descriptor to which data should be 2030 /// written. 2031 /// 2032 /// **iovs**: 2033 /// List of scatter/gather vectors where data 2034 /// should be retrieved. 2035 /// 2036 /// **offset**: 2037 /// The offset within the file at which writing 2038 /// should start. 2039 /// 2040 /// **nwritten**: 2041 /// The number of bytes written. 2042 #[inline] 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_) 2045 } 2046 2047 /// Reads from a file descriptor. 2048 /// 2049 /// ## Parameters 2050 /// 2051 /// **fd**: 2052 /// The file descriptor from which data should be 2053 /// read. 2054 /// 2055 /// **iovs**: 2056 /// List of scatter/gather vectors where data 2057 /// should be stored. 2058 /// 2059 /// **nread**: 2060 /// The number of bytes read. 2061 #[inline] 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_) 2064 } 2065 2066 /// Atomically replaces a file descriptor by a copy of another 2067 /// file descriptor. 2068 /// 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. 2074 /// 2075 /// This system call provides a way to atomically replace file 2076 /// descriptors, which would disappear if dup2() were to be 2077 /// removed entirely. 2078 /// 2079 /// ## Parameters 2080 /// 2081 /// **from**: 2082 /// The file descriptor that needs to be copied. 2083 /// 2084 /// **to**: 2085 /// The file descriptor that needs to be 2086 /// overwritten. 2087 #[inline] 2088 pub unsafe fn fd_replace(from_: fd, to_: fd) -> errno { 2089 cloudabi_sys_fd_replace(from_, to_) 2090 } 2091 2092 /// Moves the offset of the file descriptor. 2093 /// 2094 /// ## Parameters 2095 /// 2096 /// **fd**: 2097 /// The file descriptor whose offset has to be 2098 /// moved. 2099 /// 2100 /// **offset**: 2101 /// The number of bytes to move. 2102 /// 2103 /// **whence**: 2104 /// Relative to which position the move should 2105 /// take place. 2106 /// 2107 /// **newoffset**: 2108 /// The new offset of the file descriptor, 2109 /// relative to the start of the file. 2110 #[inline] 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_) 2113 } 2114 2115 /// Gets attributes of a file descriptor. 2116 /// 2117 /// ## Parameters 2118 /// 2119 /// **fd**: 2120 /// The file descriptor whose attributes have to 2121 /// be obtained. 2122 /// 2123 /// **buf**: 2124 /// The buffer where the file descriptor's 2125 /// attributes are stored. 2126 #[inline] 2127 pub unsafe fn fd_stat_get(fd_: fd, buf_: *mut fdstat) -> errno { 2128 cloudabi_sys_fd_stat_get(fd_, buf_) 2129 } 2130 2131 /// Adjusts attributes of a file descriptor. 2132 /// 2133 /// ## Parameters 2134 /// 2135 /// **fd**: 2136 /// The file descriptor whose attributes have to 2137 /// be adjusted. 2138 /// 2139 /// **buf**: 2140 /// The desired values of the file descriptor 2141 /// attributes that are adjusted. 2142 /// 2143 /// **flags**: 2144 /// A bitmask indicating which attributes have to 2145 /// be adjusted. 2146 #[inline] 2147 pub unsafe fn fd_stat_put(fd_: fd, buf_: *const fdstat, flags_: fdsflags) -> errno { 2148 cloudabi_sys_fd_stat_put(fd_, buf_, flags_) 2149 } 2150 2151 /// Synchronizes the data and metadata of a file to disk. 2152 /// 2153 /// ## Parameters 2154 /// 2155 /// **fd**: 2156 /// The file descriptor of the file whose data 2157 /// and metadata needs to be synchronized to disk. 2158 #[inline] 2159 pub unsafe fn fd_sync(fd_: fd) -> errno { 2160 cloudabi_sys_fd_sync(fd_) 2161 } 2162 2163 /// Writes to a file descriptor. 2164 /// 2165 /// ## Parameters 2166 /// 2167 /// **fd**: 2168 /// The file descriptor to which data should be 2169 /// written. 2170 /// 2171 /// **iovs**: 2172 /// List of scatter/gather vectors where data 2173 /// should be retrieved. 2174 /// 2175 /// **nwritten**: 2176 /// The number of bytes written. 2177 #[inline] 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_) 2180 } 2181 2182 /// Provides file advisory information on a file descriptor. 2183 /// 2184 /// ## Parameters 2185 /// 2186 /// **fd**: 2187 /// The file descriptor for which to provide file 2188 /// advisory information. 2189 /// 2190 /// **offset**: 2191 /// The offset within the file to which the 2192 /// advisory applies. 2193 /// 2194 /// **len**: 2195 /// The length of the region to which the advisory 2196 /// applies. 2197 /// 2198 /// **advice**: 2199 /// The advice. 2200 #[inline] 2201 pub unsafe fn file_advise(fd_: fd, offset_: filesize, len_: filesize, advice_: advice) -> errno { 2202 cloudabi_sys_file_advise(fd_, offset_, len_, advice_) 2203 } 2204 2205 /// Forces the allocation of space in a file. 2206 /// 2207 /// ## Parameters 2208 /// 2209 /// **fd**: 2210 /// The file in which the space should be 2211 /// allocated. 2212 /// 2213 /// **offset**: 2214 /// The offset at which the allocation should 2215 /// start. 2216 /// 2217 /// **len**: 2218 /// The length of the area that is allocated. 2219 #[inline] 2220 pub unsafe fn file_allocate(fd_: fd, offset_: filesize, len_: filesize) -> errno { 2221 cloudabi_sys_file_allocate(fd_, offset_, len_) 2222 } 2223 2224 /// Creates a file of a specified type. 2225 /// 2226 /// ## Parameters 2227 /// 2228 /// **fd**: 2229 /// The working directory at which the resolution 2230 /// of the file to be created starts. 2231 /// 2232 /// **path**: 2233 /// The path at which the file should be created. 2234 /// 2235 /// **type**: 2236 /// Possible values: 2237 /// 2238 /// - [`DIRECTORY`](enum.filetype.html#variant.DIRECTORY): 2239 /// Creates a directory. 2240 #[inline] 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_) 2243 } 2244 2245 /// Creates a hard link. 2246 /// 2247 /// ## Parameters 2248 /// 2249 /// **fd1**: 2250 /// The working directory at which the resolution 2251 /// of the source path starts. 2252 /// 2253 /// **path1**: 2254 /// The source path of the file that should be 2255 /// hard linked. 2256 /// 2257 /// **fd2**: 2258 /// The working directory at which the resolution 2259 /// of the destination path starts. 2260 /// 2261 /// **path2**: 2262 /// The destination path at which the hard link 2263 /// should be created. 2264 #[inline] 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()) 2267 } 2268 2269 /// Opens a file. 2270 /// 2271 /// ## Parameters 2272 /// 2273 /// **dirfd**: 2274 /// The working directory at which the resolution 2275 /// of the file to be opened starts. 2276 /// 2277 /// **path**: 2278 /// The path of the file that should be opened. 2279 /// 2280 /// **oflags**: 2281 /// The method at which the file should be opened. 2282 /// 2283 /// **fds**: 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. 2291 /// 2292 /// [`fdstat.fs_flags`](struct.fdstat.html#structfield.fs_flags) specifies the initial flags 2293 /// of the file descriptor. 2294 /// 2295 /// [`fdstat.fs_filetype`](struct.fdstat.html#structfield.fs_filetype) is ignored. 2296 /// 2297 /// **fd**: 2298 /// The file descriptor of the file that has been 2299 /// opened. 2300 #[inline] 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_) 2303 } 2304 2305 /// Reads directory entries from a directory. 2306 /// 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. 2311 /// 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. 2317 /// 2318 /// ## Parameters 2319 /// 2320 /// **fd**: 2321 /// The directory from which to read the directory 2322 /// entries. 2323 /// 2324 /// **buf**: 2325 /// The buffer where directory entries are stored. 2326 /// 2327 /// **cookie**: 2328 /// The location within the directory to start 2329 /// reading. 2330 /// 2331 /// **bufused**: 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. 2335 #[inline] 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_) 2338 } 2339 2340 /// Reads the contents of a symbolic link. 2341 /// 2342 /// ## Parameters 2343 /// 2344 /// **fd**: 2345 /// The working directory at which the resolution 2346 /// of the path of the symbolic starts. 2347 /// 2348 /// **path**: 2349 /// The path of the symbolic link whose contents 2350 /// should be read. 2351 /// 2352 /// **buf**: 2353 /// The buffer where the contents of the symbolic 2354 /// link should be stored. 2355 /// 2356 /// **bufused**: 2357 /// The number of bytes placed in the buffer. 2358 #[inline] 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_) 2361 } 2362 2363 /// Renames a file. 2364 /// 2365 /// ## Parameters 2366 /// 2367 /// **fd1**: 2368 /// The working directory at which the resolution 2369 /// of the source path starts. 2370 /// 2371 /// **path1**: 2372 /// The source path of the file that should be 2373 /// renamed. 2374 /// 2375 /// **fd2**: 2376 /// The working directory at which the resolution 2377 /// of the destination path starts. 2378 /// 2379 /// **path2**: 2380 /// The destination path to which the file should 2381 /// be renamed. 2382 #[inline] 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()) 2385 } 2386 2387 /// Gets attributes of a file by file descriptor. 2388 /// 2389 /// ## Parameters 2390 /// 2391 /// **fd**: 2392 /// The file descriptor whose attributes have to 2393 /// be obtained. 2394 /// 2395 /// **buf**: 2396 /// The buffer where the file's attributes are 2397 /// stored. 2398 #[inline] 2399 pub unsafe fn file_stat_fget(fd_: fd, buf_: *mut filestat) -> errno { 2400 cloudabi_sys_file_stat_fget(fd_, buf_) 2401 } 2402 2403 /// Adjusts attributes of a file by file descriptor. 2404 /// 2405 /// ## Parameters 2406 /// 2407 /// **fd**: 2408 /// The file descriptor whose attributes have to 2409 /// be adjusted. 2410 /// 2411 /// **buf**: 2412 /// The desired values of the file attributes that 2413 /// are adjusted. 2414 /// 2415 /// **flags**: 2416 /// A bitmask indicating which attributes have to 2417 /// be adjusted. 2418 #[inline] 2419 pub unsafe fn file_stat_fput(fd_: fd, buf_: *const filestat, flags_: fsflags) -> errno { 2420 cloudabi_sys_file_stat_fput(fd_, buf_, flags_) 2421 } 2422 2423 /// Gets attributes of a file by path. 2424 /// 2425 /// ## Parameters 2426 /// 2427 /// **fd**: 2428 /// The working directory at which the resolution 2429 /// of the path whose attributes have to be 2430 /// obtained starts. 2431 /// 2432 /// **path**: 2433 /// The path of the file whose attributes have to 2434 /// be obtained. 2435 /// 2436 /// **buf**: 2437 /// The buffer where the file's attributes are 2438 /// stored. 2439 #[inline] 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_) 2442 } 2443 2444 /// Adjusts attributes of a file by path. 2445 /// 2446 /// ## Parameters 2447 /// 2448 /// **fd**: 2449 /// The working directory at which the resolution 2450 /// of the path whose attributes have to be 2451 /// adjusted starts. 2452 /// 2453 /// **path**: 2454 /// The path of the file whose attributes have to 2455 /// be adjusted. 2456 /// 2457 /// **buf**: 2458 /// The desired values of the file attributes that 2459 /// are adjusted. 2460 /// 2461 /// **flags**: 2462 /// A bitmask indicating which attributes have to 2463 /// be adjusted. 2464 #[inline] 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_) 2467 } 2468 2469 /// Creates a symbolic link. 2470 /// 2471 /// ## Parameters 2472 /// 2473 /// **path1**: 2474 /// The contents of the symbolic link. 2475 /// 2476 /// **fd**: 2477 /// The working directory at which the resolution 2478 /// of the destination path starts. 2479 /// 2480 /// **path2**: 2481 /// The destination path at which the symbolic 2482 /// link should be created. 2483 #[inline] 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()) 2486 } 2487 2488 /// Unlinks a file, or removes a directory. 2489 /// 2490 /// ## Parameters 2491 /// 2492 /// **fd**: 2493 /// The working directory at which the resolution 2494 /// of the path starts. 2495 /// 2496 /// **path**: 2497 /// The path that needs to be unlinked or removed. 2498 /// 2499 /// **flags**: 2500 /// Possible values: 2501 /// 2502 /// - [`REMOVEDIR`](struct.ulflags.html#associatedconstant.REMOVEDIR): 2503 /// If set, attempt to remove a directory. 2504 /// Otherwise, unlink a file. 2505 #[inline] 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_) 2508 } 2509 2510 /// Unlocks a write-locked userspace lock. 2511 /// 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. 2516 /// 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. 2522 /// 2523 /// ## Parameters 2524 /// 2525 /// **lock**: 2526 /// The userspace lock that is locked for writing 2527 /// by the calling thread. 2528 /// 2529 /// **scope**: 2530 /// Whether the lock is stored in private or 2531 /// shared memory. 2532 #[inline] 2533 pub unsafe fn lock_unlock(lock_: *mut lock, scope_: scope) -> errno { 2534 cloudabi_sys_lock_unlock(lock_, scope_) 2535 } 2536 2537 /// Provides memory advisory information on a region of memory. 2538 /// 2539 /// ## Parameters 2540 /// 2541 /// **mapping**: 2542 /// The pages for which to provide memory advisory 2543 /// information. 2544 /// 2545 /// **advice**: 2546 /// The advice. 2547 #[inline] 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_) 2550 } 2551 2552 /// Creates a memory mapping, making the contents of a file 2553 /// accessible through memory. 2554 /// 2555 /// ## Parameters 2556 /// 2557 /// **addr**: 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 2561 /// location. 2562 /// 2563 /// **len**: 2564 /// The length of the memory mapping to be 2565 /// created. 2566 /// 2567 /// **prot**: 2568 /// Initial memory protection options for the 2569 /// memory mapping. 2570 /// 2571 /// **flags**: 2572 /// Memory mapping flags. 2573 /// 2574 /// **fd**: 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 2578 /// mapped. 2579 /// 2580 /// **off**: 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 2584 /// starts. 2585 /// 2586 /// **mem**: 2587 /// The starting address of the memory mapping. 2588 #[inline] 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_) 2591 } 2592 2593 /// Change the protection of a memory mapping. 2594 /// 2595 /// ## Parameters 2596 /// 2597 /// **mapping**: 2598 /// The pages that need their protection changed. 2599 /// 2600 /// **prot**: 2601 /// New protection options. 2602 #[inline] 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_) 2605 } 2606 2607 /// Synchronize a region of memory with its physical storage. 2608 /// 2609 /// ## Parameters 2610 /// 2611 /// **mapping**: 2612 /// The pages that need to be synchronized. 2613 /// 2614 /// **flags**: 2615 /// The method of synchronization. 2616 #[inline] 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_) 2619 } 2620 2621 /// Unmaps a region of memory. 2622 /// 2623 /// ## Parameters 2624 /// 2625 /// **mapping**: 2626 /// The pages that needs to be unmapped. 2627 #[inline] 2628 pub unsafe fn mem_unmap(mapping_: &mut [u8]) -> errno { 2629 cloudabi_sys_mem_unmap(mapping_.as_mut_ptr() as *mut (), mapping_.len()) 2630 } 2631 2632 /// Concurrently polls for the occurrence of a set of events. 2633 /// 2634 /// ## Parameters 2635 /// 2636 /// **in**: 2637 /// The events to which to subscribe. 2638 /// 2639 /// **out**: 2640 /// The events that have occurred. 2641 /// 2642 /// **nsubscriptions**: 2643 /// Both the number of subscriptions and events. 2644 /// 2645 /// **nevents**: 2646 /// The number of events stored. 2647 #[inline] 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_) 2650 } 2651 2652 /// Replaces the process by a new executable. 2653 /// 2654 /// Process execution in CloudABI differs from POSIX in two ways: 2655 /// handling of arguments and inheritance of file descriptors. 2656 /// 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 2662 /// YAML. 2663 /// 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. 2672 /// 2673 /// ## Parameters 2674 /// 2675 /// **fd**: 2676 /// A file descriptor of the new executable. 2677 /// 2678 /// **data**: 2679 /// Binary argument data that is passed on to the 2680 /// new executable. 2681 /// 2682 /// **fds**: 2683 /// The layout of the file descriptor table after 2684 /// execution. 2685 #[inline] 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()) 2688 } 2689 2690 /// Terminates the process normally. 2691 /// 2692 /// ## Parameters 2693 /// 2694 /// **rval**: 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). 2698 #[inline] 2699 pub unsafe fn proc_exit(rval_: exitcode) -> ! { 2700 cloudabi_sys_proc_exit(rval_) 2701 } 2702 2703 /// Forks the process of the calling thread. 2704 /// 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). 2709 /// 2710 /// ## Parameters 2711 /// 2712 /// **fd**: 2713 /// In the parent process: the file descriptor 2714 /// number of the process descriptor. 2715 /// 2716 /// In the child process: [`PROCESS_CHILD`](constant.PROCESS_CHILD.html). 2717 /// 2718 /// **tid**: 2719 /// In the parent process: undefined. 2720 /// 2721 /// In the child process: the thread ID of the 2722 /// initial thread of the child process. 2723 #[inline] 2724 pub unsafe fn proc_fork(fd_: &mut fd, tid_: &mut tid) -> errno { 2725 cloudabi_sys_proc_fork(fd_, tid_) 2726 } 2727 2728 /// Sends a signal to the process of the calling thread. 2729 /// 2730 /// ## Parameters 2731 /// 2732 /// **sig**: 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). 2738 #[inline] 2739 pub unsafe fn proc_raise(sig_: signal) -> errno { 2740 cloudabi_sys_proc_raise(sig_) 2741 } 2742 2743 /// Obtains random data from the kernel random number generator. 2744 /// 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. 2748 /// 2749 /// ## Parameters 2750 /// 2751 /// **buf**: 2752 /// The buffer that needs to be filled with random 2753 /// data. 2754 #[inline] 2755 pub unsafe fn random_get(buf_: &mut [u8]) -> errno { 2756 cloudabi_sys_random_get(buf_.as_mut_ptr() as *mut (), buf_.len()) 2757 } 2758 2759 /// Receives a message on a socket. 2760 /// 2761 /// ## Parameters 2762 /// 2763 /// **sock**: 2764 /// The socket on which a message should be 2765 /// received. 2766 /// 2767 /// **in**: 2768 /// Input parameters. 2769 /// 2770 /// **out**: 2771 /// Output parameters. 2772 #[inline] 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_) 2775 } 2776 2777 /// Sends a message on a socket. 2778 /// 2779 /// ## Parameters 2780 /// 2781 /// **sock**: 2782 /// The socket on which a message should be sent. 2783 /// 2784 /// **in**: 2785 /// Input parameters. 2786 /// 2787 /// **out**: 2788 /// Output parameters. 2789 #[inline] 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_) 2792 } 2793 2794 /// Shuts down socket send and receive channels. 2795 /// 2796 /// ## Parameters 2797 /// 2798 /// **sock**: 2799 /// The socket that needs its channels shut down. 2800 /// 2801 /// **how**: 2802 /// Which channels on the socket need to be shut 2803 /// down. 2804 #[inline] 2805 pub unsafe fn sock_shutdown(sock_: fd, how_: sdflags) -> errno { 2806 cloudabi_sys_sock_shutdown(sock_, how_) 2807 } 2808 2809 /// Creates a new thread within the current process. 2810 /// 2811 /// ## Parameters 2812 /// 2813 /// **attr**: 2814 /// The desired attributes of the new thread. 2815 /// 2816 /// **tid**: 2817 /// The thread ID of the new thread. 2818 #[inline] 2819 pub unsafe fn thread_create(attr_: *mut threadattr, tid_: &mut tid) -> errno { 2820 cloudabi_sys_thread_create(attr_, tid_) 2821 } 2822 2823 /// Terminates the calling thread. 2824 /// 2825 /// This system call can also unlock a single userspace lock 2826 /// after termination, which can be used to implement thread 2827 /// joining. 2828 /// 2829 /// ## Parameters 2830 /// 2831 /// **lock**: 2832 /// Userspace lock that is locked for writing by 2833 /// the calling thread. 2834 /// 2835 /// **scope**: 2836 /// Whether the lock is stored in private or 2837 /// shared memory. 2838 #[inline] 2839 pub unsafe fn thread_exit(lock_: *mut lock, scope_: scope) -> ! { 2840 cloudabi_sys_thread_exit(lock_, scope_) 2841 } 2842 2843 /// Temporarily yields execution of the calling thread. 2844 #[inline] 2845 pub unsafe fn thread_yield() -> errno { 2846 cloudabi_sys_thread_yield() 2847 } 2848