#![forbid(clippy::as_ptr_cast_mut)]
#![forbid(clippy::cast_ptr_alignment)]
#![deny(missing_docs)]
#![deny(clippy::arithmetic_side_effects)]
#![deny(clippy::as_underscore)]
#![deny(clippy::assertions_on_result_states)]
#![deny(clippy::borrow_as_ptr)]
#![deny(clippy::branches_sharing_code)]
#![deny(clippy::case_sensitive_file_extension_comparisons)]
#![deny(clippy::cast_lossless)]
#![deny(clippy::cast_possible_truncation)]
#![deny(clippy::cast_possible_wrap)]
#![deny(clippy::cast_precision_loss)]
#![deny(clippy::cast_sign_loss)]
#![deny(clippy::checked_conversions)]
#![deny(clippy::clear_with_drain)]
#![deny(clippy::clone_on_ref_ptr)]
#![deny(clippy::cloned_instead_of_copied)]
#![deny(clippy::cognitive_complexity)]
#![deny(clippy::collection_is_never_read)]
#![deny(clippy::copy_iterator)]
#![deny(clippy::create_dir)]
#![deny(clippy::dbg_macro)]
#![deny(clippy::debug_assert_with_mut_call)]
#![deny(clippy::decimal_literal_representation)]
#![deny(clippy::default_trait_access)]
#![deny(clippy::default_union_representation)]
#![deny(clippy::derive_partial_eq_without_eq)]
#![deny(clippy::doc_link_with_quotes)]
#![deny(clippy::explicit_into_iter_loop)]
#![deny(clippy::explicit_iter_loop)]
#![deny(clippy::fallible_impl_from)]
#![deny(clippy::missing_safety_doc)]
#![deny(clippy::undocumented_unsafe_blocks)]
pub mod api;
pub mod bins;
pub mod cgroup;
pub mod cookie;
pub(crate) mod mask;
pub mod mount;
#[macro_use]
pub(crate) mod kernel;
pub(crate) mod workers;
pub(crate) mod cache;
#[expect(missing_docs)]
pub mod compat;
pub mod config;
pub mod confine;
pub mod cpu;
pub mod elf;
pub mod err;
pub mod expiry;
pub mod fd;
pub mod filemap;
pub mod fs;
pub mod getpass;
pub mod hash;
pub mod hook;
pub mod id;
pub mod imap;
pub mod io;
pub mod ioctl;
pub mod ip;
pub mod landlock_policy;
pub mod log;
pub use log::syslog;
pub mod lookup;
pub mod magic;
pub mod namespace;
pub mod ofd;
pub mod parsers;
pub mod path;
pub mod port;
pub mod proc;
pub mod ptrace;
pub mod pty;
pub mod req;
pub mod retry;
pub mod rng;
pub mod sandbox;
pub mod seal;
#[expect(clippy::disallowed_types)]
pub mod sealbox;
pub mod sigset;
pub mod smap;
pub mod spec;
pub mod sysinfo;
pub mod timer;
pub mod unix;
pub mod uring;
pub mod uts;
#[expect(clippy::arithmetic_side_effects)]
pub mod wildmatch;
#[cfg(not(target_os = "android"))]
pub mod wordexp;
pub mod xattr;
pub mod zeroize;
#[expect(missing_docs)]
#[expect(clippy::arithmetic_side_effects)]
#[expect(clippy::undocumented_unsafe_blocks)]
pub mod caps;
#[expect(missing_docs)]
#[expect(unused_imports)]
#[expect(clippy::as_underscore)]
#[expect(clippy::borrow_as_ptr)]
#[expect(clippy::cast_lossless)]
#[expect(clippy::cast_possible_truncation)]
#[expect(clippy::decimal_literal_representation)]
#[expect(clippy::default_trait_access)]
#[expect(clippy::disallowed_methods)]
#[expect(clippy::init_numbered_fields)]
#[expect(clippy::undocumented_unsafe_blocks)]
pub mod landlock;
pub(crate) mod pool;
pub mod unshare;
#[cfg(feature = "kcov")]
#[allow(clippy::arithmetic_side_effects)]
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_possible_wrap)]
#[allow(clippy::cast_sign_loss)]
#[allow(clippy::disallowed_methods)]
pub(crate) mod kcov;
#[cfg(not(feature = "kcov"))]
#[allow(missing_docs)]
#[macro_export]
macro_rules! kcov_edge {
() => {{}};
($site:expr) => {{}};
}
#[cfg(not(feature = "kcov"))]
#[allow(missing_docs)]
#[macro_export]
macro_rules! kcov_edge_site {
($s:literal) => {{}};
}
use std::{env, ffi::OsStr};
use lexis::ToName;
use libseccomp::ScmpVersion;
use nix::{
errno::Errno,
sched::CloneFlags,
sys::{
resource::{getrlimit, Resource},
signal::{sigaction, signal, SaFlags, SigAction, SigHandler, SigSet, Signal},
utsname::uname,
},
};
use serde::{Serialize, Serializer};
use crate::{
compat::lsm_list_modules,
config::{
HAVE_AT_EXECVE_CHECK, HAVE_LANDLOCK_SCOPED_SIGNALS, HAVE_MADV_GUARD, HAVE_PIDFD_GET_INFO,
HAVE_PIDFD_THREAD, HAVE_PID_MAX, HAVE_PROCMAP_QUERY, HAVE_PROC_PID_FD_STAT_SIZE,
HAVE_RWF_NOAPPEND, HAVE_SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP, HAVE_STATX_MNT_ID_UNIQUE,
HAVE_URING_RESTRICTIONS_TASK, KERNEL_VERSION, PAGE_SIZE, VERSION,
},
confine::{
apparmor_enabled, check_cross_memory_attach, check_kcmp, check_unix_diag,
confine_core_sched, confine_mte, is_coredump, lock_enabled, ns_enabled,
seccomp_arch_native_name, selinux_enabled, selinux_enforced, SydArch, SydPersona,
SCMP_ARCH,
},
err::err2no,
hash::key_ring_validate,
landlock::ABI,
path::{XPath, XPathBuf},
proc::{
info::PROC_INFO,
util::{
proc_char_dev_major, proc_fs_file_max, proc_fs_nr_open, proc_kernel_randomize_va_space,
proc_kernel_taint, proc_net_bpf_jit_enable, proc_open, proc_tcp_fastopen,
proc_yama_ptrace_scope,
},
},
sealbox::{check_memfd_secret_support, check_mseal_support},
spec::{speculation_get, SpeculationFeature},
};
#[macro_export]
macro_rules! main {
{ $name:ident => $($body:tt)* } => {
#[doc = concat!("Binary entry point: `", stringify!($name), "`.")]
pub fn $name() -> std::process::ExitCode {
match (|| -> $crate::err::SydResult<std::process::ExitCode> { $($body)* })() {
Ok(code) => code,
Err(err) => {
u8::try_from(
err.errno()
.map(|e| e as i32)
.unwrap_or(128)
)
.map(std::process::ExitCode::from)
.unwrap_or(std::process::ExitCode::FAILURE)
}
}
}
};
{ $($body:tt)* } => {
fn main() -> std::process::ExitCode {
match (|| -> $crate::err::SydResult<std::process::ExitCode> { $($body)* })() {
Ok(code) => code,
Err(err) => {
use std::io::Write;
let desc = format!("Error: {err}\n");
let _ = std::io::stderr().write_all(desc.as_bytes());
u8::try_from(
err.errno()
.map(|e| e as i32)
.unwrap_or(128)
)
.map(std::process::ExitCode::from)
.unwrap_or(std::process::ExitCode::FAILURE)
}
}
}
};
}
#[expect(clippy::cognitive_complexity)]
pub fn syd_info(verbose: bool) -> Result<(), Errno> {
printfln!("syd {} ({})", *VERSION, syd_code_name())?;
printfln!("Rock solid application kernel")?;
printfln!("Author: Ali Polatel <alip@chesswob.org>")?;
printfln!("License: GPL-3.0-only")?;
let feat = [
#[cfg(debug_assertions)]
"+debug",
#[cfg(not(debug_assertions))]
"-debug",
#[cfg(feature = "kcov")]
"+kcov",
#[cfg(not(feature = "kcov"))]
"-kcov",
#[cfg(feature = "log")]
"+log",
#[cfg(not(feature = "log"))]
"-log",
#[cfg(feature = "oci")]
"+oci",
#[cfg(not(feature = "oci"))]
"-oci",
#[cfg(feature = "trusted")]
"+trusted",
#[cfg(not(feature = "trusted"))]
"-trusted",
];
printfln!("Features: {}", feat.join(", "))?;
if !verbose {
return Ok(());
}
let alloc = if cfg!(all(
not(target_os = "android"),
not(target_arch = "loongarch64"),
not(target_arch = "riscv64"),
target_page_size_4k,
target_pointer_width = "64"
)) {
"GrapheneOS"
} else {
"Libc"
};
printfln!("Allocator: {alloc}")?;
let libapi = libseccomp::get_api();
match ScmpVersion::current() {
Ok(libver) => {
printfln!(
"LibSeccomp: v{}.{}.{} api:{}",
libver.major,
libver.minor,
libver.micro,
libapi
)?;
}
Err(error) => {
printfln!("LibSeccomp: ? (error: {error})")?;
}
}
let fd_proc = proc_open(None);
let fd_proc = fd_proc.as_ref().map_err(|errno| *errno);
match fd_proc.and_then(proc_kernel_taint) {
Ok(tflags) => printfln!("{tflags}"),
Err(errno) => printfln!("Kernel may be tainted (error: {errno})."),
}?;
let aslr = match fd_proc.and_then(proc_kernel_randomize_va_space) {
Ok(0) => "disabled".to_string(),
Ok(1) => "enabled (stack, mmap, VDSO; PIE text randomized)".to_string(),
Ok(2) => "enabled (heap + stack, mmap, VDSO; PIE text randomized)".to_string(),
Ok(n) => format!("{n} (error: {})", Errno::EINVAL),
Err(errno) => format!("? (error: {errno})"),
};
printfln!("ASLR is {aslr}.")?;
let bpf_jit = match fd_proc.and_then(proc_net_bpf_jit_enable) {
Ok(0) => "disabled".to_string(),
Ok(1) => "enabled".to_string(),
Ok(2) => "enabled in debug mode".to_string(),
Ok(n) => format!("{n} (error: {})", Errno::EINVAL),
Err(errno) => format!("? (error: {errno})"),
};
printfln!("BPF JIT compiler is {bpf_jit}.")?;
let ptrace_scope = match fd_proc.and_then(proc_yama_ptrace_scope) {
Ok(0) => "0 - classic ptrace permissions".to_string(),
Ok(1) => "1 - restricted ptrace".to_string(),
Ok(2) => "2 - admin-only attach".to_string(),
Ok(3) => "3 - no attach".to_string(),
Ok(n) => format!("{n} (error: {})", Errno::EINVAL),
Err(errno) => format!("? (error: {errno})"),
};
printfln!("YAMA ptrace(2) scope is {ptrace_scope}.")?;
let abi = ABI::new_current();
if abi == ABI::Unsupported {
printfln!("Landlock is not supported.")?;
} else {
let state = lock_enabled(abi);
let state_verb = match state {
0 => "fully enforced",
1 => "partially enforced",
2 => "not enforced",
_ => "unsupported",
};
printfln!("Landlock ABI {} is {state_verb}.", abi as i32)?;
}
printfln!(
"User namespaces are {}supported.",
if ns_enabled(CloneFlags::CLONE_NEWUSER).unwrap_or(false) {
""
} else {
"not "
}
)?;
let cfg_cma = check_cross_memory_attach();
printfln!(
"Cross memory attach is {}supported{}",
if cfg_cma { "" } else { "not " },
if cfg_cma {
"."
} else {
" (\x1b[91minsecure\x1b[0m)."
},
)?;
printfln!(
"kcmp(2) is {}supported.",
if check_kcmp() { "" } else { "not " }
)?;
printfln!(
"Memory sealing is {}supported.",
if check_mseal_support() { "" } else { "not " }
)?;
printfln!(
"Secret memory is {}supported.",
if check_memfd_secret_support() {
""
} else {
"not "
}
)?;
printfln!(
"Memory tagging is {}supported.",
if confine_mte().is_ok() { "" } else { "not " }
)?;
printfln!(
"Core scheduling is {}supported.",
if confine_core_sched().is_ok() {
""
} else {
"not "
}
)?;
let unix_diag = match check_unix_diag() {
Ok(true) => "supported".to_string(),
Ok(false) => "not supported".to_string(),
Err(errno) => format!("unknown (error: {errno})"),
};
printfln!("UNIX socket diagnostics are {unix_diag}.")?;
match key_ring_validate() {
Ok(()) => {
printfln!("Session keyring is attached to the user keyring.")?;
}
Err(errno) => {
printfln!("Session keyring isn't attached to the user keyring: {errno}!")?;
}
}
let lsms = match lsm_list_modules() {
Ok(lsms) => lsms
.into_iter()
.map(|s| s.to_string())
.collect::<Vec<String>>()
.join(", "),
Err(Errno::ENOENT) => "none loaded".to_string(),
Err(errno) => format!("? (error: {errno})"),
};
printfln!("LSMs: {lsms}.")?;
let selinux = match selinux_enabled() {
Ok(true) => {
let enforce = if selinux_enforced().unwrap_or(false) {
"Enforcing"
} else {
"Permissive"
};
format!("enabled ({enforce})")
}
Ok(false) => "disabled".to_string(),
Err(errno) => format!("? (error: {errno})"),
};
let apparmor = match apparmor_enabled() {
Ok(true) => "enabled".to_string(),
Ok(false) => "disabled".to_string(),
Err(errno) => format!("? (error: {errno})"),
};
printfln!("SELinux is {selinux}.")?;
printfln!("AppArmor is {apparmor}.")?;
let (nofile_soft, nofile_hard) = getrlimit(Resource::RLIMIT_NOFILE).unwrap_or((0, 0));
printf!("Open file limits: {nofile_soft} soft, {nofile_hard} hard, ")?;
let file_max = fd_proc.and_then(proc_fs_file_max).unwrap_or(0);
let nr_open = fd_proc.and_then(proc_fs_nr_open).unwrap_or(0);
printfln!("{nr_open} nr_open, {file_max} file-max")?;
let uname = match uname() {
Ok(info) => OsStr::to_str(info.release()).unwrap_or("?").to_string(),
Err(_) => "?".to_string(),
};
printfln!("Host (build): {}", env!("SYD_BUILDHOST"))?;
printfln!(
"Host (target): {uname} {}",
seccomp_arch_native_name().unwrap_or("?")
)?;
printf!("Host Linux: {}.{} with", KERNEL_VERSION.0, KERNEL_VERSION.1)?;
printf!(" mmap_min_addr={}", PROC_INFO.mmap_min_addr)?;
printf!(", page_size={}", *PAGE_SIZE)?;
printf!(
", {}at_execve_check",
if *HAVE_AT_EXECVE_CHECK { "+" } else { "-" }
)?;
printf!(
", {}landlock_scoped_signals",
if *HAVE_LANDLOCK_SCOPED_SIGNALS {
"+"
} else {
"-"
}
)?;
printf!(
", {}madv_guard_install",
if *HAVE_MADV_GUARD { "+" } else { "-" }
)?;
printf!(
", {}namespaced_pid_max",
if *HAVE_PID_MAX { "+" } else { "-" }
)?;
printf!(
", {}pidfd_thread",
if *HAVE_PIDFD_THREAD { "+" } else { "-" }
)?;
printf!(
", {}pidfd_get_info",
if *HAVE_PIDFD_GET_INFO { "+" } else { "-" }
)?;
printf!(
", {}procmap_query",
if *HAVE_PROCMAP_QUERY { "+" } else { "-" }
)?;
printf!(
", {}proc_pid_fd_stat_size",
if *HAVE_PROC_PID_FD_STAT_SIZE {
"+"
} else {
"-"
}
)?;
printf!(
", {}pwritev2_rwf_noappend",
if *HAVE_RWF_NOAPPEND { "+" } else { "-" }
)?;
printf!(
", {}seccomp_user_notif_fd_sync_wake_up",
if *HAVE_SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP {
"+"
} else {
"-"
}
)?;
printf!(
", {}statx_mnt_id_unique",
if *HAVE_STATX_MNT_ID_UNIQUE { "+" } else { "-" }
)?;
printf!(
", {}uring_restrictions_task",
if *HAVE_URING_RESTRICTIONS_TASK {
"+"
} else {
"-"
}
)?;
match fd_proc.and_then(proc_tcp_fastopen) {
Ok(tcp_fastopen) => printf!(", tcp_fastopen={tcp_fastopen:#x}"),
Err(errno) => printf!(", tcp_fastopen=? (error: {errno})"),
}?;
printf!(", char_devices={}", PROC_INFO.char_dev.len())?;
for name in ["mem", "kmem", "cpu/msr", "cpu/cpuid", "kfd", "ntsync"] {
if let Some(major) = proc_char_dev_major(name.as_bytes()) {
printf!(", {name}={major}")?;
}
}
printfln!()?;
let pers = match SydPersona::get() {
Ok(pers) => pers.to_string(),
Err(errno) => format!("? (error: {errno})"),
};
printfln!(
"Environment: {}-{pers}-{}",
env!("SYD_TARGET_ENV"),
env!("SYD_TARGET_POINTER_WIDTH")
)?;
let arch = SCMP_ARCH
.iter()
.map(SydArch::from)
.map(|arch| arch.to_string())
.collect::<Vec<_>>()
.join(", ");
printfln!("Architectures: {arch}")?;
let mut has_ipc = Vec::new();
let mut has_socketcall = Vec::new();
for arch in SCMP_ARCH.iter().map(SydArch::from) {
if arch.has_ipc() {
has_ipc.push(arch.to_string());
}
if arch.has_socketcall() {
has_socketcall.push(arch.to_string());
}
}
if !has_ipc.is_empty() {
let plurals = if has_ipc.len() > 1 { "s" } else { "" };
let verbone = if has_ipc.len() == 1 { "s" } else { "" };
let has_ipc = has_ipc.join(", ");
printfln!("Architecture{plurals} {has_ipc} support{verbone} ipc(2) multiplexer.")?;
}
if !has_socketcall.is_empty() {
let plurals = if has_socketcall.len() > 1 { "s" } else { "" };
let verbone = if has_socketcall.len() == 1 { "s" } else { "" };
let has_socketcall = has_socketcall.join(", ");
printfln!(
"Architecture{plurals} {has_socketcall} support{verbone} socketcall(2) multiplexer."
)?;
}
let nproc = crate::cpu::get().unwrap_or(2);
printfln!("CPU: {nproc}, {}-endian", env!("SYD_TARGET_ENDIAN"))?;
printfln!("CPUFLAGS: {}", env!("SYD_TARGET_FEATURE"))?;
for spec_feat in [
SpeculationFeature::StoreBypass,
SpeculationFeature::IndirectBranch,
SpeculationFeature::L1DFlush,
] {
printfln!(
"{}",
match speculation_get(spec_feat) {
Ok(status) => status.to_string(),
Err(errno) => format!("{spec_feat} status: ? (error: {errno})"),
}
)?;
}
Ok(())
}
pub fn syd_code_name() -> &'static str {
#[expect(clippy::disallowed_methods)]
let major = env!("CARGO_PKG_VERSION_MAJOR")
.parse::<u64>()
.expect("CARGO_PKG_VERSION_MAJOR");
#[expect(clippy::disallowed_methods)]
let minor = env!("CARGO_PKG_VERSION_MINOR")
.parse::<u64>()
.expect("CARGO_PKG_VERSION_MINOR");
#[expect(clippy::disallowed_methods)]
let patch = env!("CARGO_PKG_VERSION_PATCH")
.parse::<u64>()
.expect("CARGO_PKG_VERSION_PATCH");
let hex_version = (major << 16) | (minor << 8) | patch;
hex_version.to_name()
}
pub fn ignore_signal(signal: Signal) -> Result<(), Errno> {
let sig_action = SigAction::new(
SigHandler::SigIgn, SaFlags::empty(),
SigSet::empty(),
);
unsafe { sigaction(signal, &sig_action) }.map(drop)
}
pub fn reset_signal(signal: Signal) -> Result<(), Errno> {
let sig_action = SigAction::new(
SigHandler::SigDfl, SaFlags::empty(),
SigSet::empty(),
);
unsafe { sigaction(signal, &sig_action) }.map(drop)
}
bitflags::bitflags! {
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct IgnoreSignalOpts: u8 {
const NoCore = 1 << 0;
const NoAlarm = 1 << 1;
const NoWinch = 1 << 2;
}
}
impl Serialize for IgnoreSignalOpts {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut opts: Vec<&str> = vec![];
if self.is_empty() {
return serializer.collect_seq(opts);
}
if self.contains(Self::NoCore) {
opts.push("no_core");
}
if self.contains(Self::NoAlarm) {
opts.push("no_alarm");
}
if self.contains(Self::NoWinch) {
opts.push("no_winch");
}
serializer.collect_seq(opts)
}
}
pub fn ignore_signals(opts: IgnoreSignalOpts) -> Result<(), Errno> {
for signal in Signal::iterator() {
match signal {
Signal::SIGCHLD | Signal::SIGKILL | Signal::SIGSTOP => {}
Signal::SIGALRM if opts.contains(IgnoreSignalOpts::NoAlarm) => {}
Signal::SIGWINCH if opts.contains(IgnoreSignalOpts::NoWinch) => {}
signal if opts.contains(IgnoreSignalOpts::NoCore) && is_coredump(signal as i32) => {}
signal => ignore_signal(signal)?,
}
}
for signum in libc::SIGRTMIN()..libc::SIGRTMAX() {
Errno::result(unsafe { libc::signal(signum, libc::SIG_IGN as libc::sighandler_t) })?;
}
Ok(())
}
pub fn reset_signals() -> Result<(), Errno> {
for signal in Signal::iterator() {
if !matches!(signal, Signal::SIGKILL | Signal::SIGSTOP) {
reset_signal(signal)?;
}
}
for signum in libc::SIGRTMIN()..libc::SIGRTMAX() {
Errno::result(unsafe { libc::signal(signum, libc::SIG_DFL as libc::sighandler_t) })?;
}
Ok(())
}
const IOPRIO_CLASS_IDLE: i32 = 3;
const IOPRIO_WHO_PROCESS: i32 = 1;
pub(crate) fn set_io_priority_idle() -> Result<(), Errno> {
let ioprio = IOPRIO_CLASS_IDLE << 13;
Errno::result(unsafe { libc::syscall(libc::SYS_ioprio_set, IOPRIO_WHO_PROCESS, 0, ioprio) })
.map(drop)
}
pub(crate) fn set_cpu_priority_idle() -> Result<(), Errno> {
let param: libc::sched_param = unsafe { std::mem::zeroed() };
Errno::result(unsafe {
libc::sched_setscheduler(0, libc::SCHED_IDLE, std::ptr::addr_of!(param))
})
.map(drop)
}
#[expect(clippy::arithmetic_side_effects)]
#[expect(clippy::cast_precision_loss)]
pub fn human_size(bytes: usize) -> String {
const SIZES: &[char] = &['B', 'K', 'M', 'G', 'T', 'P', 'E'];
let factor = 1024usize;
let mut size = bytes as f64;
let mut i = 0;
while size > factor as f64 && i < SIZES.len() - 1 {
size /= factor as f64;
i += 1;
}
format!("{:.2}{}", size, SIZES[i])
}
pub fn set_sigpipe_dfl() -> Result<(), Errno> {
unsafe { signal(Signal::SIGPIPE, SigHandler::SigDfl) }.map(drop)
}
pub fn try_to_string(s: &str) -> Result<String, Errno> {
let mut out = String::new();
out.try_reserve_exact(s.len()).or(Err(Errno::ENOMEM))?;
out.push_str(s);
Ok(out)
}
pub fn try_to_vec(data: &[u8]) -> Result<Vec<u8>, Errno> {
let mut vec = Vec::new();
vec.try_reserve_exact(data.len()).or(Err(Errno::ENOMEM))?;
vec.extend_from_slice(data);
Ok(vec)
}
#[inline]
#[cold]
fn cold() {}
#[inline]
pub(crate) fn likely(b: bool) -> bool {
if !b {
cold()
}
b
}
#[inline]
pub(crate) fn unlikely(b: bool) -> bool {
if b {
cold()
}
b
}
pub fn t(msg: &str) {
let buf = msg.as_bytes();
let len = buf.len() as libc::size_t;
unsafe { libc::syscall(libc::SYS_write, -31415, buf.as_ptr(), len) };
}
#[macro_export]
macro_rules! t {
($($arg:tt)*) => {{
syd::t(&format!($($arg)*));
}}
}
#[macro_export]
macro_rules! T {
($($arg:tt)*) => {{
$crate::t(&format!($($arg)*));
}}
}
#[cfg(test)]
mod t {
pub mod mktemp;
pub mod uring;
use super::*;
#[test]
fn test_human_size_0() {
assert_eq!(human_size(0), "0.00B");
}
#[test]
fn test_human_size_1() {
assert_eq!(human_size(512), "512.00B");
}
#[test]
fn test_human_size_2() {
assert_eq!(human_size(1024), "1024.00B");
}
#[test]
fn test_human_size_3() {
assert_eq!(human_size(1025), "1.00K");
}
#[test]
fn test_human_size_4() {
assert_eq!(human_size(1048576), "1024.00K");
}
#[test]
fn test_human_size_5() {
assert_eq!(human_size(1048577), "1.00M");
}
#[test]
fn test_human_size_6() {
assert_eq!(human_size(1073741824), "1024.00M");
}
#[test]
fn test_human_size_7() {
assert_eq!(human_size(1073741825), "1.00G");
}
#[test]
fn test_likely_0() {
assert!(likely(true));
}
#[test]
fn test_likely_1() {
assert!(!likely(false));
}
#[test]
fn test_unlikely_0() {
assert!(unlikely(true));
}
#[test]
fn test_unlikely_1() {
assert!(!unlikely(false));
}
#[test]
fn test_syd_code_name_0() {
let name = syd_code_name();
assert!(!name.is_empty());
}
#[test]
fn test_syd_code_name_1() {
let name = syd_code_name();
assert!(name.chars().next().unwrap().is_uppercase());
}
#[test]
fn test_ignore_signal_opts_0() {
let opts = IgnoreSignalOpts::empty();
assert!(!opts.contains(IgnoreSignalOpts::NoAlarm));
assert!(!opts.contains(IgnoreSignalOpts::NoCore));
}
#[test]
fn test_ignore_signal_opts_1() {
let opts = IgnoreSignalOpts::NoAlarm | IgnoreSignalOpts::NoCore;
assert!(opts.contains(IgnoreSignalOpts::NoAlarm));
assert!(opts.contains(IgnoreSignalOpts::NoCore));
}
}