blob: 48c23b529b5c7e31fd7ce1550010cff0f4036747 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// TODO: Generate from Linux uapi using bindgen.
#![allow(non_camel_case_types)]
#![allow(dead_code)]
use {
fuchsia_zircon::{self as zx, sys::zx_vaddr_t},
std::fmt,
std::ops,
zerocopy::{AsBytes, FromBytes},
};
pub type uid_t = u32;
pub type gid_t = u32;
pub type dev_t = u64;
pub type ino_t = u64;
pub type mode_t = u16;
pub type off_t = i64;
#[derive(Debug)]
pub struct Errno(i32);
impl Errno {
pub fn value(&self) -> i32 {
self.0
}
}
impl fmt::Display for Errno {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// TODO(tbodt): Return the string name of the error (would be nice to be able to do this
// without typing them all twice.)
write!(f, "error {}", self.0)
}
}
pub const EPERM: Errno = Errno(1);
pub const ENOENT: Errno = Errno(2);
pub const ESRCH: Errno = Errno(3);
pub const EINTR: Errno = Errno(4);
pub const EIO: Errno = Errno(5);
pub const ENXIO: Errno = Errno(6);
pub const E2BIG: Errno = Errno(7);
pub const ENOEXEC: Errno = Errno(8);
pub const EBADF: Errno = Errno(9);
pub const ECHILD: Errno = Errno(10);
pub const EAGAIN: Errno = Errno(11);
pub const ENOMEM: Errno = Errno(12);
pub const EACCES: Errno = Errno(13);
pub const EFAULT: Errno = Errno(14);
pub const ENOTBLK: Errno = Errno(15);
pub const EBUSY: Errno = Errno(16);
pub const EEXIST: Errno = Errno(17);
pub const EXDEV: Errno = Errno(18);
pub const ENODEV: Errno = Errno(19);
pub const ENOTDIR: Errno = Errno(20);
pub const EISDIR: Errno = Errno(21);
pub const EINVAL: Errno = Errno(22);
pub const ENFILE: Errno = Errno(23);
pub const EMFILE: Errno = Errno(24);
pub const ENOTTY: Errno = Errno(25);
pub const ETXTBSY: Errno = Errno(26);
pub const EFBIG: Errno = Errno(27);
pub const ENOSPC: Errno = Errno(28);
pub const ESPIPE: Errno = Errno(29);
pub const EROFS: Errno = Errno(30);
pub const EMLINK: Errno = Errno(31);
pub const EPIPE: Errno = Errno(32);
pub const EDOM: Errno = Errno(33);
pub const ERANGE: Errno = Errno(34);
pub const EDEADLK: Errno = Errno(35);
pub const ENAMETOOLONG: Errno = Errno(36);
pub const ENOLCK: Errno = Errno(37);
pub const ENOSYS: Errno = Errno(38);
pub const ENOTEMPTY: Errno = Errno(39);
pub const EPROTONOSUPPORT: Errno = Errno(93);
pub const ENOTSUP: Errno = Errno(95);
pub const EADDRINUSE: Errno = Errno(98);
pub const ENETUNREACH: Errno = Errno(101);
pub const ECONNABORTED: Errno = Errno(103);
pub const ECONNRESET: Errno = Errno(104);
pub const ENOTCONN: Errno = Errno(107);
pub const ETIMEDOUT: Errno = Errno(110);
pub const ECONNREFUSED: Errno = Errno(111);
// There isn't really a mapping from zx::Status to Errno. The correct mapping is context-speific
// but this converter is a reasonable first-approximation. The translation matches
// fdio_status_to_errno. See fxbug.dev/30921 for more context.
// TODO: Replace clients with more context-specific mappings.
impl From<zx::Status> for Errno {
fn from(status: zx::Status) -> Self {
match status {
zx::Status::NOT_FOUND => ENOENT,
zx::Status::NO_MEMORY => ENOMEM,
zx::Status::INVALID_ARGS => EINVAL,
zx::Status::BUFFER_TOO_SMALL => EINVAL,
zx::Status::TIMED_OUT => ETIMEDOUT,
zx::Status::UNAVAILABLE => EBUSY,
zx::Status::ALREADY_EXISTS => EEXIST,
zx::Status::PEER_CLOSED => EPIPE,
zx::Status::BAD_STATE => EPIPE,
zx::Status::BAD_PATH => ENAMETOOLONG,
zx::Status::IO => EIO,
zx::Status::NOT_FILE => EISDIR,
zx::Status::NOT_DIR => ENOTDIR,
zx::Status::NOT_SUPPORTED => ENOTSUP,
zx::Status::WRONG_TYPE => ENOTSUP,
zx::Status::OUT_OF_RANGE => EINVAL,
zx::Status::NO_RESOURCES => ENOMEM,
zx::Status::BAD_HANDLE => EBADF,
zx::Status::ACCESS_DENIED => EACCES,
zx::Status::SHOULD_WAIT => EAGAIN,
zx::Status::FILE_BIG => EFBIG,
zx::Status::NO_SPACE => ENOSPC,
zx::Status::NOT_EMPTY => ENOTEMPTY,
zx::Status::IO_REFUSED => ECONNREFUSED,
zx::Status::IO_INVALID => EIO,
zx::Status::CANCELED => EBADF,
zx::Status::PROTOCOL_NOT_SUPPORTED => EPROTONOSUPPORT,
zx::Status::ADDRESS_UNREACHABLE => ENETUNREACH,
zx::Status::ADDRESS_IN_USE => EADDRINUSE,
zx::Status::NOT_CONNECTED => ENOTCONN,
zx::Status::CONNECTION_REFUSED => ECONNREFUSED,
zx::Status::CONNECTION_RESET => ECONNRESET,
zx::Status::CONNECTION_ABORTED => ECONNABORTED,
_ => EIO,
}
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, AsBytes, FromBytes)]
#[repr(transparent)]
pub struct UserAddress(u64);
impl UserAddress {
pub fn ptr(&self) -> zx_vaddr_t {
self.0 as zx_vaddr_t
}
pub fn round_up(&self, increment: u64) -> UserAddress {
UserAddress((self.0 + (increment - 1)) & !(increment - 1))
}
}
impl Default for UserAddress {
fn default() -> UserAddress {
UserAddress(0)
}
}
impl From<u64> for UserAddress {
fn from(value: u64) -> Self {
UserAddress(value)
}
}
impl From<usize> for UserAddress {
fn from(value: usize) -> Self {
UserAddress(value as u64)
}
}
impl ops::Add<u64> for UserAddress {
type Output = UserAddress;
fn add(self, rhs: u64) -> UserAddress {
UserAddress(self.0 + rhs)
}
}
impl ops::Sub<UserAddress> for UserAddress {
type Output = usize;
fn sub(self, rhs: UserAddress) -> usize {
self.ptr() - rhs.ptr()
}
}
impl fmt::Display for UserAddress {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "0x{:x}", self.0)
}
}
pub struct SyscallResult(u64);
pub const SUCCESS: SyscallResult = SyscallResult(0);
impl SyscallResult {
pub fn value(&self) -> u64 {
self.0
}
}
impl From<UserAddress> for SyscallResult {
fn from(value: UserAddress) -> Self {
SyscallResult(value.ptr() as u64)
}
}
impl From<u32> for SyscallResult {
fn from(value: u32) -> Self {
SyscallResult(value as u64)
}
}
impl From<i32> for SyscallResult {
fn from(value: i32) -> Self {
SyscallResult(value as u64)
}
}
impl From<u64> for SyscallResult {
fn from(value: u64) -> Self {
SyscallResult(value)
}
}
impl From<usize> for SyscallResult {
fn from(value: usize) -> Self {
SyscallResult(value as u64)
}
}
pub type syscall_number_t = u64;
pub const SYS_WRITE: syscall_number_t = 1;
pub const SYS_FSTAT: syscall_number_t = 5;
pub const SYS_MMAP: syscall_number_t = 9;
pub const SYS_MPROTECT: syscall_number_t = 10;
pub const SYS_BRK: syscall_number_t = 12;
pub const SYS_PREAD64: syscall_number_t = 17;
pub const SYS_WRITEV: syscall_number_t = 20;
pub const SYS_ACCESS: syscall_number_t = 21;
pub const SYS_GETPID: syscall_number_t = 39;
pub const SYS_EXIT: syscall_number_t = 60;
pub const SYS_UNAME: syscall_number_t = 63;
pub const SYS_READLINK: syscall_number_t = 89;
pub const SYS_GETUID: syscall_number_t = 102;
pub const SYS_GETGID: syscall_number_t = 104;
pub const SYS_GETEUID: syscall_number_t = 107;
pub const SYS_GETEGID: syscall_number_t = 108;
pub const SYS_FSTATFS: syscall_number_t = 138;
pub const SYS_SCHED_GETSCHEDULER: syscall_number_t = 145;
pub const SYS_ARCH_PRCTL: syscall_number_t = 158;
pub const SYS_EXIT_GROUP: syscall_number_t = 231;
pub const SYS_OPENAT: syscall_number_t = 257;
pub const SYS_GETRANDOM: syscall_number_t = 318;
pub const ARCH_SET_GS: i32 = 0x1001;
pub const ARCH_SET_FS: i32 = 0x1002;
pub const AT_NULL: u64 = 0;
pub const AT_PHDR: u64 = 3;
pub const AT_PHNUM: u64 = 5;
pub const AT_PAGESZ: u64 = 6;
pub const AT_ENTRY: u64 = 9;
pub const AT_BASE: u64 = 7;
pub const AT_UID: u64 = 11;
pub const AT_EUID: u64 = 12;
pub const AT_GID: u64 = 13;
pub const AT_EGID: u64 = 14;
pub const AT_SECURE: u64 = 23;
pub const AT_RANDOM: u64 = 25;
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, AsBytes)]
#[repr(C)]
pub struct utsname_t {
pub sysname: [u8; 65],
pub nodename: [u8; 65],
pub release: [u8; 65],
pub version: [u8; 65],
pub machine: [u8; 65],
}
#[derive(Debug, Default, Eq, PartialEq, Hash, Copy, Clone, AsBytes)]
#[repr(C)]
pub struct timespec_t {
pub tv_sec: i64,
pub tv_nsec: i64,
}
#[derive(Debug, Default, Eq, PartialEq, Hash, Copy, Clone, AsBytes)]
#[repr(C)]
pub struct stat_t {
pub st_dev: dev_t,
pub st_ino: ino_t,
pub st_nlink: u64,
pub st_mode: u32, // should be mod_t
pub st_uid: uid_t,
pub st_gid: gid_t,
pub _pad0: u32,
pub st_rdev: dev_t,
pub st_size: off_t,
pub st_blksize: i64,
pub st_blocks: i64,
pub st_atim: timespec_t,
pub st_mtim: timespec_t,
pub st_ctim: timespec_t,
pub _pad3: [i64; 3],
}
#[derive(Debug, Default, Clone, Copy, AsBytes, FromBytes)]
#[repr(C)]
pub struct iovec {
pub iov_base: UserAddress,
pub iov_len: usize,
}
pub const UIO_MAXIOV: u32 = 1024;
pub const PROT_READ: i32 = 0x1;
pub const PROT_WRITE: i32 = 0x2;
pub const PROT_EXEC: i32 = 0x4;
pub const PROT_NONE: i32 = 0;
pub const MAP_SHARED: i32 = 0x1;
pub const MAP_PRIVATE: i32 = 0x2;
pub const MAP_FIXED: i32 = 0x10;
pub const MAP_ANONYMOUS: i32 = 0x20;
pub const MAP_NORESERVE: i32 = 0x4000;
pub const SCHED_OTHER: i32 = 0;
pub const AT_FDCWD: i32 = -100;
pub const PATH_MAX: usize = 4096;
#[derive(Debug, Default, AsBytes)]
#[repr(C)]
pub struct statfs {
f_type: i64,
f_bsize: i64,
f_blocks: i64,
f_bfree: i64,
f_bavail: i64,
f_files: i64,
f_ffree: i64,
f_fsid: i64,
f_namelen: i64,
f_frsize: i64,
f_flags: i64,
f_spare: [i64; 4],
}